init
This commit is contained in:
269
llmjob/2984.go
Normal file
269
llmjob/2984.go
Normal 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
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user