package ptn import ( "fmt" "github.com/banbox/banbot/config" "github.com/banbox/banbot/strat" ta "github.com/banbox/banta" "math" ) type tunmoMore struct { topVal float64 btmVal float64 barNum int } /* 检查是否是吞没形态 */ func isTunMo(e *ta.BarEnv) (int, float64, float64) { o, h, l, c := GetMains(e, 0) o1, h1, l1, c1 := GetMains(e, 1) solid := math.Abs(o - c) if solid/(h-l) < 0.6 { // 第二个蜡烛实体至少60% return 0, 0, 0 } solid1 := math.Abs(o1 - c1) if solid1/(h1-l1) <= 0.13 && solid > solid1*3 { // 第一个是十字星,直接符合 if o > c { return -1, min(l, l1), max(h, h1) } else { return 1, min(l, l1), max(h, h1) } } if o < c { // 后一个是阳线,要求前一个是阴线 if o1 > c1 && o1 <= c && c1 >= o { // 前开<收盘 & 前收 > 开盘 return 1, min(l, l1), max(h, h1) } } else if o1 < c1 && c1 <= o && o1 >= c { // 后一个阴线,要求前一个阳线 // 前收<开盘 & 前开 > 收盘 return -1, min(l, l1), max(h, h1) } return 0, 0, 0 } func TunMo(pol *config.RunPolicyConfig) *strat.TradeStrat { const v1AtrLen = 14 return &strat.TradeStrat{ Version: 1, WarmupNum: 30, MinTfScore: 0.75, DrawDownExit: true, OnStartUp: func(s *strat.StratJob) { s.More = &tunmoMore{} }, OnBar: func(s *strat.StratJob) { e := s.Env // ma5 := ta.SMA(e.Close, 5).Get(1) atr := ta.ATR(e.High, e.Low, e.Close, v1AtrLen) baseAtrLen := int(math.Round(float64(v1AtrLen) * 4.3)) atrBase := ta.Lowest(ta.Highest(atr, v1AtrLen), baseAtrLen).Get(0) //rsiCol := ta.RSI(e.Close, 14) //rsi := rsiCol.Range(0, 2) if math.IsNaN(atrBase) || s.OrderNum > 0 { return } m, _ := s.More.(*tunmoMore) mode, btmVal, topVal := isTunMo(e) if mode != 0 && atr.Get(0) > atrBase*2 { m.btmVal = btmVal - atrBase m.topVal = topVal + atrBase m.barNum = e.BarNum } if e.BarNum-m.barNum > 10 { // 忽略吞没形态10个之后的蜡烛 return } c := e.Close.Get(0) // slices.Max(rsi) > 70 // && c > ma5 if c > m.topVal { stopLoss := max(m.topVal, c) + atr.Get(0) err := s.OpenOrder(&strat.EnterReq{ Tag: "short", StopLoss: stopLoss, Short: true, }) if err != nil { fmt.Printf("open fail %v", err) } } else if c < m.btmVal { stopLoss := min(m.btmVal, c) - atr.Get(0) err := s.OpenOrder(&strat.EnterReq{ Tag: "long", StopLoss: stopLoss, }) if err != nil { fmt.Printf("open fail %v", err) } } }, } }