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 J3955(pol *config.RunPolicyConfig) *strat.TradeStrat { // 定义可调超参数 macdFastPeriod := pol.DefInt("macdFastPeriod", 14, core.PNorm(5, 20)) macdSlowRate := pol.Def("macdSlowRate", 2, core.PNorm(1.5, 4)) macdSignalPeriod := pol.DefInt("macdSignalPeriod", 9, core.PNorm(5, 15)) vwmaFastPeriod := pol.DefInt("vwmaFastPeriod", 20, core.PNorm(10, 40)) leverage := pol.DefInt("leverage", 1, core.PNorm(1, 20)) // 计算MACD慢线周期 macdSlowPeriod := int(float64(macdFastPeriod) * macdSlowRate) return &strat.TradeStrat{ WarmupNum: macdSlowPeriod + macdSignalPeriod, // 确保有足够的数据计算指标 HedgeOff: true, // 单向持仓模式 EachMaxLong: 1, // 最多一个多头订单 EachMaxShort: 1, // 最多一个空头订单 RunTimeFrames: []string{"8h"}, OnBar: func(s *strat.StratJob) { e := s.Env // 计算MACD指标 macdLine, signalLine := ta.MACD(e.Close, macdFastPeriod, macdSlowPeriod, macdSignalPeriod) histogram := macdLine.Sub(signalLine) // 计算MACD柱状图 // 计算VWMA指标 vwma20 := ta.VWMA(e.Close, e.Volume, vwmaFastPeriod) // 使用VWMA替代WMA,考虑成交量因素 vwma50 := ta.VWMA(e.Close, e.Volume, 50) // 使用VWMA替代WMA,考虑成交量因素 // 获取当前指标值 macdLineVal := macdLine.Get(0) signalLineVal := signalLine.Get(0) histogramVal := histogram.Get(0) vwma20Val := vwma20.Get(0) vwma50Val := vwma50.Get(0) // 检查数据有效性 if math.IsNaN(macdLineVal) || math.IsNaN(signalLineVal) || math.IsNaN(histogramVal) || math.IsNaN(vwma20Val) || math.IsNaN(vwma50Val) { return } // 生成MACD信号 macdLongEntrySignal := histogramVal > 0 macdShortEntrySignal := histogramVal < 0 // 生成VWMA信号 vwmaLongEntrySignal := vwma20Val > vwma50Val vwmaShortEntrySignal := vwma20Val < vwma50Val // 生成组合交易信号 longEntry := macdLongEntrySignal && vwmaLongEntrySignal shortEntry := macdShortEntrySignal && vwmaShortEntrySignal // 检测MACD交叉信号作为出场条件(优化为单次调用) cross := macdLine.Cross(signalLine) longExit := cross == -1 // MACD线下穿信号线 shortExit := cross == 1 // MACD线上穿信号线 // 执行交易逻辑 if longEntry && len(s.LongOrders) == 0 { // 计算杠杆化后的合约数量 costRate := float64(leverage) s.OpenOrder(&strat.EnterReq{ Tag: "Long", Short: false, CostRate: costRate, Leverage: float64(leverage), OrderType: core.OrderTypeMarket, }) } if longExit && len(s.LongOrders) > 0 { s.CloseOrders(&strat.ExitReq{ Tag: "LongExit", Dirt: core.OdDirtLong, }) } if shortEntry && len(s.ShortOrders) == 0 { // 计算杠杆化后的合约数量 costRate := float64(leverage) s.OpenOrder(&strat.EnterReq{ Tag: "Short", Short: true, CostRate: costRate, Leverage: float64(leverage), OrderType: core.OrderTypeMarket, }) } if shortExit && len(s.ShortOrders) > 0 { s.CloseOrders(&strat.ExitReq{ Tag: "ShortExit", Dirt: core.OdDirtShort, }) } }, } }