111 lines
3.2 KiB
Go
111 lines
3.2 KiB
Go
package llmjob
|
|
|
|
import (
|
|
"math"
|
|
|
|
"github.com/banbox/banbot/config"
|
|
"github.com/banbox/banbot/core"
|
|
"github.com/banbox/banbot/strat"
|
|
ta "github.com/banbox/banta"
|
|
)
|
|
|
|
func J4217(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
|
// 定义可调参数
|
|
fastLength := pol.DefInt("fastLength", 9, core.PNorm(5, 20))
|
|
maRate := pol.Def("maRate", 2.33, core.PNorm(1.5, 5))
|
|
rsiLength := pol.DefInt("rsiLength", 14, core.PNorm(7, 21))
|
|
rsiThreshold := pol.DefInt("rsiThreshold", 70, core.PNorm(60, 80))
|
|
atrStopLoss := pol.Def("atrStopLoss", 2.0, core.PNorm(1.0, 4.0))
|
|
atrPeriod := pol.DefInt("atrPeriod", 14, core.PNorm(7, 21))
|
|
// 添加MACD参数配置
|
|
macdFast := pol.DefInt("macdFast", 12, core.PNorm(8, 20))
|
|
macdSlow := pol.DefInt("macdSlow", 26, core.PNorm(20, 40))
|
|
macdSignal := pol.DefInt("macdSignal", 9, core.PNorm(5, 15))
|
|
|
|
// 计算慢速EMA周期
|
|
slowLength := int(float64(fastLength) * maRate)
|
|
|
|
// 计算RSI超买超卖水平
|
|
rsiOverboughtLevel := float64(rsiThreshold)
|
|
rsiOversoldLevel := 100 - float64(rsiThreshold)
|
|
|
|
return &strat.TradeStrat{
|
|
WarmupNum: slowLength + atrPeriod, // 确保有足够的数据计算指标
|
|
HedgeOff: true, // 单向持仓模式
|
|
EachMaxLong: 1, // 最多开1个多单
|
|
EachMaxShort: 1, // 最多开1个空单
|
|
TimeFrames: "8h",
|
|
OnBar: func(s *strat.StratJob) {
|
|
e := s.Env
|
|
|
|
// 计算技术指标
|
|
fastMA := ta.EMA(e.Close, fastLength)
|
|
slowMA := ta.EMA(e.Close, slowLength)
|
|
rsi := ta.RSI(e.Close, rsiLength)
|
|
// 使用配置的MACD参数
|
|
macdLine, signalLine := ta.MACD(e.Close, macdFast, macdSlow, macdSignal)
|
|
atr := ta.ATR(e.High, e.Low, e.Close, atrPeriod)
|
|
|
|
// 获取最新值
|
|
fastMAVal := fastMA.Get(0)
|
|
slowMAVal := slowMA.Get(0)
|
|
rsiVal := rsi.Get(0)
|
|
atrVal := atr.Get(0)
|
|
|
|
// 检查数据有效性
|
|
if math.IsNaN(fastMAVal) || math.IsNaN(slowMAVal) || math.IsNaN(rsiVal) || math.IsNaN(atrVal) {
|
|
return
|
|
}
|
|
|
|
// 判断趋势
|
|
bullishTrend := fastMAVal > slowMAVal
|
|
bearishTrend := fastMAVal < slowMAVal
|
|
|
|
// 生成交易信号
|
|
longCondition := bullishTrend && rsiVal < rsiOverboughtLevel && macdLine.Cross(signalLine) == 1
|
|
shortCondition := bearishTrend && rsiVal > rsiOversoldLevel && macdLine.Cross(signalLine) == -1
|
|
|
|
// 计算止损距离
|
|
stopLossDistance := atrVal * atrStopLoss
|
|
|
|
// 执行交易操作
|
|
if longCondition && len(s.LongOrders) == 0 {
|
|
// 开多单
|
|
s.OpenOrder(&strat.EnterReq{
|
|
Tag: "Long",
|
|
Short: false,
|
|
StopLossVal: stopLossDistance,
|
|
StopLossTag: "ATR Stop Loss",
|
|
})
|
|
}
|
|
|
|
if shortCondition && len(s.ShortOrders) == 0 {
|
|
// 开空单
|
|
s.OpenOrder(&strat.EnterReq{
|
|
Tag: "Short",
|
|
Short: true,
|
|
StopLossVal: stopLossDistance,
|
|
StopLossTag: "ATR Stop Loss",
|
|
})
|
|
}
|
|
|
|
// 平仓条件
|
|
if len(s.LongOrders) > 0 && (bearishTrend || rsiVal > rsiOverboughtLevel) {
|
|
// 平多单
|
|
s.CloseOrders(&strat.ExitReq{
|
|
Tag: "Close Long",
|
|
Dirt: core.OdDirtLong,
|
|
})
|
|
}
|
|
|
|
if len(s.ShortOrders) > 0 && (bullishTrend || rsiVal < rsiOversoldLevel) {
|
|
// 平空单
|
|
s.CloseOrders(&strat.ExitReq{
|
|
Tag: "Close Short",
|
|
Dirt: core.OdDirtShort,
|
|
})
|
|
}
|
|
},
|
|
}
|
|
}
|