97 lines
2.9 KiB
Go
97 lines
2.9 KiB
Go
package llmjob
|
|
|
|
import (
|
|
"github.com/banbox/banbot/config"
|
|
"github.com/banbox/banbot/core"
|
|
"github.com/banbox/banbot/strat"
|
|
ta "github.com/banbox/banta"
|
|
)
|
|
|
|
func J4583(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
|
// 定义策略参数
|
|
rsiLength := pol.DefInt("rsiLength", 5, core.PNorm(2, 14))
|
|
maLength := pol.DefInt("maLength", 200, core.PNorm(50, 300))
|
|
exitMaLength := pol.DefInt("exitMaLength", 5, core.PNorm(3, 20))
|
|
overboughtThreshold := pol.Def("overboughtThreshold", 80, core.PNorm(70, 95))
|
|
oversoldThreshold := pol.Def("oversoldThreshold", 20, core.PNorm(5, 30))
|
|
stopLossPercentage := pol.Def("stopLossPercentage", 3, core.PNorm(1, 10))
|
|
|
|
return &strat.TradeStrat{
|
|
WarmupNum: maLength, // 预热期设置为长期均线周期
|
|
HedgeOff: true, // 单向持仓模式
|
|
RunTimeFrames: []string{"1h"},
|
|
OnBar: func(s *strat.StratJob) {
|
|
e := s.Env
|
|
|
|
// 计算技术指标
|
|
rsi2 := ta.RSI(e.Close, rsiLength)
|
|
ma200 := ta.SMA(e.Close, maLength)
|
|
ma5Exit := ta.SMA(e.Close, exitMaLength)
|
|
|
|
// 获取当前指标值
|
|
rsiValue := rsi2.Get(0)
|
|
closePrice := e.Close.Get(0)
|
|
ma200Value := ma200.Get(0)
|
|
ma5ExitValue := ma5Exit.Get(0)
|
|
|
|
// 判断趋势方向
|
|
positiveTrend := closePrice > ma200Value
|
|
negativeTrend := closePrice < ma200Value
|
|
|
|
// 生成交易信号
|
|
buyCondition := rsiValue < oversoldThreshold && positiveTrend
|
|
sellCondition := rsiValue > overboughtThreshold && negativeTrend
|
|
|
|
// 生成出场信号
|
|
exitLongCondition := closePrice > ma5ExitValue
|
|
exitShortCondition := closePrice < ma5ExitValue
|
|
|
|
// 执行交易逻辑
|
|
if buyCondition && len(s.LongOrders) == 0 {
|
|
// 开多单,设置止损百分比
|
|
s.OpenOrder(&strat.EnterReq{
|
|
Tag: "Buy",
|
|
Short: false,
|
|
StopLossRate: stopLossPercentage / 100,
|
|
StopLossTag: "stop_loss",
|
|
})
|
|
} else if sellCondition && len(s.ShortOrders) == 0 {
|
|
// 开空单,设置止损百分比
|
|
s.OpenOrder(&strat.EnterReq{
|
|
Tag: "Sell",
|
|
Short: true,
|
|
StopLossRate: stopLossPercentage / 100,
|
|
StopLossTag: "stop_loss",
|
|
})
|
|
}
|
|
|
|
// 计算止损水平
|
|
var stopLossLevelLong, stopLossLevelShort float64
|
|
if len(s.LongOrders) > 0 {
|
|
longEntryPrice := s.LongOrders[0].InitPrice
|
|
stopLossLevelLong = longEntryPrice * (1 - stopLossPercentage/100)
|
|
}
|
|
if len(s.ShortOrders) > 0 {
|
|
shortEntryPrice := s.ShortOrders[0].InitPrice
|
|
stopLossLevelShort = shortEntryPrice * (1 + stopLossPercentage/100)
|
|
}
|
|
|
|
// 多头出场条件(包含止损触发)
|
|
if len(s.LongOrders) > 0 && (exitLongCondition || closePrice <= stopLossLevelLong) {
|
|
s.CloseOrders(&strat.ExitReq{
|
|
Tag: "exit_long",
|
|
Dirt: core.OdDirtLong,
|
|
})
|
|
}
|
|
|
|
// 空头出场条件(包含止损触发)
|
|
if len(s.ShortOrders) > 0 && (exitShortCondition || closePrice >= stopLossLevelShort) {
|
|
s.CloseOrders(&strat.ExitReq{
|
|
Tag: "exit_short",
|
|
Dirt: core.OdDirtShort,
|
|
})
|
|
}
|
|
},
|
|
}
|
|
}
|