// 修复后的完整策略代码 // 请勿修改package包名和任意函数名 package llmjob import ( "github.com/banbox/banbot/config" "github.com/banbox/banbot/core" "github.com/banbox/banbot/strat" ta "github.com/banbox/banta" "math" ) func J4670(pol *config.RunPolicyConfig) *strat.TradeStrat { fastEMAPeriod := pol.DefInt("fastEMAPeriod", 10, core.PNorm(3, 15)) emaRate := pol.Def("emaRate", 2.5, core.PNorm(1.5, 5)) stopLossPercent := pol.Def("stopLossPercent", 2, core.PNorm(0.5, 5)) takeProfitPercent := pol.Def("takeProfitPercent", 4, core.PNorm(1, 10)) // 计算慢速EMA周期 slowEMAPeriod := int(float64(fastEMAPeriod) * emaRate) return &strat.TradeStrat{ WarmupNum: slowEMAPeriod * 2, // 预热数量设置为慢速EMA周期的2倍 HedgeOff: true, // 单向持仓模式 EachMaxLong: 1, // 最多同时持有一个多头仓位 EachMaxShort: 1, // 最多同时持有一个空头仓位 RunTimeFrames: []string{"8h"}, OnBar: func(s *strat.StratJob) { e := s.Env // 计算EMA指标 ema5 := ta.EMA(e.Close, fastEMAPeriod) ema15 := ta.EMA(e.Close, slowEMAPeriod) // 获取当前价格 currentPrice := e.Close.Get(0) if math.IsNaN(currentPrice) { return } // 检测EMA交叉(只计算一次) crossSignal := ema5.Cross(ema15) longCondition := crossSignal == 1 // 5周期EMA上穿15周期EMA shortCondition := crossSignal == -1 // 5周期EMA下穿15周期EMA // 执行交易逻辑 if longCondition && len(s.LongOrders) == 0 { // 开多单,使用入场价格计算止损止盈 s.OpenOrder(&strat.EnterReq{ Tag: "Long", StopLossVal: currentPrice * stopLossPercent / 100, TakeProfitVal: currentPrice * takeProfitPercent / 100, StopLossTag: "Stop Loss", TakeProfitTag: "Take Profit", }) } if shortCondition && len(s.ShortOrders) == 0 { // 开空单,使用入场价格计算止损止盈 s.OpenOrder(&strat.EnterReq{ Tag: "Short", Short: true, StopLossVal: currentPrice * stopLossPercent / 100, TakeProfitVal: currentPrice * takeProfitPercent / 100, StopLossTag: "Stop Loss", TakeProfitTag: "Take Profit", }) } }, } }