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

114 lines
3.5 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.

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