init
This commit is contained in:
144
trend/SMACrossV2.go
Normal file
144
trend/SMACrossV2.go
Normal file
@@ -0,0 +1,144 @@
|
||||
package trend
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
"github.com/banbox/banstagy/com"
|
||||
ta "github.com/banbox/banta"
|
||||
"math"
|
||||
)
|
||||
|
||||
/*
|
||||
自研均线趋势策略,多空都开。适合1h
|
||||
尝试加止损、止盈、限价入场,都会导致整体收益减少
|
||||
48个品种,21年到24年11月1日,累计收益1291%,最大回撤66%,夏普9.2
|
||||
|
||||
总收益90%来自多头
|
||||
但加入空投可使夏普从5.64提高到9.2
|
||||
|
||||
TODO 添加相似矩阵过滤,趋同的品种不开单
|
||||
结合MACDEMA,优化做多逻辑
|
||||
|
||||
相比SMACrossV1,略微不平滑;且收益降低;优先使用SMACrossV1
|
||||
|
||||
*/
|
||||
|
||||
type maSta struct {
|
||||
openPrice float64
|
||||
bigRsi float64
|
||||
bigLong bool
|
||||
}
|
||||
|
||||
func SMACrossV2(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
// 初始:两个SMA 做空:SMA 15 8
|
||||
maLType := com.DefMaType(p, "maL", com.MaSMA)
|
||||
maSType := com.DefMaType(p, "maS", com.MaSMA)
|
||||
maLLen := p.DefInt("maLLen", 20, core.PNormF(7, 70, 20, 0))
|
||||
maSLen := p.DefInt("maSLen", 15, core.PNormF(5, 50, 15, 0))
|
||||
maLRate := p.Def("maLRate", 9, core.PNorm(2, 15))
|
||||
maSRate := p.Def("maSRate", 8, core.PNorm(2, 14))
|
||||
maLBig := int(math.Round(float64(maLLen) * maLRate))
|
||||
maSBig := int(math.Round(float64(maSLen) * maSRate))
|
||||
p.KeepHyperOnly("maSLen", "maSRate")
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 200,
|
||||
EachMaxShort: 1,
|
||||
EachMaxLong: 1,
|
||||
BatchInOut: true,
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
s.More = &maSta{}
|
||||
},
|
||||
OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
|
||||
return []*strat.PairSub{
|
||||
{"_cur_", "4h", 30},
|
||||
}
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
m, _ := s.More.(*maSta)
|
||||
c := e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, 30)
|
||||
openRate := 0.015 * c / atr.Get(0)
|
||||
if openRate < 1 {
|
||||
openRate = math.Sqrt(openRate)
|
||||
}
|
||||
er := ta.ER(e.Close, 50)
|
||||
erDelta := min(1.3, er.Get(0)/er.Get(12))
|
||||
if erDelta > 1 {
|
||||
openRate *= erDelta
|
||||
} else {
|
||||
// 过滤掉ER下降的
|
||||
openRate = 0
|
||||
}
|
||||
|
||||
// 方案一:多空SMA:略微平滑,收益略小一点
|
||||
// 方案二:多空VWMA:略微波动大点,收益略好一点
|
||||
price := ta.AvgPrice(e)
|
||||
ma1 := com.GetMA(price, e.Volume, maLType, maLLen)
|
||||
ma2 := com.GetMA(price, e.Volume, maLType, maLBig)
|
||||
x1 := ma1.Cross(ma2)
|
||||
if x1 == 1 && openRate > 0 {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "long", CostRate: openRate, Log: true})
|
||||
} else if x1 == -1 {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "xlong", Dirt: core.OdDirtLong, Log: true})
|
||||
}
|
||||
|
||||
if len(s.LongOrders) > 0 && m.openPrice < c && m.bigRsi > 80 && ma1.Get(0)-ma1.Get(2) > atr.Get(0)*0.5 {
|
||||
// 多仓,盈利,小均线变向平仓
|
||||
m.bigLong = true
|
||||
}
|
||||
//if m.bigLong && m.bigRsi > 70 {
|
||||
// m.bigLong = false
|
||||
// s.OpenOrder(&strat.EnterReq{Tag: "short2", Short: true, CostRate: openRate, Log: true})
|
||||
//}
|
||||
|
||||
ma3 := com.GetMA(price, e.Volume, maSType, maSLen)
|
||||
ma4 := com.GetMA(price, e.Volume, maSType, maSBig)
|
||||
x2 := ma3.Cross(ma4)
|
||||
if len(s.ShortOrders) == 0 && x2 == -1 && openRate > 0 {
|
||||
m.bigLong = false
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "short", Short: true, CostRate: openRate, Log: true})
|
||||
} else if x2 == 1 {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "xshort", Dirt: core.OdDirtShort, Log: true})
|
||||
}
|
||||
if len(s.ShortOrders) > 0 && m.bigRsi < 30 && s.ShortOrders[0].ProfitRate > 0 {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "xshort2", Dirt: core.OdDirtShort, Log: true})
|
||||
}
|
||||
//if !s.IsWarmUp {
|
||||
// line := fmt.Sprintf("%s %s %d %d %f %f %f %f %f atr:%f er:%f m1:%f m2:%f m3:%f m4:%f x1:%v x2:%v rate:%f",
|
||||
// s.Account, s.Symbol.Symbol, len(s.LongOrders), len(s.ShortOrders),
|
||||
// e.Open.Get(0), e.High.Get(0), e.Low.Get(0), e.Close.Get(0), e.Volume.Get(0),
|
||||
// atr.Get(0), er.Get(0), ma1.Get(0), ma2.Get(0), ma3.Get(0), ma4.Get(0),
|
||||
// x1, x2, openRate)
|
||||
// s.Strat.WriteOutput(line, true)
|
||||
//}
|
||||
},
|
||||
OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
|
||||
m, _ := s.More.(*maSta)
|
||||
m.bigRsi = ta.RSI(e.Close, 9).Get(0)
|
||||
},
|
||||
OnBatchJobs: func(jobs []*strat.StratJob) {
|
||||
longNum := float64(0)
|
||||
bigDown := float64(0)
|
||||
for _, s := range jobs {
|
||||
if len(s.LongOrders) == 0 {
|
||||
continue
|
||||
}
|
||||
longNum += 1
|
||||
m, _ := s.More.(*maSta)
|
||||
if m.bigLong {
|
||||
bigDown += 1
|
||||
}
|
||||
}
|
||||
if bigDown*1.5 > longNum && longNum*2 > float64(len(jobs)) {
|
||||
for _, s := range jobs {
|
||||
if len(s.LongOrders) == 0 {
|
||||
continue
|
||||
}
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "xlong2", Dirt: core.OdDirtLong, Log: true})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user