init
This commit is contained in:
110
ptn/tunmo.go
Normal file
110
ptn/tunmo.go
Normal 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)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user