package demo import ( "github.com/banbox/banbot/config" "github.com/banbox/banbot/core" "github.com/banbox/banbot/strat" ta "github.com/banbox/banta" ) func Made(pol *config.RunPolicyConfig) *strat.TradeStrat { // 定义可调超参数 fastMAPeriod := pol.DefInt("fast_ma_period", 5, core.PUniform(3, 10)) slowMAPeriod := pol.DefInt("slow_ma_period", 20, core.PUniform(10, 40)) atrPeriod := pol.DefInt("atr_period", 14, core.PUniform(7, 21)) slRate := pol.Def("sl_rate", 2.0, core.PUniform(1.0, 4.0)) return &strat.TradeStrat{ WarmupNum: 100, EachMaxLong: 1, EachMaxShort: 1, DrawDownExit: true, // 启用回撤止盈 OnBar: func(s *strat.StratJob) { e := s.Env // 计算技术指标 maFast := ta.SMA(e.Close, fastMAPeriod) maSlow := ta.SMA(e.Close, slowMAPeriod) atr := ta.ATR(e.High, e.Low, e.Close, atrPeriod) // 计算均线交叉信号 maCrossOver := maFast.Cross(maSlow) // 1 表示上穿 maCrossUnder := maSlow.Cross(maFast) // 1 表示下穿 // 获取当前价格和ATR值 currentPrice := e.Close.Get(0) currentATR := atr.Get(0) // 多头入场信号:快线上穿慢线(金叉) if maCrossOver == 1 { if s.GetOrderNum(core.OdDirtShort) > 0 { s.CloseOrders(&strat.ExitReq{Dirt: core.OdDirtShort, Tag: "exit_short"}) } if s.GetOrderNum(core.OdDirtLong) == 0 { stopLossPrice := currentPrice - currentATR*slRate s.OpenOrder(&strat.EnterReq{ Tag: "long", StopLoss: stopLossPrice, StopLossTag: "atr_sl_long", }) } } // 空头入场信号:快线下穿慢线(死叉) if maCrossUnder == 1 { if s.GetOrderNum(core.OdDirtLong) > 0 { s.CloseOrders(&strat.ExitReq{Dirt: core.OdDirtLong, Tag: "exit_long"}) } if s.GetOrderNum(core.OdDirtShort) == 0 { stopLossPrice := currentPrice + currentATR*slRate s.OpenOrder(&strat.EnterReq{ Tag: "short", Short: true, StopLoss: stopLossPrice, StopLossTag: "atr_sl_short", }) } } // 多头出场信号:快线下穿慢线(死叉) if maCrossUnder == 1 && s.GetOrderNum(core.OdDirtLong) > 0 { s.CloseOrders(&strat.ExitReq{ Dirt: core.OdDirtLong, Tag: "exit_long", }) } // 空头出场信号:快线上穿慢线(金叉) if maCrossOver == 1 && s.GetOrderNum(core.OdDirtShort) > 0 { s.CloseOrders(&strat.ExitReq{ Dirt: core.OdDirtShort, Tag: "exit_short", }) } }, } }