This commit is contained in:
2026-08-24 20:53:21 +08:00
commit 6e78bba16a
287 changed files with 32443 additions and 0 deletions

131
llmjob/7046.go Normal file
View File

@@ -0,0 +1,131 @@
package llmjob
import (
"math"
"github.com/banbox/banbot/config"
"github.com/banbox/banbot/core"
"github.com/banbox/banbot/orm/ormo"
"github.com/banbox/banbot/strat"
ta "github.com/banbox/banta"
)
func J7046(pol *config.RunPolicyConfig) *strat.TradeStrat {
// 定义可调超参数
smaPeriod := pol.DefInt("smaPeriod", 22, core.PNorm(10, 50))
mult := pol.Def("mult", 1.0, core.PNorm(0.8, 3.0))
trailingLossPct := pol.Def("trailingLossPct", 0.075, core.PNorm(0.03, 0.15))
trailingPointsPct := pol.Def("trailingPointsPct", 0.05, core.PNorm(0.01, 0.10))
trailingOffsetPct := pol.Def("trailingOffsetPct", 0.005, core.PNorm(0.001, 0.02))
return &strat.TradeStrat{
Name: "Bollinger Band Breakout",
WarmupNum: smaPeriod + 10, // 预热K线数量
HedgeOff: true, // 单向持仓模式
EachMaxLong: 1, // 最多1个多单
EachMaxShort: 1, // 最多1个空单
TimeFrames: "8h",
OnBar: func(s *strat.StratJob) {
e := s.Env
closePrice := e.Close.Get(0)
// 检查数据有效性
if math.IsNaN(closePrice) {
return
}
// 计算布林带指标
upper, _, lower := ta.BBANDS(e.Close, smaPeriod, mult, mult)
// 检测突破信号
longSignal := e.Close.Cross(upper) // 上穿上轨,返回1表示上穿
shortSignal := e.Close.Cross(lower) // 下穿下轨,返回-1表示下穿
// 多头入场逻辑
if longSignal == 1 && len(s.LongOrders) == 0 {
s.OpenOrder(&strat.EnterReq{
Tag: "long",
Short: false,
OrderType: core.OrderTypeMarket,
})
}
// 空头入场逻辑
if shortSignal == -1 && len(s.ShortOrders) == 0 {
s.OpenOrder(&strat.EnterReq{
Tag: "short",
Short: true,
OrderType: core.OrderTypeMarket,
})
}
// 更新追踪止损
updateTrailingStop(s, closePrice, trailingLossPct, trailingPointsPct, trailingOffsetPct)
},
}
}
// 更新追踪止损的辅助函数
func updateTrailingStop(s *strat.StratJob, closePrice, lossPct, pointsPct, offsetPct float64) {
// 处理多头仓位的追踪止损
for _, order := range s.LongOrders {
if order.Status >= 2 { // 已入场
entryPrice := order.Enter.Average
maxLossPrice := entryPrice * (1 - lossPct) // 最大损失价格
activationPrice := entryPrice * (1 + pointsPct) // 激活追踪的价格
// 获取当前止损信息
currentStop := order.GetStopLoss()
var newStopPrice float64
// 判断是否已激活追踪止损
if closePrice >= activationPrice {
// 已激活,使用偏移量计算止损
newStopPrice = closePrice * (1 - offsetPct)
} else {
// 未激活,使用最大损失作为止损
newStopPrice = maxLossPrice
}
// 只有当新止损价格更优(更高)时才更新
if currentStop == nil || newStopPrice > currentStop.Price {
order.SetStopLoss(&ormo.ExitTrigger{
Price: newStopPrice,
Tag: "trailing_stop",
})
}
}
}
// 处理空头仓位的追踪止损
for _, order := range s.ShortOrders {
if order.Status >= 2 { // 已入场
entryPrice := order.Enter.Average
maxLossPrice := entryPrice * (1 + lossPct) // 最大损失价格
activationPrice := entryPrice * (1 - pointsPct) // 激活追踪的价格
// 获取当前止损信息
currentStop := order.GetStopLoss()
var newStopPrice float64
// 判断是否已激活追踪止损
if closePrice <= activationPrice {
// 已激活,使用偏移量计算止损
newStopPrice = closePrice * (1 + offsetPct)
} else {
// 未激活,使用最大损失作为止损
newStopPrice = maxLossPrice
}
// 只有当新止损价格更优(更低)时才更新
if currentStop == nil || newStopPrice < currentStop.Price {
order.SetStopLoss(&ormo.ExitTrigger{
Price: newStopPrice,
Tag: "trailing_stop",
})
}
}
}
}