package llmjob import ( "github.com/banbox/banbot/config" "github.com/banbox/banbot/core" "github.com/banbox/banbot/orm/ormo" "github.com/banbox/banbot/strat" "math" "time" ) type WeekendData struct { FridayClose float64 HasLong bool TotCost float64 TotAmt float64 } func J2439(pol *config.RunPolicyConfig) *strat.TradeStrat { entryThreshold := pol.Def("entryThreshold", 0.02, core.PNorm(0.01, 0.1)) profitTakingPercentThreshold := pol.Def("profitTakingPercentThreshold", 0.06, core.PNorm(0.01, 0.08)) return &strat.TradeStrat{ WarmupNum: 7, // 需要最多7天的数据来获取周五收盘价 HedgeOff: true, // 单向持仓模式 RunTimeFrames: []string{"5m"}, OnStartUp: func(s *strat.StratJob) { s.More = &WeekendData{FridayClose: math.NaN()} }, OnBar: func(s *strat.StratJob) { e := s.Env data, _ := s.More.(*WeekendData) currentTime := time.Unix(e.TimeStop/1000, 0) weekday := currentTime.Weekday() // 计算距离周五的天数 var daysSinceFriday int switch weekday { case time.Saturday: daysSinceFriday = 1 case time.Sunday: daysSinceFriday = 0 case time.Monday: daysSinceFriday = 6 case time.Tuesday: daysSinceFriday = 5 case time.Wednesday: daysSinceFriday = 4 case time.Thursday: daysSinceFriday = 3 case time.Friday: daysSinceFriday = 2 } // 获取周五收盘价 - 使用日线数据 if e.Close.Len() > daysSinceFriday { data.FridayClose = e.Close.Get(daysSinceFriday) } // 如果没有有效的周五收盘价,不执行交易逻辑 if math.IsNaN(data.FridayClose) { return } // 检查止盈条件 if s.EnteredNum > 0 { totalProfitRate := 0.0 for _, od := range s.LongOrders { if od.Status >= ormo.InOutStatusPartEnter { totalProfitRate += od.ProfitRate } } for _, od := range s.ShortOrders { if od.Status >= ormo.InOutStatusPartEnter { totalProfitRate += od.ProfitRate } } if totalProfitRate > profitTakingPercentThreshold { s.CloseOrders(&strat.ExitReq{ Tag: "profit_take", Dirt: core.OdDirtBoth, }) return } } // 周末交易逻辑(周日和周一) if weekday == time.Sunday || weekday == time.Monday { currentPrice := e.Close.Get(0) if math.IsNaN(currentPrice) { return } upperThreshold := data.FridayClose * (1 + entryThreshold) lowerThreshold := data.FridayClose * (1 - entryThreshold) // 没有持仓时的入场逻辑 if s.OrderNum == 0 { if currentPrice > upperThreshold { s.OpenOrder(&strat.EnterReq{ Tag: "short_entry", Short: true, }) } else if currentPrice < lowerThreshold { s.OpenOrder(&strat.EnterReq{ Tag: "long_entry", }) } } else { // 已有持仓时的加仓逻辑 for _, od := range s.ShortOrders { if od.Status >= ormo.InOutStatusPartEnter && currentPrice > od.InitPrice*(1+entryThreshold) { s.OpenOrder(&strat.EnterReq{ Tag: "add_short", Short: true, }) break } } for _, od := range s.LongOrders { if od.Status >= ormo.InOutStatusPartEnter { s.OpenOrder(&strat.EnterReq{ Tag: "add_long", }) break } } } } // 周二平仓逻辑 if weekday == time.Tuesday { if s.OrderNum > 0 { s.CloseOrders(&strat.ExitReq{ Tag: "monday_close", Dirt: core.OdDirtBoth, }) } } }, } }