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

161 lines
5.2 KiB
Go
Raw 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"
)
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,
})
}
},
}
}