init
This commit is contained in:
160
llmjob/3939.go
Normal file
160
llmjob/3939.go
Normal file
@@ -0,0 +1,160 @@
|
||||
package llmjob
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
func J3939(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
// 定义可调超参数
|
||||
lwstPeriod := pol.DefInt("lwst_period", 10, core.PNorm(5, 25))
|
||||
lwstMultiplier := pol.Def("lwst_multiplier", 3.0, core.PNorm(1.5, 5.5))
|
||||
lwstLength := pol.DefInt("lwst_length", 20, core.PNorm(10, 40))
|
||||
trendLength := pol.DefInt("trend_length", 14, core.PNorm(7, 25))
|
||||
trendThreshold := pol.Def("trend_threshold", 0.5, core.PNorm(0.1, 2.0))
|
||||
wtChannelLength := pol.DefInt("wt_channel_length", 9, core.PNorm(5, 20))
|
||||
wtAverageLength := pol.DefInt("wt_average_length", 12, core.PNorm(6, 24))
|
||||
wtMaLength := pol.DefInt("wt_ma_length", 3, core.PNorm(2, 8))
|
||||
wtOverbought := pol.Def("wt_overbought", 53, core.PNorm(40, 70))
|
||||
wtOversold := pol.Def("wt_oversold", -53, core.PNorm(-70, -40)) // 修复:独立的超卖参数
|
||||
slPercent := pol.Def("sl_percent", 2.0, core.PNorm(0.5, 5.0))
|
||||
tpPercent := pol.Def("tp_percent", 4.0, core.PNorm(1.0, 10.0))
|
||||
|
||||
warmupNum := max(lwstPeriod*2, trendLength*2, wtChannelLength+wtAverageLength)
|
||||
|
||||
return &strat.TradeStrat{
|
||||
Name: "Multi-Indicator-Consensus",
|
||||
WarmupNum: warmupNum + 50,
|
||||
HedgeOff: true, // 单向持仓模式
|
||||
EachMaxLong: 1,
|
||||
EachMaxShort: 1,
|
||||
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
currentPrice := e.Close.Get(0)
|
||||
|
||||
// =================== Indicator 1: Liquidity Weighted Supertrend ===================
|
||||
// Volume-weighted component for dynamic sensitivity
|
||||
volSma := ta.SMA(e.Volume, lwstLength)
|
||||
volWeight := e.Volume.Div(volSma)
|
||||
|
||||
// ATR-based bands with volume weighting
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lwstPeriod)
|
||||
hl2 := ta.HL2(e.High, e.Low)
|
||||
_ = hl2.Add(atr.Mul(lwstMultiplier).Mul(volWeight)) // upperBand
|
||||
_ = hl2.Sub(atr.Mul(lwstMultiplier).Mul(volWeight)) // lowerBand
|
||||
|
||||
// Trend determination based on price action and previous trend
|
||||
// 修复:使用Series保存趋势状态
|
||||
lwstTrendSeries := e.Close.To("_lwst_trend", 0)
|
||||
var lwstTrend float64
|
||||
if e.Close.Len() > 1 {
|
||||
prevTrend := lwstTrendSeries.Get(1)
|
||||
if currentPrice > prevTrend {
|
||||
lwstTrend = 1
|
||||
} else if currentPrice < prevTrend {
|
||||
lwstTrend = -1
|
||||
} else {
|
||||
lwstTrend = prevTrend
|
||||
}
|
||||
} else {
|
||||
lwstTrend = 1.0
|
||||
}
|
||||
lwstTrendSeries.Set(lwstTrend)
|
||||
|
||||
// =================== Indicator 2: Trend Signals ===================
|
||||
// Dual EMA system for trend detection
|
||||
fastEma := ta.EMA(e.Close, trendLength)
|
||||
slowEma := ta.EMA(e.Close, trendLength*2)
|
||||
trendDiff := fastEma.Sub(slowEma).Div(slowEma).Mul(100)
|
||||
trendDiffVal := trendDiff.Get(0)
|
||||
|
||||
var trendSignal float64
|
||||
if trendDiffVal > trendThreshold {
|
||||
trendSignal = 1
|
||||
} else if trendDiffVal < -trendThreshold {
|
||||
trendSignal = -1
|
||||
} else {
|
||||
trendSignal = 0
|
||||
}
|
||||
|
||||
// =================== Indicator 3: Enhanced Wavetrend ===================
|
||||
// Calculate Wavetrend components
|
||||
ap := ta.HLC3(e.High, e.Low, e.Close)
|
||||
esa := ta.EMA(ap, wtChannelLength)
|
||||
d := ta.EMA(ap.Sub(esa).Abs(), wtChannelLength)
|
||||
ci := ap.Sub(esa).Div(d.Mul(0.015))
|
||||
tci := ta.EMA(ci, wtAverageLength)
|
||||
|
||||
// Generate main and signal lines
|
||||
wt1 := tci
|
||||
wt2 := ta.SMA(wt1, wtMaLength)
|
||||
|
||||
// Generate Wavetrend Signal based on overbought/oversold conditions
|
||||
wt1Val := wt1.Get(0)
|
||||
wt2Val := wt2.Get(0)
|
||||
|
||||
// 修复:使用Series保存wt_signal状态
|
||||
wtSignalSeries := e.Close.To("_wt_signal", 0)
|
||||
var wtSignal float64
|
||||
if wt1Val > wtOverbought && wt2Val > wtOverbought {
|
||||
wtSignal = -1 // 超买信号
|
||||
} else if wt1Val < wtOversold && wt2Val < wtOversold { // 修复:使用独立的wtOversold参数
|
||||
wtSignal = 1 // 超卖信号
|
||||
} else {
|
||||
wtSignal = wtSignalSeries.Get(1)
|
||||
}
|
||||
wtSignalSeries.Set(wtSignal)
|
||||
|
||||
// =================== Consensus Signal Generation ===================
|
||||
// 修复:正确计算净信号数(范围-3到3)
|
||||
consensusCount := 0
|
||||
if lwstTrend == 1 {
|
||||
consensusCount++
|
||||
} else if lwstTrend == -1 {
|
||||
consensusCount--
|
||||
}
|
||||
if trendSignal == 1 {
|
||||
consensusCount++
|
||||
} else if trendSignal == -1 {
|
||||
consensusCount--
|
||||
}
|
||||
if wtSignal == 1 {
|
||||
consensusCount++
|
||||
} else if wtSignal == -1 {
|
||||
consensusCount--
|
||||
}
|
||||
|
||||
// Generate trading signals when majority (2+ indicators) agree
|
||||
buySignal := consensusCount >= 2
|
||||
sellSignal := consensusCount <= -2
|
||||
|
||||
// =================== Trade Execution ===================
|
||||
if buySignal && len(s.LongOrders) == 0 && len(s.ShortOrders) == 0 {
|
||||
// 计算止损止盈价格
|
||||
slAmount := currentPrice * slPercent / 100
|
||||
tpAmount := currentPrice * tpPercent / 100
|
||||
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: "Short",
|
||||
Short: true,
|
||||
StopLossVal: slAmount,
|
||||
TakeProfitVal: tpAmount,
|
||||
})
|
||||
} else if sellSignal && len(s.ShortOrders) == 0 && len(s.LongOrders) == 0 {
|
||||
// 计算做空止损止盈价格
|
||||
slAmount := currentPrice * slPercent / 100
|
||||
tpAmount := currentPrice * tpPercent / 100
|
||||
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: "Long",
|
||||
Short: false,
|
||||
StopLossVal: slAmount,
|
||||
TakeProfitVal: tpAmount,
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user