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

174
llmjob/2391.go Normal file
View File

@@ -0,0 +1,174 @@
package llmjob
import (
"github.com/banbox/banbot/config"
"github.com/banbox/banbot/core"
"github.com/banbox/banbot/strat"
ta "github.com/banbox/banta"
)
// Sta2391 用于保存每个品种的策略状态
type Sta2391 struct {
posReversal123 float64 // 123反转策略的信号值
posmStochCross float64 // 随机指标交叉策略的信号值
}
func J2391(pol *config.RunPolicyConfig) *strat.TradeStrat {
// 123反转策略参数
length := pol.DefInt("length", 40, core.PNorm(5, 30))
kSmoothing := pol.DefInt("kSmoothing", 1, core.PNorm(1, 5))
dLength := pol.DefInt("dLength", 3, core.PNorm(1, 5))
level := pol.Def("level", 30, core.PNorm(30, 70))
// 随机指标交叉策略参数
lengthSC := pol.DefInt("lengthSC", 20, core.PNorm(3, 21))
dLengthSC := pol.DefInt("dLengthSC", 3, core.PNorm(1, 5))
oversold := pol.Def("oversold", 10, core.PNorm(10, 30))
overbought := pol.Def("overbought", 90, core.PNorm(70, 90))
reverse := pol.Def("reverse", 0, core.PUniform(0, 1)) // 0表示不反转,1表示反转
// 计算预热数量,取两个策略中需要的历史数据最大值
warmupNum := length
if lengthSC > warmupNum {
warmupNum = lengthSC
}
if kSmoothing+dLength > warmupNum {
warmupNum = kSmoothing + dLength
}
if dLengthSC > warmupNum {
warmupNum = dLengthSC
}
// 额外需要2个历史K线判断价格反转
warmupNum += 2
return &strat.TradeStrat{
WarmupNum: warmupNum,
HedgeOff: true, // 单向持仓模式
TimeFrames: "8h",
OnStartUp: func(s *strat.StratJob) {
// 初始化策略状态
s.More = &Sta2391{
posReversal123: 0,
posmStochCross: 0,
}
},
OnBar: func(s *strat.StratJob) {
e := s.Env
state, _ := s.More.(*Sta2391)
// 获取价格数据
close0 := e.Close.Get(0) // 当前收盘价
close1 := e.Close.Get(1) // 前一个收盘价
close2 := e.Close.Get(2) // 前两个收盘价
// 1. 计算123反转策略信号
// 计算随机指标
kFast := ta.Stoch(e.High, e.Low, e.Close, length)
// 对K值进行平滑
vFast := ta.SMA(kFast, kSmoothing)
// 计算D值
vSlow := ta.SMA(vFast, dLength)
// 获取当前值
vFastVal := vFast.Get(0)
vSlowVal := vSlow.Get(0)
// 判断123反转策略信号
if close2 < close1 && close1 < close0 && vFastVal < vSlowVal && vFastVal > level {
// 买入信号:两天内收盘价从低点转为高点,且随机指标快速线在慢速线下方但高于阈值
state.posReversal123 = 1
} else if close2 > close1 && close1 > close0 && vFastVal > vSlowVal && vFastVal < level {
// 卖出信号:两天内收盘价从高点转为低点,且随机指标快速线在慢速线上方但低于阈值
state.posReversal123 = -1
}
// 否则保持之前的信号(不需要else,因为不改变state.posReversal123的值)
// 2. 计算随机指标交叉策略信号
// 计算随机指标
kFastSC := ta.Stoch(e.High, e.Low, e.Close, lengthSC)
// 计算D值
vSlowSC := ta.SMA(kFastSC, dLengthSC)
// 获取当前值
vFastSCVal := kFastSC.Get(0)
vSlowSCVal := vSlowSC.Get(0)
// 判断随机指标交叉策略信号
if vFastSCVal >= vSlowSCVal && vFastSCVal < oversold && vSlowSCVal < oversold {
// 买入信号:快速线在慢速线上方,且两者都处于超卖区域
state.posmStochCross = 1
} else if vFastSCVal < vSlowSCVal && vFastSCVal > overbought && vSlowSCVal > overbought {
// 卖出信号:快速线在慢速线下方,且两者都处于超买区域
state.posmStochCross = -1
}
// 否则保持之前的信号(不需要else,因为不改变state.posmStochCross的值)
// 3. 组合信号
var pos float64
if state.posReversal123 == 1 && state.posmStochCross == 1 {
// 两个策略都给出买入信号
pos = 1
} else if state.posReversal123 == -1 && state.posmStochCross == -1 {
// 两个策略都给出卖出信号
pos = -1
} else {
// 信号不一致,无交易信号
pos = 0
}
// 4. 处理信号反转
var possig float64
if reverse == 1 { // 明确检查reverse是否为1
if pos == 1 {
possig = -1 // 反转买入信号为卖出信号
} else if pos == -1 {
possig = 1 // 反转卖出信号为买入信号
} else {
possig = 0
}
} else {
possig = pos // 不反转信号
}
// 5. 执行交易
if possig == 1 {
// 买入信号
if len(s.LongOrders) == 0 {
s.OpenOrder(&strat.EnterReq{
Tag: "long",
})
}
// 如果有做空持仓,平仓
if len(s.ShortOrders) > 0 {
s.CloseOrders(&strat.ExitReq{
Tag: "close_short",
Dirt: core.OdDirtShort,
})
}
} else if possig == -1 {
// 卖出信号
if len(s.ShortOrders) == 0 {
s.OpenOrder(&strat.EnterReq{
Tag: "short",
Short: true,
})
}
// 如果有做多持仓,平仓
if len(s.LongOrders) > 0 {
s.CloseOrders(&strat.ExitReq{
Tag: "close_long",
Dirt: core.OdDirtLong,
})
}
} else if possig == 0 {
// 无信号,平仓所有持仓
if len(s.LongOrders) > 0 || len(s.ShortOrders) > 0 {
s.CloseOrders(&strat.ExitReq{
Tag: "close_all",
Dirt: core.OdDirtBoth,
})
}
}
},
}
}