75 lines
1.9 KiB
Go
75 lines
1.9 KiB
Go
package llmjob
|
||
|
||
import (
|
||
"math"
|
||
|
||
"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"
|
||
)
|
||
|
||
func J7593(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||
// 定义可调参数
|
||
lengthRSI := pol.DefInt("lengthRSI", 20, core.PNorm(5, 30))
|
||
rsiEntryThs := pol.DefInt("rsiEntryThs", 72, core.PNorm(60, 85))
|
||
rsiExitThs := pol.DefInt("rsiExitThs", 50, core.PNorm(45, 65))
|
||
takeProfitRate := pol.Def("takeProfitRate", 6.0, core.PNorm(1, 15))
|
||
|
||
return &strat.TradeStrat{
|
||
Name: "TrendFollowingRSI",
|
||
WarmupNum: lengthRSI + 10, // 预热足够的K线用于RSI计算
|
||
HedgeOff: true, // 单向持仓模式
|
||
EachMaxLong: 1, // 最多持有一个多单
|
||
TimeFrames: "8h",
|
||
OnBar: func(s *strat.StratJob) {
|
||
e := s.Env
|
||
|
||
// 计算RSI指标
|
||
rsi := ta.RSI(e.Close, lengthRSI)
|
||
currentRSI := rsi.Get(0)
|
||
|
||
// 检查是否有有效的RSI值
|
||
if math.IsNaN(currentRSI) {
|
||
return
|
||
}
|
||
|
||
// 入场条件:RSI > 70
|
||
if currentRSI > float64(rsiEntryThs) && len(s.LongOrders) == 0 {
|
||
s.OpenOrder(&strat.EnterReq{
|
||
Tag: "long",
|
||
Short: false,
|
||
})
|
||
}
|
||
|
||
// 出场条件:RSI < 55
|
||
if currentRSI < float64(rsiExitThs) && s.Position(core.OdDirtLong, "") > 0 {
|
||
s.CloseOrders(&strat.ExitReq{
|
||
Tag: "rsi_exit",
|
||
Dirt: core.OdDirtLong,
|
||
})
|
||
}
|
||
},
|
||
|
||
OnCheckExit: func(s *strat.StratJob, od *ormo.InOutOrder) *strat.ExitReq {
|
||
// 仅对开仓状态的多头订单检查止盈
|
||
if !od.Short || od.Status != ormo.InOutStatusFullEnter {
|
||
return nil
|
||
}
|
||
|
||
// 基于持仓成本计算止盈目标价
|
||
longTakeProfit := od.InitPrice * (1 + takeProfitRate/100)
|
||
|
||
// 检查是否达到止盈条件
|
||
if s.Env.Close.Get(0) > longTakeProfit {
|
||
return &strat.ExitReq{
|
||
Tag: "tp_exit",
|
||
Dirt: core.OdDirtLong,
|
||
}
|
||
}
|
||
return nil
|
||
},
|
||
}
|
||
}
|