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

128 lines
3.4 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 修复后的banbot完整策略代码
package llmjob
import (
"math"
"github.com/banbox/banbot/config"
"github.com/banbox/banbot/core"
"github.com/banbox/banbot/strat"
)
type DDLState struct {
lastbull float64 // 最后一个涨停价(连续上涨时的最高点)
lastbear float64 // 最后一个跌停价(连续下跌时的最低点)
lot float64 // 计算后的开仓数量
}
func J3137(pol *config.RunPolicyConfig) *strat.TradeStrat {
// 定义可调超参数
signalshort := pol.Def("signalshort", 5.1, core.PNorm(1.0, 10.0))
signallong := pol.Def("signallong", -5.1, core.PNorm(-10.0, -1.0))
capital := pol.Def("capital", 145.0, core.PNorm(10.0, 200.0))
needlong := pol.Def("needlong", 1.0, core.PNorm(0.0, 1.0))
needshort := pol.Def("needshort", 1.0, core.PNorm(0.0, 1.0))
return &strat.TradeStrat{
WarmupNum: 2, // 至少需要2个K线数据才能计算bull和bear
HedgeOff: false, // 允许双向持仓
RunTimeFrames: []string{"15m"},
OnStartUp: func(s *strat.StratJob) {
// 初始化每个品种的状态
s.More = &DDLState{
lastbull: math.NaN(),
lastbear: math.NaN(),
lot: 0.0,
}
},
OnBar: func(s *strat.StratJob) {
e := s.Env
state, _ := s.More.(*DDLState)
// 获取当前和前一个K线的价格
closePrice := e.Close.Get(0)
prevClose := e.Close.Get(1)
openPrice := e.Open.Get(0)
// 计算capital比例,避免重复计算
capitalRate := capital / 100
// 如果数据不足,返回
if math.IsNaN(closePrice) || math.IsNaN(prevClose) {
return
}
// 计算价格波动方向
bull := closePrice > prevClose
bear := closePrice < prevClose
// 更新最后一个涨停价和跌停价
if bull {
state.lastbull = closePrice
}
if bear {
state.lastbear = closePrice
}
// 如果还没有初始化lastbull和lastbear,返回
if math.IsNaN(state.lastbull) || math.IsNaN(state.lastbear) {
return
}
// 计算价格变化比例
ddl := ((closePrice / state.lastbull) - 1) * 100
dds := ((closePrice / state.lastbear) - 1) * 100
// 生成交易信号
up := ddl < signallong
dn := dds > signalshort
// 计算开仓数量(如果没有持仓)
if s.OrderNum == 0 {
// 修复:使用策略方法获取权益计算仓位
stakeAmount := s.Strat.GetStakeAmount(s)
state.lot = stakeAmount / closePrice * capitalRate
}
// truetime条件,与原始策略保持一致
truetime := true
// 执行交易
if up && needlong > 0.5 && truetime {
// 修复:使用计算好的lot值作为开仓数量
s.OpenOrder(&strat.EnterReq{
Tag: "Long",
Short: false,
Amount: state.lot,
})
}
if dn && needshort > 0.5 && truetime {
// 修复:使用计算好的lot值作为开仓数量
s.OpenOrder(&strat.EnterReq{
Tag: "Short",
Short: true,
Amount: state.lot,
})
}
// 平仓条件:开多仓后价格上涨就平多仓,开空仓后价格下跌就平空仓
if len(s.LongOrders) > 0 && closePrice > openPrice {
// 修复:使用CloseOrders进行平仓
s.CloseOrders(&strat.ExitReq{
Tag: "CloseLong",
Dirt: core.OdDirtLong,
})
}
if len(s.ShortOrders) > 0 && closePrice < openPrice {
// 修复:使用CloseOrders进行平仓
s.CloseOrders(&strat.ExitReq{
Tag: "CloseShort",
Dirt: core.OdDirtShort,
})
}
},
}
}