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

204
llmjob/5689.go Normal file
View File

@@ -0,0 +1,204 @@
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"
)
/*
因止损未检查bug导致表现看起来很好,不可用
*/
type State5689 struct {
entryPrice float64
hlv3 int // 保存三重均线状态
}
func J5689(pol *config.RunPolicyConfig) *strat.TradeStrat {
// 定义可调超参数
tpPercent := pol.Def("tpPercent", 0.33, core.PNorm(0.15, 0.5)) // 止盈百分比
length := pol.DefInt("length", 18, core.PNorm(10, 50)) // 通道计算周期
lengthChop := pol.DefInt("lengthChop", 14, core.PNorm(5, 30)) // CHOP指标周期
emaPeriod := pol.DefInt("emaPeriod", 10, core.PNorm(5, 30)) // EMA平滑周期
maPeriod := pol.DefInt("maPeriod", 50, core.PNorm(30, 100)) // 主均线周期
channelRate := pol.Def("channelRate", 0.15, core.PNorm(0.1, 0.5)) // 通道倍率
exitPeriod := pol.DefInt("exitPeriod", 12, core.PNorm(5, 30)) // 退出均线周期
return &strat.TradeStrat{
WarmupNum: maPeriod, // 预热K线数量,至少需要主均线周期
RunTimeFrames: []string{"1h"},
OnStartUp: func(s *strat.StratJob) {
// 初始化每个品种的状态变量
s.More = &State5689{
entryPrice: math.NaN(),
hlv3: 0, // 初始状态为0
}
},
OnBar: func(s *strat.StratJob) {
e := s.Env
state, _ := s.More.(*State5689)
// 计算技术指标
upper := ta.Highest(e.High, length)
lower := ta.Lowest(e.Low, length)
// 计算output值:价格在通道中的百分比位置
output := e.Close.Sub(upper).Div(upper.Sub(lower)).Mul(100)
emaOutput := ta.EMA(output, emaPeriod)
// 自定义MA函数:双重WMA平滑
maFunc := func(src *ta.Series, len int) *ta.Series {
wma1 := ta.WMA(src, len/2)
wma2 := ta.WMA(src, len)
return ta.WMA(wma1.Mul(2).Sub(wma2), int(math.Round(math.Sqrt(float64(len)))))
}
// 计算主均线和通道
BBMC := maFunc(e.Close, maPeriod)
rangema := ta.EMA(ta.TR(e.High, e.Low, e.Close), maPeriod)
upperk := BBMC.Add(rangema.Mul(channelRate))
lowerk := BBMC.Sub(rangema.Mul(channelRate))
// 计算退出均线
exitHigh := ta.WMA(e.High, exitPeriod)
exitLow := ta.WMA(e.Low, exitPeriod)
// 计算RSI指标(原始代码中计算但未使用)
_ = ta.RSI(e.Close, 14)
// 计算CHOP指标(虽然不影响交易逻辑,但为了完整性实现)
atr1 := ta.ATR(e.High, e.Low, e.Close, 1)
sumAtr := ta.Sum(atr1, lengthChop)
highestChop := ta.Highest(e.High, lengthChop)
lowestChop := ta.Lowest(e.Low, lengthChop)
chopRange := highestChop.Sub(lowestChop)
// 避免除以零
chopRangeValid := chopRange.Get(0) > 0
if chopRangeValid {
_ = sumAtr.Div(chopRange).Mul(100)
} else {
_ = ta.EMA(e.Close, 1).Mul(0) // 创建全0序列
}
// 获取当前值
closePrice := e.Close.Get(0)
upperkVal := upperk.Get(0)
lowerkVal := lowerk.Get(0)
BBMCVal := BBMC.Get(0)
outputVal := output.Get(0)
emaOutputVal := emaOutput.Get(0)
exitHighVal := exitHigh.Get(0)
exitLowVal := exitLow.Get(0)
// 检查数据有效性
if math.IsNaN(closePrice) || math.IsNaN(BBMCVal) || math.IsNaN(outputVal) || math.IsNaN(emaOutputVal) {
return
}
// 判断价格位置和颜色
colorBlue := closePrice > upperkVal
colorBarFuchsia := closePrice < lowerkVal
// 更新三重均线状态
if closePrice > exitHighVal {
state.hlv3 = 1
} else if closePrice < exitLowVal {
state.hlv3 = -1
}
// 否则保持上一个状态
// 计算退出线
_ = exitHigh
if state.hlv3 < 0 {
_ = exitLow
}
// 生成交易信号
closeXBBMC := e.Close.Cross(BBMC)
longCondition := closeXBBMC == 1 && outputVal > emaOutputVal
shortCondition := closeXBBMC == -1 && outputVal < emaOutputVal
// 执行交易逻辑
if longCondition && len(s.LongOrders) == 0 {
// 记录入场价格
state.entryPrice = closePrice
// 开多单
s.OpenOrder(&strat.EnterReq{
Tag: "ENTER-LONG",
OrderType: core.OrderTypeMarket,
TakeProfit: closePrice * (1 + tpPercent),
})
}
// 为已有订单设置动态止损
if len(s.LongOrders) > 0 && !math.IsNaN(state.entryPrice) {
od := s.LongOrders[0]
if od.Status == ormo.InOutStatusFullEnter {
// 只有当color_bar为FUCHSIA时才设置止损
if colorBarFuchsia && !math.IsNaN(BBMCVal) {
// 设置BBMC作为止损价格
od.SetStopLoss(&ormo.ExitTrigger{
Price: BBMCVal,
Rate: 1.0, // 全部退出
Tag: "dynamic_stop_loss",
})
} else {
// 不设置止损
od.SetStopLoss(nil)
}
// 更新止盈
takeProfitPrice := state.entryPrice * (1 + tpPercent)
od.SetTakeProfit(&ormo.ExitTrigger{
Price: takeProfitPrice,
Rate: 1.0, // 全部退出
Tag: "take_profit",
})
}
}
// 做空部分(原始代码中被注释,这里也注释掉)
if shortCondition && len(s.ShortOrders) == 0 {
state.entryPrice = closePrice
s.OpenOrder(&strat.EnterReq{
Tag: "ENTER-SHORT",
OrderType: core.OrderTypeMarket,
Short: true,
TakeProfit: closePrice * (1 - tpPercent),
})
}
if len(s.ShortOrders) > 0 && !math.IsNaN(state.entryPrice) {
od := s.ShortOrders[0]
if od.Status == ormo.InOutStatusFullEnter {
// 只有当color_bar为BLUE时才设置止损
if colorBlue && !math.IsNaN(BBMCVal) {
// 设置BBMC作为止损价格
od.SetStopLoss(&ormo.ExitTrigger{
Price: BBMCVal,
Rate: 1.0, // 全部退出
Tag: "dynamic_stop_loss_short",
})
} else {
// 不设置止损
od.SetStopLoss(nil)
}
// 更新止盈
takeProfitPrice := state.entryPrice * (1 - tpPercent)
od.SetTakeProfit(&ormo.ExitTrigger{
Price: takeProfitPrice,
Rate: 1.0, // 全部退出
Tag: "take_profit_short",
})
}
}
},
}
}