init
This commit is contained in:
215
llmjob/5609.go
Normal file
215
llmjob/5609.go
Normal file
@@ -0,0 +1,215 @@
|
||||
package llmjob
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
"math"
|
||||
)
|
||||
|
||||
// State5609 存储每个品种的策略状态
|
||||
type State5609 struct {
|
||||
longEntryPrice float64
|
||||
shortEntryPrice float64
|
||||
longEntryBar int64
|
||||
shortEntryBar int64
|
||||
}
|
||||
|
||||
func J5609(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
// 定义可调超参数
|
||||
atrPeriod := pol.DefInt("atrPeriod", 14, core.PNorm(7, 30))
|
||||
bbLength := pol.DefInt("bbLength", 18, core.PNorm(10, 50))
|
||||
bbStdDev := pol.Def("bbStdDev", 1.9, core.PNorm(1, 3))
|
||||
rsiPeriod := pol.DefInt("rsiPeriod", 12, core.PNorm(7, 21))
|
||||
atrMultiplier := pol.Def("atrMultiplier", 1.6, core.PNorm(0.5, 3))
|
||||
vwapLength := pol.DefInt("vwapLength", 20, core.PNorm(10, 40))
|
||||
targetMultiplier := pol.Def("targetMultiplier", 2.4, core.PNorm(1, 4))
|
||||
maxHoldingBars := pol.DefInt("maxHoldingBars", 3, core.PNorm(2, 10))
|
||||
|
||||
// 计算预热期,确保所有指标都有足够的数据计算
|
||||
warmupNum := bbLength
|
||||
if atrPeriod > warmupNum {
|
||||
warmupNum = atrPeriod
|
||||
}
|
||||
if rsiPeriod > warmupNum {
|
||||
warmupNum = rsiPeriod
|
||||
}
|
||||
if vwapLength > warmupNum {
|
||||
warmupNum = vwapLength
|
||||
}
|
||||
// 额外增加20个K线确保稳定性
|
||||
warmupNum += 20
|
||||
|
||||
return &strat.TradeStrat{
|
||||
Name: "OptionsStrategy",
|
||||
WarmupNum: warmupNum,
|
||||
HedgeOff: true, // 单向持仓模式
|
||||
EachMaxLong: 1, // 最多一个多头订单
|
||||
EachMaxShort: 1, // 最多一个空头订单
|
||||
RunTimeFrames: []string{"4h"},
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
// 初始化每个品种的策略状态
|
||||
s.More = &State5609{
|
||||
longEntryPrice: 0,
|
||||
shortEntryPrice: 0,
|
||||
longEntryBar: 0,
|
||||
shortEntryBar: 0,
|
||||
}
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
state := s.More.(*State5609)
|
||||
|
||||
// 计算技术指标
|
||||
atrValue := ta.ATR(e.High, e.Low, e.Close, atrPeriod)
|
||||
smaValue := ta.SMA(e.Close, bbLength)
|
||||
stdDev := ta.StdDev(e.Close, bbLength)
|
||||
upperBB := smaValue.Add(stdDev.Mul(bbStdDev))
|
||||
lowerBB := smaValue.Sub(stdDev.Mul(bbStdDev))
|
||||
rsiValue := ta.RSI(e.Close, rsiPeriod)
|
||||
// 修复错误1:使用正确的VWAP计算方法
|
||||
vwap := ta.Sum(e.Close.Mul(e.Volume), vwapLength).Div(ta.Sum(e.Volume, vwapLength))
|
||||
volSMA := ta.SMA(e.Volume, 10)
|
||||
atrSMA := ta.SMA(atrValue, 20)
|
||||
|
||||
// 获取当前值
|
||||
closePrice := e.Close.Get(0)
|
||||
atrVal := atrValue.Get(0)
|
||||
upperBBVal := upperBB.Get(0)
|
||||
lowerBBVal := lowerBB.Get(0)
|
||||
rsiVal := rsiValue.Get(0)
|
||||
vwapVal := vwap.Get(0)
|
||||
volumeVal := e.Volume.Get(0)
|
||||
volSMAVal := volSMA.Get(0)
|
||||
atrSMAVal := atrSMA.Get(0)
|
||||
|
||||
// 检查数据有效性
|
||||
if math.IsNaN(closePrice) || math.IsNaN(atrVal) || math.IsNaN(upperBBVal) ||
|
||||
math.IsNaN(lowerBBVal) || math.IsNaN(rsiVal) || math.IsNaN(vwapVal) ||
|
||||
math.IsNaN(volumeVal) || math.IsNaN(volSMAVal) || math.IsNaN(atrSMAVal) {
|
||||
return
|
||||
}
|
||||
|
||||
// 计算条件
|
||||
volSpike := volumeVal > volSMAVal*1.5
|
||||
atrFilter := atrVal > atrSMAVal*0.5
|
||||
|
||||
// 生成交易信号
|
||||
longCE := e.Close.Cross(upperBB) == 1 && rsiVal > 60 && volSpike && closePrice > vwapVal && atrFilter
|
||||
longPE := e.Close.Cross(lowerBB) == -1 && rsiVal < 40 && volSpike && closePrice < vwapVal && atrFilter
|
||||
|
||||
// 计算止损止盈
|
||||
longStopLoss := 0.0
|
||||
longTarget := 0.0
|
||||
shortStopLoss := 0.0
|
||||
shortTarget := 0.0
|
||||
|
||||
// 修复错误5:使用实际成交的平均价格作为止损止盈的计算基准
|
||||
if len(s.LongOrders) > 0 {
|
||||
// 获取多头持仓的平均价格
|
||||
longAvgPrice := state.longEntryPrice
|
||||
if longAvgPrice > 0 {
|
||||
longStopLoss = longAvgPrice - atrMultiplier*atrVal
|
||||
longTarget = longAvgPrice + targetMultiplier*atrVal
|
||||
}
|
||||
}
|
||||
|
||||
if len(s.ShortOrders) > 0 {
|
||||
// 获取空头持仓的平均价格
|
||||
shortAvgPrice := state.shortEntryPrice
|
||||
if shortAvgPrice > 0 {
|
||||
shortStopLoss = shortAvgPrice + atrMultiplier*atrVal
|
||||
shortTarget = shortAvgPrice - targetMultiplier*atrVal
|
||||
}
|
||||
}
|
||||
|
||||
// 执行交易
|
||||
if longCE && len(s.LongOrders) == 0 {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: "CE Entry",
|
||||
OrderType: core.OrderTypeMarket,
|
||||
StopLossVal: atrMultiplier * atrVal,
|
||||
TakeProfitVal: targetMultiplier * atrVal,
|
||||
})
|
||||
// 记录入场价格和K线时间
|
||||
state.longEntryPrice = closePrice
|
||||
state.longEntryBar = e.TimeStop
|
||||
}
|
||||
|
||||
if longPE && len(s.ShortOrders) == 0 {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: "PE Entry",
|
||||
Short: true,
|
||||
OrderType: core.OrderTypeMarket,
|
||||
StopLossVal: atrMultiplier * atrVal,
|
||||
TakeProfitVal: targetMultiplier * atrVal,
|
||||
})
|
||||
// 记录入场价格和K线时间
|
||||
state.shortEntryPrice = closePrice
|
||||
state.shortEntryBar = e.TimeStop
|
||||
}
|
||||
|
||||
// 出场管理
|
||||
if len(s.LongOrders) > 0 {
|
||||
// 计算持仓时间(K线数)
|
||||
holdBars := e.BarCount(state.longEntryBar)
|
||||
|
||||
// 止盈出场
|
||||
if closePrice >= longTarget {
|
||||
s.CloseOrders(&strat.ExitReq{
|
||||
Tag: "CE Target Hit",
|
||||
Dirt: core.OdDirtLong,
|
||||
Force: true,
|
||||
})
|
||||
}
|
||||
// 止损出场
|
||||
if closePrice <= longStopLoss {
|
||||
s.CloseOrders(&strat.ExitReq{
|
||||
Tag: "CE Stop Loss Hit",
|
||||
Dirt: core.OdDirtLong,
|
||||
Force: true,
|
||||
})
|
||||
}
|
||||
// 时间出场
|
||||
if int64(holdBars) >= int64(maxHoldingBars) {
|
||||
s.CloseOrders(&strat.ExitReq{
|
||||
Tag: "CE Timed Exit",
|
||||
Dirt: core.OdDirtLong,
|
||||
Force: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if len(s.ShortOrders) > 0 {
|
||||
// 计算持仓时间(K线数)
|
||||
holdBars := e.BarCount(state.shortEntryBar)
|
||||
|
||||
// 止盈出场
|
||||
if closePrice <= shortTarget {
|
||||
s.CloseOrders(&strat.ExitReq{
|
||||
Tag: "PE Target Hit",
|
||||
Dirt: core.OdDirtShort,
|
||||
Force: true,
|
||||
})
|
||||
}
|
||||
// 止损出场
|
||||
if closePrice >= shortStopLoss {
|
||||
s.CloseOrders(&strat.ExitReq{
|
||||
Tag: "PE Stop Loss Hit",
|
||||
Dirt: core.OdDirtShort,
|
||||
Force: true,
|
||||
})
|
||||
}
|
||||
// 时间出场
|
||||
if int64(holdBars) >= int64(maxHoldingBars) {
|
||||
s.CloseOrders(&strat.ExitReq{
|
||||
Tag: "PE Timed Exit",
|
||||
Dirt: core.OdDirtShort,
|
||||
Force: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user