package llmjob import ( "github.com/banbox/banbot/config" "github.com/banbox/banbot/core" "github.com/banbox/banbot/strat" ta "github.com/banbox/banta" ) func J6969(pol *config.RunPolicyConfig) *strat.TradeStrat { // 定义可调超参数 moveLimit := pol.Def("moveLimit", 69, core.PNorm(50, 90)) // 大幅移动阈值百分比 maLength := pol.DefInt("maLength", 150, core.PNorm(50, 300)) // 均线过滤周期 return &strat.TradeStrat{ WarmupNum: maLength + 3, // 预热数量:均线周期 + 3根K线用于形态判断 HedgeOff: true, // 修改为单向持仓模式,与原始Pine Script行为一致 TimeFrames: "3d", OnBar: func(s *strat.StratJob) { e := s.Env // 计算均线指标 ma := ta.SMA(e.Close, maLength) // 判断K线形态 // downBar: 当前K线是否为阴线 downBar := e.Open.Get(0) > e.Close.Get(0) downBar1 := e.Open.Get(1) > e.Close.Get(1) downBar2 := e.Open.Get(2) > e.Close.Get(2) // isThreeDown: 连续三根阴线 isThreeDown := downBar && downBar1 && downBar2 // isThreeUp: 连续三根阳线 isThreeUp := !downBar && !downBar1 && !downBar2 // 计算大幅移动指标 // isBigMoveDown: 当前K线实体占整个波段的百分比超过阈值 highLowRange0 := e.High.Get(0) - e.Low.Get(0) isBigMoveDown := ((e.Open.Get(0) - e.Close.Get(0)) / (0.001 + highLowRange0)) > moveLimit/100.0 // 复用 highLowRange0 变量,避免重复计算 isBigMoveUp := ((e.Close.Get(0) - e.Open.Get(0)) / (0.001 + highLowRange0)) > moveLimit/100.0 // 生成交易信号 // isLongBuy: 连续三阴且最后一根是大跌 isLongBuy := isThreeDown && isBigMoveDown // isLongExit: 收盘价突破前一根K线的最高价 isLongExit := e.Close.Get(0) > e.High.Get(1) // isShortBuy: 连续三阳且最后一根是大涨 isShortBuy := isThreeUp && isBigMoveUp // isShortExit: 收盘价跌破前一根K线的最低价 isShortExit := e.Close.Get(0) < e.Low.Get(1) // 执行交易逻辑 // 多头入场 if isLongBuy { s.OpenOrder(&strat.EnterReq{ Tag: "Entry Long", Short: false, }) } // 多头出场 if isLongExit { s.CloseOrders(&strat.ExitReq{ Tag: "Entry Long", Dirt: core.OdDirtLong, }) } // 空头入场(需要满足价格低于均线的过滤条件) if isShortBuy && e.Close.Get(0) < ma.Get(0) { s.OpenOrder(&strat.EnterReq{ Tag: "Entry Short", Short: true, }) } // 空头出场 if isShortExit { s.CloseOrders(&strat.ExitReq{ Tag: "Entry Short", Dirt: core.OdDirtShort, }) } }, } }