97 lines
2.5 KiB
Go
97 lines
2.5 KiB
Go
package hammer
|
||
|
||
import (
|
||
"fmt"
|
||
"github.com/banbox/banbot/config"
|
||
"github.com/banbox/banbot/strat"
|
||
"github.com/banbox/banexg"
|
||
ta "github.com/banbox/banta"
|
||
"math"
|
||
)
|
||
|
||
/*
|
||
加入RSI低于55限制,同时调低atr倍率,允许更多机会。
|
||
测试效果不如V4,弃用
|
||
*/
|
||
|
||
const (
|
||
v5AtrLen = 14
|
||
v5WatchMin = 5 // 入场后观察后续蜡烛的最少个数
|
||
v5WatchMax = 100 // 入场后观察后续蜡烛的最多个数
|
||
v5RefNum = 20 // 回顾历史回撤的数量
|
||
)
|
||
|
||
func makeV5OnBar(atrLen, refNum, watchMin, watchMax int, baseRate float64) func(s *strat.StratJob) {
|
||
return func(s *strat.StratJob) {
|
||
e := s.Env
|
||
ma5 := ta.SMA(e.Close, 5).Get(0)
|
||
atr := ta.ATR(e.High, e.Low, e.Close, atrLen)
|
||
baseAtrLen := int(math.Round(float64(atrLen) * 4.3))
|
||
atrBase := ta.Lowest(ta.Highest(atr, atrLen), baseAtrLen).Get(0)
|
||
|
||
rsiCol := ta.RSI(e.Close, 20)
|
||
rsi, rsiPrv := rsiCol.Get(0), rsiCol.Get(1)
|
||
|
||
more, _ := s.More.(*MoreHammer)
|
||
|
||
if math.IsNaN(atrBase) {
|
||
return
|
||
}
|
||
rsiOk := rsiPrv >= 70 && rsiPrv-rsi > 30 || (rsiPrv+rsi)/2 < 55
|
||
if !rsiOk {
|
||
return
|
||
}
|
||
o, h, l, c := e.Open.Get(0), e.High.Get(0), e.Low.Get(0), e.Close.Get(0)
|
||
v := e.Volume.Get(0)
|
||
solid := math.Abs(o - c)
|
||
btm := min(o, c) - l
|
||
up := h - max(o, c)
|
||
if btm > max(2.0*solid, up*5.0, atrBase*baseRate) && c < ma5 {
|
||
// 检查是否处于信号后观察模式
|
||
CloseWatch(s, more, refNum)
|
||
// 开始新观察
|
||
bar := &banexg.Kline{Time: e.TimeStart, Open: o, High: h, Low: l, Close: c, Volume: v}
|
||
StartWatch(e, more, bar, btm/atrBase)
|
||
// 创建入场订单
|
||
limit := c - (c-l)*more.backRate*0.55
|
||
stopLoss := c - atr.Get(0)*3.0
|
||
if stopLoss >= limit {
|
||
stopLoss = limit - atr.Get(0)
|
||
}
|
||
err := s.OpenOrder(&strat.EnterReq{
|
||
Tag: "long",
|
||
Limit: limit,
|
||
StopLoss: stopLoss,
|
||
})
|
||
if err != nil {
|
||
fmt.Printf("open fail %v", err)
|
||
}
|
||
} else if more.lastEnt > 0 {
|
||
// 更新观察数据
|
||
UpdateWatch(s, more, c, l, watchMin, watchMax, refNum)
|
||
}
|
||
}
|
||
}
|
||
|
||
func MainV5(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||
return &strat.TradeStrat{
|
||
Version: 1,
|
||
WarmupNum: 3000,
|
||
MinTfScore: 0.75,
|
||
DrawDownExit: true,
|
||
StopEnterBars: 10,
|
||
OnStartUp: func(s *strat.StratJob) {
|
||
s.More = &MoreHammer{
|
||
odInfos: map[int64]*OdInfo{},
|
||
}
|
||
},
|
||
OnBar: makeV5OnBar(v5AtrLen, v5RefNum, v5WatchMin, v5WatchMax, 2.2),
|
||
OnOrderChange: onOrderChange,
|
||
GetDrawDownExitRate: makeDrawDownExit(0.8, [][2]float64{
|
||
{0.625, 0.25},
|
||
{0.3, 0.37},
|
||
{0.15, 0.5},
|
||
}),
|
||
}
|
||
}
|