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 J5763(pol *config.RunPolicyConfig) *strat.TradeStrat { keh := pol.DefInt("keh", 33, core.PNorm(5, 30)) tenkanPeriod := pol.DefInt("tenkanPeriod", 23, core.PNorm(5, 20)) kijunTenkanRatio := pol.Def("kijunTenkanRatio", 3.3, core.PNorm(2.0, 4.0)) senkouBPeriod := pol.DefInt("senkouBPeriod", 75, core.PNorm(30, 100)) displacement := pol.DefInt("displacement", 28, core.PNorm(15, 40)) // 计算基准线周期 kijunPeriod := int(float64(tenkanPeriod) * kijunTenkanRatio) // 计算预热期数量,考虑最长的周期和位移 warmupNum := senkouBPeriod + displacement return &strat.TradeStrat{ WarmupNum: warmupNum, HedgeOff: true, // 单向持仓模式 RunTimeFrames: []string{"8h"}, OnBar: func(s *strat.StratJob) { e := s.Env // 计算Hull移动平均线 // 当前周期HMA计算 halfKeh := int(math.Round(float64(keh) / 2)) n2ma := ta.WMA(e.Close, halfKeh).Mul(2) nma := ta.WMA(e.Close, keh) diff := n2ma.Sub(nma) sqn := int(math.Round(math.Sqrt(float64(keh)))) n1 := ta.WMA(diff, sqn) // 前一周期HMA计算 closeBack1 := e.Close.Back(1) n2ma1 := ta.WMA(closeBack1, halfKeh).Mul(2) nma1 := ta.WMA(closeBack1, keh) diff1 := n2ma1.Sub(nma1) sqn1 := int(math.Round(math.Sqrt(float64(keh)))) n2 := ta.WMA(diff1, sqn1) // 计算一目均衡图组件 // 转换线(Tenkan-sen) tenkanSenHigh := ta.Highest(e.High, tenkanPeriod) tenkanSenLow := ta.Lowest(e.Low, tenkanPeriod) tenkanSen := tenkanSenHigh.Add(tenkanSenLow).Div(2) // 基准线(Kijun-sen) kijunSenHigh := ta.Highest(e.High, kijunPeriod) kijunSenLow := ta.Lowest(e.Low, kijunPeriod) kijunSen := kijunSenHigh.Add(kijunSenLow).Div(2) // 先行带A(Senkou Span A) senkouSpanA := tenkanSen.Add(kijunSen).Div(2) // 先行带B(Senkou Span B) senkouSpanBHigh := ta.Highest(e.High, senkouBPeriod) senkouSpanBLow := ta.Lowest(e.Low, senkouBPeriod) senkouSpanB := senkouSpanBHigh.Add(senkouSpanBLow).Div(2) // 先行带高点和低点(位移后) senkouSpanABack := senkouSpanA.Back(displacement - 1) senkouSpanBBack := senkouSpanB.Back(displacement - 1) senkouSpanH := senkouSpanABack.Max(senkouSpanBBack) senkouSpanL := senkouSpanABack.Min(senkouSpanBBack) // 滞后线(Chikou Span) chikouSpan := e.Close.Back(displacement - 1) // 获取当前值 n1Val := n1.Get(0) n2Val := n2.Get(0) closeVal := e.Close.Get(0) tenkanSenVal := tenkanSen.Get(0) kijunSenVal := kijunSen.Get(0) senkouSpanHVal := senkouSpanH.Get(0) senkouSpanLVal := senkouSpanL.Get(0) chikouSpanVal := chikouSpan.Get(0) // 多头入场条件 longCondition := n1Val > n2Val && closeVal > n2Val && closeVal > chikouSpanVal && closeVal > senkouSpanHVal && (tenkanSenVal >= kijunSenVal || closeVal > kijunSenVal) // 空头入场条件 shortCondition := n1Val < n2Val && closeVal < n2Val && closeVal < chikouSpanVal && closeVal < senkouSpanLVal && (tenkanSenVal <= kijunSenVal || closeVal < kijunSenVal) // 多头平仓条件 closeLongCondition := n1Val < n2Val && (closeVal < n2Val || tenkanSenVal < kijunSenVal || closeVal < tenkanSenVal || closeVal < kijunSenVal || closeVal < senkouSpanHVal || closeVal < chikouSpanVal) // 空头平仓条件 closeShortCondition := n1Val > n2Val && (closeVal > n2Val || tenkanSenVal > kijunSenVal || closeVal > tenkanSenVal || closeVal > kijunSenVal || closeVal > senkouSpanLVal || closeVal > chikouSpanVal) // 执行交易逻辑 if longCondition && len(s.LongOrders) == 0 { s.OpenOrder(&strat.EnterReq{ Tag: "Long", }) } if shortCondition && len(s.ShortOrders) == 0 { s.OpenOrder(&strat.EnterReq{ Tag: "Short", Short: true, }) } if closeLongCondition && len(s.LongOrders) > 0 { s.CloseOrders(&strat.ExitReq{ Tag: "CloseLong", Dirt: core.OdDirtLong, }) } if closeShortCondition && len(s.ShortOrders) > 0 { s.CloseOrders(&strat.ExitReq{ Tag: "CloseShort", Dirt: core.OdDirtShort, }) } }, } }