package trend import ( "github.com/banbox/banbot/config" "github.com/banbox/banbot/core" "github.com/banbox/banbot/strat" "github.com/banbox/banstagy/com" ta "github.com/banbox/banta" "math" ) /* 测试加入1d的大周期过滤,对做多或做空都未获得更好效果,反而略差 20210101-20250101 只做多:1776%,回撤28.8%,夏普3.93 多空双开:1913%,回撤22%,夏普4.53 做空部分单独运行波动很大,但和做多一起运行可减少做多的回撤 参考SMACross1加入海龟资金和ErDelta过滤后: 170品种下:夏普从7.97提升到8.91,显示最大回撤从18.71%下降到17.65%;收益从718%变为707% 2025/02/25 ERChg<1时保留ATR比率开单,整体*1.15 */ type entExitMore struct { enter *strat.EnterReq exit *strat.ExitReq } func MACDEMAV2(p *config.RunPolicyConfig) *strat.TradeStrat { // 初始HMA 25 4 maType := com.DefMaType(p, "ma", com.MaHMA) // hma 包揽优化列表头部 maLen := p.DefInt("maLen", 15, core.PNormF(7, 100, 25, 0)) // 超过40表现不佳,20多表现最好 maRate := p.Def("maRate", 4.1, core.PNorm(1.5, 7)) emaLen := p.DefInt("emaLen", 100, core.PNormF(30, 240, 100, 0)) macdRt := p.Def("macdRt", 1, core.PNormF(0.7, 3, 1.2, 0)) maBigLen := int(math.Round(float64(maLen) * maRate)) mc1, mc2, mc3 := int(math.Round(12*macdRt)), int(math.Round(26*macdRt)), int(math.Round(9*macdRt)) p.KeepHyperOnly("ma", "maLen", "maRate") return &strat.TradeStrat{ WarmupNum: 500, EachMaxLong: 1, EachMaxShort: 1, //OnStartUp: func(s *strat.StratJob) { // s.More = &entExitMore{} //}, //OnPairInfos: func(s *strat.StratJob) []*strat.PairSub { // return []*strat.PairSub{ // {"_cur_", "4h", 500}, // } //}, //OnBar: func(s *strat.StratJob) { // m, _ := s.More.(*entExitMore) // if m.enter != nil { // s.OpenOrder(m.enter) // m.enter = nil // } // if m.exit != nil { // s.CloseOrders(m.exit) // m.exit = nil // } //}, //OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) { // m, _ := s.More.(*entExitMore) OnBar: func(s *strat.StratJob) { e := s.Env c := e.Close.Get(0) atr := ta.ATR(e.High, e.Low, e.Close, 30) openRate := 0.015 * c / atr.Get(0) if openRate < 1 { openRate = math.Sqrt(openRate) } openRate *= 1.15 er := ta.ER(e.Close, 50) erDelta := min(1.3, er.Get(0)/er.Get(12)) if erDelta > 1 { openRate *= erDelta } ema := ta.EMA(e.Close, emaLen).Get(0) macd, signal := ta.MACD(e.Close, mc1, mc2, mc3) macdSub := macd.Get(0) - signal.Get(0) if c > ema && macdSub > 0 && len(s.LongOrders) == 0 { s.OpenOrder(&strat.EnterReq{ Tag: "long", CostRate: openRate, }) } else if len(s.LongOrders) > 0 && (macdSub < 0 && c < ema) { s.CloseOrders(&strat.ExitReq{ Tag: "closeL", Dirt: core.OdDirtLong, }) } ma1 := com.GetMA(e.Close, e.Volume, maType, maLen) ma2 := com.GetMA(e.Close, e.Volume, maType, maBigLen) cross := ma1.Cross(ma2) if cross == 1 && len(s.ShortOrders) > 0 { s.CloseOrders(&strat.ExitReq{ Tag: "closeS", Dirt: core.OdDirtShort, }) } else if cross == -1 && len(s.ShortOrders) == 0 { s.OpenOrder(&strat.EnterReq{ Tag: "short", Short: true, CostRate: openRate, }) } }, } }