package trend import ( "github.com/banbox/banbot/config" "github.com/banbox/banbot/core" "github.com/banbox/banbot/orm/ormo" "github.com/banbox/banbot/strat" ta "github.com/banbox/banta" "math" ) /* 基于MACDEMAV2,修改做空部分。做空的表现和SMACrossV1很相似,导致趋同性回撤 压力位开空,止损为atr 盈利空间超过atr,设置止损为c+atr 盈利超过3倍atr,设置止损0.6 10个bar时,小亏,直接平仓 */ func MACDEMAV3(p *config.RunPolicyConfig) *strat.TradeStrat { emaLen := p.DefInt("emaLen", 100, core.PNormF(30, 240, 100, 0)) macdRt := p.Def("macdRt", 1, core.PNormF(0.7, 3, 1.2, 0)) lenAtr := int(p.Def("atr", 29, core.PNorm(7, 40))) baseAtrLen := int(float64(lenAtr) * 4.3) mc1, mc2, mc3 := int(math.Round(12*macdRt)), int(math.Round(26*macdRt)), int(math.Round(9*macdRt)) p.KeepHyperOnly("emaLen", "macdRt") stateKey := "state" return &strat.TradeStrat{ WarmupNum: 500, EachMaxLong: 1, EachMaxShort: 1, OnBar: func(s *strat.StratJob) { e := s.Env c := e.Close.Get(0) atr := ta.ATR(e.High, e.Low, e.Close, lenAtr) atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0) atrVal := atr.Get(0) atrMa := (atrBase + atrVal) / 2 ema := ta.EMA(e.Close, emaLen).Get(0) macd, signal := ta.MACD(e.Close, mc1, mc2, mc3) macdSub := macd.Get(0) - signal.Get(0) hh3 := ta.Highest(e.High, 3).Get(0) _, kdjD, _ := ta.KDJBy(e.High, e.Low, e.Close, 13, 3, 3, "sma") dSMA := ta.SMA(kdjD, 3) isYaLi := dSMA.Cross(80.5) == 1 // crossover if (c-ema)*macdSub > 0 { if macdSub < 0 { if len(s.LongOrders) > 0 { s.CloseOrders(&strat.ExitReq{ Tag: "closeL", Dirt: core.OdDirtLong, }) } } else { //s.OpenOrder(&strat.EnterReq{ // Tag: "long", //}) } } if len(s.ShortOrders) > 0 { low := e.Low.Get(0) for _, od := range s.ShortOrders { if od.Status < ormo.InOutStatusFullEnter { continue } // state: 0初始止损 1平衡止损c+atr 2盈利宽止损 state := od.GetInfoFloat64(stateKey) bestRange := od.InitPrice - low sl := od.GetStopLoss() if bestRange > atrMa*2 || state == 2 { // 处于较好盈利 newSl := c + bestRange*0.35 if newSl < sl.Price { od.SetStopLoss(&ormo.ExitTrigger{Price: newSl, Tag: "good"}) od.SetInfo(stateKey, 2) } continue } holdNum := e.BarCount(od.EnterAt) if holdNum > 9.5 && od.Profit < 0 { // 超过10个bar,依然亏,直接平 s.CloseOrders(&strat.ExitReq{Tag: "exit10", OrderID: od.ID}) continue } if bestRange > atrMa*0.6 || state == 1 { // 处于平衡状态 newSL := c + atrMa*0.3 if newSL < sl.Price { od.SetStopLoss(&ormo.ExitTrigger{Price: newSL, Tag: "zero"}) od.SetInfo(stateKey, 1) } } } } if isYaLi && len(s.ShortOrders) == 0 { s.OpenOrder(&strat.EnterReq{ Tag: "short", Short: true, Limit: hh3 - atrMa*0.5, StopLoss: hh3 + atrMa, StopBars: 7, }) } }, } }