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

113
llmjob/4225.go Normal file
View File

@@ -0,0 +1,113 @@
package llmjob
import (
"github.com/banbox/banbot/config"
"github.com/banbox/banbot/core"
"github.com/banbox/banbot/strat"
ta "github.com/banbox/banta"
)
// StrategyMore 存储每个品种的策略状态
type StrategyMore struct {
LastBarNum float64 // 上次交易的K线编号
}
// MultiEMACross 多重均线交叉与时间间隔整合策略
func J4225(pol *config.RunPolicyConfig) *strat.TradeStrat {
// 定义可调参数
emaBasePeriod := pol.DefInt("emaBasePeriod", 4, core.PNorm(3, 15))
emaMidRatio := pol.Def("emaMidRatio", 2.1, core.PNorm(1.5, 4))
emaSlowRatio := pol.Def("emaSlowRatio", 10, core.PNorm(5, 20))
timeInterval := pol.DefInt("timeInterval", 35, core.PNorm(10, 100))
atrMultiplier := pol.Def("atrMultiplier", 1.9, core.PNorm(0.5, 5))
// 计算EMA周期
emaMidPeriod := int(float64(emaBasePeriod) * emaMidRatio)
emaSlowPeriod := int(float64(emaBasePeriod) * emaSlowRatio)
// 确定预热K线数量,取最慢EMA周期的2倍
warmupNum := emaSlowPeriod * 2
return &strat.TradeStrat{
WarmupNum: warmupNum,
HedgeOff: true, // 单向持仓模式
RunTimeFrames: []string{"8h"},
OnStartUp: func(s *strat.StratJob) {
// 初始化每个品种的策略状态
s.More = &StrategyMore{
LastBarNum: -1, // 初始化为-1,表示尚未交易
}
},
OnBar: func(s *strat.StratJob) {
e := s.Env
m, _ := s.More.(*StrategyMore)
// 计算EMA指标
emaFast := ta.EMA(e.Close, emaBasePeriod)
emaMid := ta.EMA(e.Close, emaMidPeriod)
emaSlow := ta.EMA(e.Close, emaSlowPeriod)
// 计算ATR用于动态止盈止损
atr := ta.ATR(e.High, e.Low, e.Close, 14)
atrVal := atr.Get(0)
// 检查EMA交叉条件 - 修复重复计算问题
fastCrossSlow := emaFast.Cross(emaSlow)
midCrossSlow := emaMid.Cross(emaSlow)
fastCrossSlowUp := fastCrossSlow == 1 // 快线上穿慢线
midCrossSlowUp := midCrossSlow == 1 // 中线上穿慢线
fastCrossSlowDown := fastCrossSlow == -1 // 快线下穿慢线
midCrossSlowDown := midCrossSlow == -1 // 中线下穿慢线
// 生成交易信号
buyCondition := fastCrossSlowUp && midCrossSlowUp
sellCondition := fastCrossSlowDown && midCrossSlowDown
// 检查时间间隔是否满足要求
currentBarNum := e.BarCount(0)
barsSinceLastTrade := currentBarNum - m.LastBarNum
timeElapsedOk := m.LastBarNum == -1 || barsSinceLastTrade >= float64(timeInterval)
// 如果有交易信号且时间间隔满足要求
if (buyCondition || sellCondition) && timeElapsedOk {
// 先平掉所有现有仓位
if len(s.LongOrders) > 0 || len(s.ShortOrders) > 0 {
s.CloseOrders(&strat.ExitReq{
Tag: "close_all",
Dirt: core.OdDirtBoth,
Force: true,
})
}
// 计算止盈止损价格
stopLossDist := atrVal * atrMultiplier
takeProfitDist := stopLossDist * 1.67 // 保持5:3的盈亏比
// 根据信号方向开仓
if buyCondition {
s.OpenOrder(&strat.EnterReq{
Tag: "Buy",
Short: false,
OrderType: core.OrderTypeMarket,
StopLossVal: stopLossDist,
TakeProfitVal: takeProfitDist,
StopLossTag: "stop_loss",
TakeProfitTag: "take_profit",
})
m.LastBarNum = currentBarNum
} else if sellCondition {
s.OpenOrder(&strat.EnterReq{
Tag: "Sell",
Short: true,
OrderType: core.OrderTypeMarket,
StopLossVal: stopLossDist,
TakeProfitVal: takeProfitDist,
StopLossTag: "stop_loss",
TakeProfitTag: "take_profit",
})
m.LastBarNum = currentBarNum
}
}
},
}
}