package llmjob import ( "math" "github.com/banbox/banbot/config" "github.com/banbox/banbot/core" "github.com/banbox/banbot/strat" ta "github.com/banbox/banta" ) func J4217(pol *config.RunPolicyConfig) *strat.TradeStrat { // 定义可调参数 fastLength := pol.DefInt("fastLength", 9, core.PNorm(5, 20)) maRate := pol.Def("maRate", 2.33, core.PNorm(1.5, 5)) rsiLength := pol.DefInt("rsiLength", 14, core.PNorm(7, 21)) rsiThreshold := pol.DefInt("rsiThreshold", 70, core.PNorm(60, 80)) atrStopLoss := pol.Def("atrStopLoss", 2.0, core.PNorm(1.0, 4.0)) atrPeriod := pol.DefInt("atrPeriod", 14, core.PNorm(7, 21)) // 添加MACD参数配置 macdFast := pol.DefInt("macdFast", 12, core.PNorm(8, 20)) macdSlow := pol.DefInt("macdSlow", 26, core.PNorm(20, 40)) macdSignal := pol.DefInt("macdSignal", 9, core.PNorm(5, 15)) // 计算慢速EMA周期 slowLength := int(float64(fastLength) * maRate) // 计算RSI超买超卖水平 rsiOverboughtLevel := float64(rsiThreshold) rsiOversoldLevel := 100 - float64(rsiThreshold) return &strat.TradeStrat{ WarmupNum: slowLength + atrPeriod, // 确保有足够的数据计算指标 HedgeOff: true, // 单向持仓模式 EachMaxLong: 1, // 最多开1个多单 EachMaxShort: 1, // 最多开1个空单 TimeFrames: "8h", OnBar: func(s *strat.StratJob) { e := s.Env // 计算技术指标 fastMA := ta.EMA(e.Close, fastLength) slowMA := ta.EMA(e.Close, slowLength) rsi := ta.RSI(e.Close, rsiLength) // 使用配置的MACD参数 macdLine, signalLine := ta.MACD(e.Close, macdFast, macdSlow, macdSignal) atr := ta.ATR(e.High, e.Low, e.Close, atrPeriod) // 获取最新值 fastMAVal := fastMA.Get(0) slowMAVal := slowMA.Get(0) rsiVal := rsi.Get(0) atrVal := atr.Get(0) // 检查数据有效性 if math.IsNaN(fastMAVal) || math.IsNaN(slowMAVal) || math.IsNaN(rsiVal) || math.IsNaN(atrVal) { return } // 判断趋势 bullishTrend := fastMAVal > slowMAVal bearishTrend := fastMAVal < slowMAVal // 生成交易信号 longCondition := bullishTrend && rsiVal < rsiOverboughtLevel && macdLine.Cross(signalLine) == 1 shortCondition := bearishTrend && rsiVal > rsiOversoldLevel && macdLine.Cross(signalLine) == -1 // 计算止损距离 stopLossDistance := atrVal * atrStopLoss // 执行交易操作 if longCondition && len(s.LongOrders) == 0 { // 开多单 s.OpenOrder(&strat.EnterReq{ Tag: "Long", Short: false, StopLossVal: stopLossDistance, StopLossTag: "ATR Stop Loss", }) } if shortCondition && len(s.ShortOrders) == 0 { // 开空单 s.OpenOrder(&strat.EnterReq{ Tag: "Short", Short: true, StopLossVal: stopLossDistance, StopLossTag: "ATR Stop Loss", }) } // 平仓条件 if len(s.LongOrders) > 0 && (bearishTrend || rsiVal > rsiOverboughtLevel) { // 平多单 s.CloseOrders(&strat.ExitReq{ Tag: "Close Long", Dirt: core.OdDirtLong, }) } if len(s.ShortOrders) > 0 && (bullishTrend || rsiVal < rsiOversoldLevel) { // 平空单 s.CloseOrders(&strat.ExitReq{ Tag: "Close Short", Dirt: core.OdDirtShort, }) } }, } }