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

View File

@@ -0,0 +1,98 @@
package trend
import (
"github.com/banbox/banbot/config"
"github.com/banbox/banbot/core"
"github.com/banbox/banbot/strat"
ta "github.com/banbox/banta"
"strconv"
)
/*
版本1:备份:2025/02/23
原始灵感:https://www.fmz.com/strategy/442547
已改动了大部分
测试在4h上表现最佳;210101-241101,48个品种
收益1919%,回撤23%,夏普5.5
添加adx过滤,收益增加
测试使用ATRBase显著收益下降
*/
type supFlwMore struct {
enter *strat.EnterReq
exitIds []int64
}
func SuperFollow(p *config.RunPolicyConfig) *strat.TradeStrat {
atrLen := 14 // 默认12
mult := p.Def("mult", 1.4, core.PNorm(0.7, 2.5))
sRate := p.Def("sRate", 1.1, core.PNorm(0.7, 1.8))
slAtr := p.Def("slAtr", 1.6, core.PNorm(1, 2.5))
tpRate := p.Def("tpRate", 3, core.PNorm(1.7, 5.5))
shortMult := -mult * sRate
return &strat.TradeStrat{
WarmupNum: 200,
EachMaxShort: 1,
EachMaxLong: 1,
//OnStartUp: func(s *strat.StratJob) {
// s.More = &supFlwMore{}
//},
//OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
// return []*strat.PairSub{
// {"_cur_", "4h", 200},
// }
//},
//OnBar: func(s *strat.StratJob) {
// m, _ := s.More.(*supFlwMore)
// if m.enter != nil {
// s.OpenOrder(m.enter)
// m.enter = nil
// } else if len(m.exitIds) > 0 {
// for _, id := range m.exitIds {
// s.CloseOrders(&strat.ExitReq{Tag: "tooLong", OrderID: id})
// }
// m.exitIds = nil
// }
//},
//OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
// m, _ := s.More.(*supFlwMore)
OnBar: func(s *strat.StratJob) {
e := s.Env
o, c := e.Open.Get(0), e.Close.Get(0)
atr := ta.ATR(e.High, e.Low, e.Close, atrLen).Get(0)
dist := (c - o) / atr
adx := ta.ADX(e.High, e.Low, e.Close, 30).Get(0)
openDirt := 0
overRate := 0.0
if len(s.ShortOrders) == 0 && dist < shortMult && adx < 20 {
openDirt = -1
overRate = dist / shortMult
} else if len(s.LongOrders) == 0 && dist > mult {
openDirt = 1
overRate = dist / mult
}
if openDirt != 0 {
costRate := overRate * 1.1
s.OpenOrder(&strat.EnterReq{
Tag: strconv.Itoa(openDirt),
Short: openDirt < 0,
TakeProfitVal: atr * slAtr * tpRate * overRate,
StopLossVal: atr * slAtr * overRate,
CostRate: costRate,
})
} else {
// 长期未关闭的,超过200个平仓
odList := s.GetOrders(core.OdDirtBoth)
for _, od := range odList {
holdNum := e.BarCount(od.EnterAt)
if holdNum > 200 {
s.CloseOrders(&strat.ExitReq{Tag: "tooLong", OrderID: od.ID})
}
}
}
},
}
}