package llmjob import ( "github.com/banbox/banbot/config" "github.com/banbox/banbot/core" "github.com/banbox/banbot/strat" ta "github.com/banbox/banta" ) func J8179(pol *config.RunPolicyConfig) *strat.TradeStrat { // 定义可调超参数 lookback := pol.DefInt("lookback", 20, core.PNorm(5, 25)) // 随机振荡器计算周期 kSmoothing := pol.DefInt("kSmoothing", 4, core.PNorm(1, 10)) // %K线平滑周期 maLookback := pol.DefInt("maLookback", 19, core.PNorm(5, 30)) // %K线均线周期 return &strat.TradeStrat{ WarmupNum: lookback + kSmoothing + maLookback + 10, // 确保有足够的历史数据 EachMaxLong: 1, // 每个品种最多1个多单 EachMaxShort: 1, // 每个品种最多1个空单 TimeFrames: "8h", OnBar: func(s *strat.StratJob) { e := s.Env // 计算随机振荡器 KDJ // KDJ返回[K, D, RSV],其中K就是我们需要的%K线 stochK, _, _ := ta.KDJ(e.High, e.Low, e.Close, lookback, kSmoothing, 3) // 计算%K线的移动平均线 maStochK := ta.SMA(stochK, maLookback) // 检测交叉信号 // Cross返回: 1=上穿, -1=下穿, 0=重合或未知 crossSignal := stochK.Cross(maStochK) // 根据交叉信号生成交易决策 if crossSignal == 1 { // %K线上穿其均线,买入做多 s.OpenOrder(&strat.EnterReq{ Tag: "long_cross", Short: false, }) // 同时平掉空单(如果有) s.CloseOrders(&strat.ExitReq{ Tag: "close_short", Dirt: core.OdDirtShort, }) } else if crossSignal == -1 { // %K线下穿其均线,卖出做空 s.OpenOrder(&strat.EnterReq{ Tag: "short_cross", Short: true, }) // 同时平掉多单(如果有) s.CloseOrders(&strat.ExitReq{ Tag: "close_long", Dirt: core.OdDirtLong, }) } }, } }