Files
banstagy/llmjob/2439.go
2026-08-24 20:53:21 +08:00

145 lines
3.5 KiB
Go

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,
})
}
}
},
}
}