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

269
llmjob/2984.go Normal file
View File

@@ -0,0 +1,269 @@
package llmjob
import (
"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"
"math"
)
// ZeroLagEMA 计算零滞后指数移动平均线
func ZeroLagEMA(source *ta.Series, length int) *ta.Series {
res := source.To("_zlema", length)
if res.Cached() {
return res
}
if source.Len() < length {
return res.Append(math.NaN())
}
ema1 := ta.EMA(source, length)
ema2 := ta.EMA(ema1, length)
c1 := ema1.Get(0) - ema2.Get(0)
zlema := ema1.Get(0) + c1
return res.Append(zlema)
}
// ZlemaState 存储每个品种的策略状态
type ZlemaState struct {
goLong bool
sectionLongs int
sectionShorts int
sectionLongConditions int
sectionShortConditions int
totalLongs float64
totalShorts float64
averageLongs float64
averageShorts float64
lastHigh float64
lastLow float64
inLong bool
inShort bool
}
func J2984(pol *config.RunPolicyConfig) *strat.TradeStrat {
// 定义可调超参数
fastPeriod := pol.DefInt("fastPeriod", 10, core.PNorm(3, 20))
maRate := pol.Def("maRate", 2.4, core.PNorm(1.5, 5))
takeProfitRate := pol.Def("takeProfitRate", 3.5, core.PNorm(1, 10))
trailingStopRate := pol.Def("trailingStopRate", 3.5, core.PNorm(1, 8))
trailingActivationRate := pol.Def("trailingActivationRate", 16, core.PNorm(5, 25))
stopLossPercent := pol.Def("stopLossPercent", 7.5, core.PNorm(1, 15))
// 金字塔加仓参数
pyramidingLess := pol.DefInt("pyramidingLess", 1, core.PNorm(0, 5))
pyramidingEqual := pol.DefInt("pyramidingEqual", 0, core.PNorm(0, 5))
pyramidingGreater := pol.DefInt("pyramidingGreater", 1000000, core.PNorm(100, 1000000))
// 交易方向控制参数
longsOnly := pol.Def("longsOnly", 0, core.PUniform(0, 1)) > 0.5
shortsOnly := pol.Def("shortsOnly", 0, core.PUniform(0, 1)) > 0.5
flipOpens := pol.Def("flipOpens", 0, core.PUniform(0, 1)) > 0.5
// 计算慢线周期
slowPeriod := int(float64(fastPeriod) * maRate)
return &strat.TradeStrat{
WarmupNum: slowPeriod * 2, // 确保有足够的数据计算指标
HedgeOff: true, // 单向持仓模式
EachMaxLong: 1, // 最多开1单多仓
EachMaxShort: 1, // 最多开1单空仓
DrawDownExit: false, // 不使用回撤止盈
RunTimeFrames: []string{"8h"},
StopLoss: 0.075,
OnStartUp: func(s *strat.StratJob) {
// 初始化策略状态
s.More = &ZlemaState{
goLong: true,
sectionLongs: 0,
sectionShorts: 0,
sectionLongConditions: 0,
sectionShortConditions: 0,
totalLongs: 0,
totalShorts: 0,
averageLongs: 0,
averageShorts: 0,
lastHigh: 0,
lastLow: 0,
inLong: false,
inShort: false,
}
},
OnBar: func(s *strat.StratJob) {
e := s.Env
state, _ := s.More.(*ZlemaState)
// 计算Zero-Lag EMA
zlemaFast := ZeroLagEMA(e.Close, fastPeriod)
zlemaSlow := ZeroLagEMA(e.Close, slowPeriod)
// 获取当前值
fastVal := zlemaFast.Get(0)
slowVal := zlemaSlow.Get(0)
fastVal1 := zlemaFast.Get(1)
slowVal1 := zlemaSlow.Get(1)
closePrice := e.Close.Get(0)
highPrice := e.High.Get(0)
lowPrice := e.Low.Get(0)
// 检查数据有效性
if math.IsNaN(fastVal) || math.IsNaN(slowVal) || math.IsNaN(closePrice) {
return
}
// 生成基础交易信号
longSignal := fastVal > slowVal && fastVal1 <= slowVal1 // 快线上穿慢线
shortSignal := fastVal < slowVal && fastVal1 >= slowVal1 // 快线下穿慢线
// 应用交易方向翻转功能
if flipOpens {
longSignal, shortSignal = shortSignal, longSignal
}
// 应用仅做多/仅做空选项
if longsOnly {
shortSignal = false
}
if shortsOnly {
longSignal = false
}
// 更新连续信号计数
if longSignal {
state.sectionLongs++
state.sectionShorts = 0
} else if shortSignal {
state.sectionShorts++
state.sectionLongs = 0
}
// 应用金字塔式加仓条件
longCondition := longSignal && (state.sectionLongs <= pyramidingLess || state.sectionLongs >= pyramidingGreater || state.sectionLongs == pyramidingEqual)
shortCondition := shortSignal && (state.sectionShorts <= pyramidingLess || state.sectionShorts >= pyramidingGreater || state.sectionShorts == pyramidingEqual)
// 更新开仓价格和数量
if longCondition {
state.totalLongs += closePrice
state.sectionLongConditions++
state.averageLongs = state.totalLongs / float64(state.sectionLongConditions)
state.inLong = true
state.inShort = false
} else if shortCondition {
state.totalShorts += closePrice
state.sectionShortConditions++
state.averageShorts = state.totalShorts / float64(state.sectionShortConditions)
state.inShort = true
state.inLong = false
}
// 更新最高价/最低价追踪
if state.inLong {
if state.lastHigh == 0 || highPrice > state.lastHigh {
state.lastHigh = highPrice
}
} else if state.inShort {
if state.lastLow == 0 || lowPrice < state.lastLow {
state.lastLow = lowPrice
}
}
// 执行交易
if longCondition && len(s.LongOrders) == 0 {
// 设置止损止盈 - 基于平均开仓价计算
stopLossVal := state.averageLongs * (1 - stopLossPercent/100)
takeProfitVal := state.averageLongs * (1 + takeProfitRate/100)
s.OpenOrder(&strat.EnterReq{
Tag: "long",
Short: false,
OrderType: core.OrderTypeMarket,
StopLossVal: stopLossVal,
TakeProfitVal: takeProfitVal,
StopLossTag: "stop_loss",
TakeProfitTag: "take_profit",
})
} else if shortCondition && len(s.ShortOrders) == 0 {
// 设置止损止盈 - 基于平均开仓价计算
stopLossVal := state.averageShorts * (1 + stopLossPercent/100)
takeProfitVal := state.averageShorts * (1 - takeProfitRate/100)
s.OpenOrder(&strat.EnterReq{
Tag: "short",
Short: true,
OrderType: core.OrderTypeMarket,
StopLossVal: stopLossVal,
TakeProfitVal: takeProfitVal,
StopLossTag: "stop_loss",
TakeProfitTag: "take_profit",
})
}
// 检查平仓条件
if state.inLong && shortSignal {
s.CloseOrders(&strat.ExitReq{
Tag: "trend_reverse",
Dirt: core.OdDirtLong,
})
} else if state.inShort && longSignal {
s.CloseOrders(&strat.ExitReq{
Tag: "trend_reverse",
Dirt: core.OdDirtShort,
})
}
},
OnCheckExit: func(s *strat.StratJob, od *ormo.InOutOrder) *strat.ExitReq {
e := s.Env
state, _ := s.More.(*ZlemaState)
closePrice := e.Close.Get(0)
if od.Short {
// 做空订单检查
if state.inShort {
// 检查追踪止损条件 - 包含激活条件判断
if state.lastLow > 0 &&
state.lastLow <= state.averageShorts*(1-trailingActivationRate/100) && // 激活条件
closePrice >= state.lastLow*(1+trailingStopRate/100) { // 追踪止损条件
return &strat.ExitReq{Tag: "trailing_stop"}
}
}
} else {
// 做多订单检查
if state.inLong {
// 检查追踪止损条件 - 包含激活条件判断
if state.lastHigh > 0 &&
state.lastHigh >= state.averageLongs*(1+trailingActivationRate/100) && // 激活条件
closePrice <= state.lastHigh*(1-trailingStopRate/100) { // 追踪止损条件
return &strat.ExitReq{Tag: "trailing_stop"}
}
}
}
return nil
},
OnOrderChange: func(s *strat.StratJob, od *ormo.InOutOrder, chgType int) {
state, _ := s.More.(*ZlemaState)
// 订单状态变化时更新状态
if chgType == strat.OdChgExitFill {
if od.Short {
// 做空订单已平仓
state.inShort = false
state.averageShorts = 0
state.totalShorts = 0
state.sectionShorts = 0
state.sectionShortConditions = 0
state.lastLow = 0
} else {
// 做多订单已平仓
state.inLong = false
state.averageLongs = 0
state.totalLongs = 0
state.sectionLongs = 0
state.sectionLongConditions = 0
state.lastHigh = 0
}
}
},
}
}