package llmjob import ( "github.com/banbox/banbot/config" "github.com/banbox/banbot/core" "github.com/banbox/banbot/orm/ormo" "github.com/banbox/banbot/strat" ta "github.com/banbox/banta" "math" ) /* 因止损未检查bug导致表现看起来很好,不可用 */ type State5689 struct { entryPrice float64 hlv3 int // 保存三重均线状态 } func J5689(pol *config.RunPolicyConfig) *strat.TradeStrat { // 定义可调超参数 tpPercent := pol.Def("tpPercent", 0.33, core.PNorm(0.15, 0.5)) // 止盈百分比 length := pol.DefInt("length", 18, core.PNorm(10, 50)) // 通道计算周期 lengthChop := pol.DefInt("lengthChop", 14, core.PNorm(5, 30)) // CHOP指标周期 emaPeriod := pol.DefInt("emaPeriod", 10, core.PNorm(5, 30)) // EMA平滑周期 maPeriod := pol.DefInt("maPeriod", 50, core.PNorm(30, 100)) // 主均线周期 channelRate := pol.Def("channelRate", 0.15, core.PNorm(0.1, 0.5)) // 通道倍率 exitPeriod := pol.DefInt("exitPeriod", 12, core.PNorm(5, 30)) // 退出均线周期 return &strat.TradeStrat{ WarmupNum: maPeriod, // 预热K线数量,至少需要主均线周期 RunTimeFrames: []string{"1h"}, OnStartUp: func(s *strat.StratJob) { // 初始化每个品种的状态变量 s.More = &State5689{ entryPrice: math.NaN(), hlv3: 0, // 初始状态为0 } }, OnBar: func(s *strat.StratJob) { e := s.Env state, _ := s.More.(*State5689) // 计算技术指标 upper := ta.Highest(e.High, length) lower := ta.Lowest(e.Low, length) // 计算output值:价格在通道中的百分比位置 output := e.Close.Sub(upper).Div(upper.Sub(lower)).Mul(100) emaOutput := ta.EMA(output, emaPeriod) // 自定义MA函数:双重WMA平滑 maFunc := func(src *ta.Series, len int) *ta.Series { wma1 := ta.WMA(src, len/2) wma2 := ta.WMA(src, len) return ta.WMA(wma1.Mul(2).Sub(wma2), int(math.Round(math.Sqrt(float64(len))))) } // 计算主均线和通道 BBMC := maFunc(e.Close, maPeriod) rangema := ta.EMA(ta.TR(e.High, e.Low, e.Close), maPeriod) upperk := BBMC.Add(rangema.Mul(channelRate)) lowerk := BBMC.Sub(rangema.Mul(channelRate)) // 计算退出均线 exitHigh := ta.WMA(e.High, exitPeriod) exitLow := ta.WMA(e.Low, exitPeriod) // 计算RSI指标(原始代码中计算但未使用) _ = ta.RSI(e.Close, 14) // 计算CHOP指标(虽然不影响交易逻辑,但为了完整性实现) atr1 := ta.ATR(e.High, e.Low, e.Close, 1) sumAtr := ta.Sum(atr1, lengthChop) highestChop := ta.Highest(e.High, lengthChop) lowestChop := ta.Lowest(e.Low, lengthChop) chopRange := highestChop.Sub(lowestChop) // 避免除以零 chopRangeValid := chopRange.Get(0) > 0 if chopRangeValid { _ = sumAtr.Div(chopRange).Mul(100) } else { _ = ta.EMA(e.Close, 1).Mul(0) // 创建全0序列 } // 获取当前值 closePrice := e.Close.Get(0) upperkVal := upperk.Get(0) lowerkVal := lowerk.Get(0) BBMCVal := BBMC.Get(0) outputVal := output.Get(0) emaOutputVal := emaOutput.Get(0) exitHighVal := exitHigh.Get(0) exitLowVal := exitLow.Get(0) // 检查数据有效性 if math.IsNaN(closePrice) || math.IsNaN(BBMCVal) || math.IsNaN(outputVal) || math.IsNaN(emaOutputVal) { return } // 判断价格位置和颜色 colorBlue := closePrice > upperkVal colorBarFuchsia := closePrice < lowerkVal // 更新三重均线状态 if closePrice > exitHighVal { state.hlv3 = 1 } else if closePrice < exitLowVal { state.hlv3 = -1 } // 否则保持上一个状态 // 计算退出线 _ = exitHigh if state.hlv3 < 0 { _ = exitLow } // 生成交易信号 closeXBBMC := e.Close.Cross(BBMC) longCondition := closeXBBMC == 1 && outputVal > emaOutputVal shortCondition := closeXBBMC == -1 && outputVal < emaOutputVal // 执行交易逻辑 if longCondition && len(s.LongOrders) == 0 { // 记录入场价格 state.entryPrice = closePrice // 开多单 s.OpenOrder(&strat.EnterReq{ Tag: "ENTER-LONG", OrderType: core.OrderTypeMarket, TakeProfit: closePrice * (1 + tpPercent), }) } // 为已有订单设置动态止损 if len(s.LongOrders) > 0 && !math.IsNaN(state.entryPrice) { od := s.LongOrders[0] if od.Status == ormo.InOutStatusFullEnter { // 只有当color_bar为FUCHSIA时才设置止损 if colorBarFuchsia && !math.IsNaN(BBMCVal) { // 设置BBMC作为止损价格 od.SetStopLoss(&ormo.ExitTrigger{ Price: BBMCVal, Rate: 1.0, // 全部退出 Tag: "dynamic_stop_loss", }) } else { // 不设置止损 od.SetStopLoss(nil) } // 更新止盈 takeProfitPrice := state.entryPrice * (1 + tpPercent) od.SetTakeProfit(&ormo.ExitTrigger{ Price: takeProfitPrice, Rate: 1.0, // 全部退出 Tag: "take_profit", }) } } // 做空部分(原始代码中被注释,这里也注释掉) if shortCondition && len(s.ShortOrders) == 0 { state.entryPrice = closePrice s.OpenOrder(&strat.EnterReq{ Tag: "ENTER-SHORT", OrderType: core.OrderTypeMarket, Short: true, TakeProfit: closePrice * (1 - tpPercent), }) } if len(s.ShortOrders) > 0 && !math.IsNaN(state.entryPrice) { od := s.ShortOrders[0] if od.Status == ormo.InOutStatusFullEnter { // 只有当color_bar为BLUE时才设置止损 if colorBlue && !math.IsNaN(BBMCVal) { // 设置BBMC作为止损价格 od.SetStopLoss(&ormo.ExitTrigger{ Price: BBMCVal, Rate: 1.0, // 全部退出 Tag: "dynamic_stop_loss_short", }) } else { // 不设置止损 od.SetStopLoss(nil) } // 更新止盈 takeProfitPrice := state.entryPrice * (1 - tpPercent) od.SetTakeProfit(&ormo.ExitTrigger{ Price: takeProfitPrice, Rate: 1.0, // 全部退出 Tag: "take_profit_short", }) } } }, } }