This commit is contained in:
2026-08-24 20:53:21 +08:00
commit 6e78bba16a
287 changed files with 32443 additions and 0 deletions

110
ptn/tunmo.go Normal file
View File

@@ -0,0 +1,110 @@
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)
}
}
},
}
}