164 lines
4.4 KiB
Go
164 lines
4.4 KiB
Go
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"
|
||
)
|
||
|
||
type KijunData struct {
|
||
initialCapital float64
|
||
netProfit float64
|
||
}
|
||
|
||
func J3746(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||
// 定义可调超参数
|
||
ksPeriod := pol.DefInt("ksPeriod", 30, core.PNorm(9, 50))
|
||
atrPeriod := pol.DefInt("atrPeriod", 14, core.PNorm(7, 30))
|
||
atrMultiplier := pol.Def("atrMultiplier", 1.5, core.PNorm(0.8, 4))
|
||
targetPoints := pol.Def("targetPoints", 100, core.PNorm(50, 200))
|
||
riskPercent := pol.Def("riskPercent", 4, core.PNorm(1, 10))
|
||
equityProtection := pol.Def("equityProtection", 30, core.PNorm(10, 50))
|
||
|
||
return &strat.TradeStrat{
|
||
WarmupNum: ksPeriod, // 预热K线数量,确保基均线计算有足够数据
|
||
HedgeOff: true, // 单向持仓模式
|
||
RunTimeFrames: []string{"3d"},
|
||
OnStartUp: func(s *strat.StratJob) {
|
||
// 初始化每个品种的特定数据
|
||
s.More = &KijunData{
|
||
initialCapital: 50000.0, // 初始资金
|
||
netProfit: 0.0, // 初始净利润
|
||
}
|
||
},
|
||
|
||
OnBar: func(s *strat.StratJob) {
|
||
e := s.Env
|
||
m, _ := s.More.(*KijunData)
|
||
|
||
// 计算技术指标
|
||
atr := ta.ATR(e.High, e.Low, e.Close, atrPeriod)
|
||
atrValue := atr.Get(0)
|
||
|
||
// 计算基均线 (Kijun Sen)
|
||
highest := ta.Highest(e.High, ksPeriod)
|
||
lowest := ta.Lowest(e.Low, ksPeriod)
|
||
kijunSen := highest.Add(lowest).Div(2)
|
||
kijunSenValue := kijunSen.Get(0)
|
||
|
||
// 检查数据有效性
|
||
if math.IsNaN(atrValue) || math.IsNaN(kijunSenValue) {
|
||
return
|
||
}
|
||
|
||
// 生成交易信号
|
||
openPrice := e.Open.Get(0)
|
||
closePrice := e.Close.Get(0)
|
||
baseLong := openPrice < kijunSenValue && closePrice > kijunSenValue
|
||
baseShort := openPrice > kijunSenValue && closePrice < kijunSenValue
|
||
|
||
// 计算止损距离
|
||
stopLossVal := atrValue * atrMultiplier
|
||
|
||
// 更新净利润
|
||
// 计算总浮动盈亏
|
||
totalFloating := 0.0
|
||
for _, od := range s.LongOrders {
|
||
totalFloating += od.Profit
|
||
}
|
||
for _, od := range s.ShortOrders {
|
||
totalFloating += od.Profit
|
||
}
|
||
m.netProfit = totalFloating
|
||
|
||
// 权益保护检查
|
||
equityStopout := false
|
||
if s.OrderNum > 0 {
|
||
// 计算当前余额(初始资金 + 净利润)
|
||
totalBalance := m.initialCapital + m.netProfit
|
||
|
||
// 检查是否触发权益保护
|
||
if totalFloating < 0 && math.Abs(totalFloating/totalBalance) > equityProtection/100 {
|
||
equityStopout = true
|
||
}
|
||
}
|
||
|
||
// 权益保护触发时平仓所有头寸
|
||
if equityStopout {
|
||
s.CloseOrders(&strat.ExitReq{
|
||
Tag: "equity_protection",
|
||
Dirt: core.OdDirtBoth,
|
||
Force: true,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 检查是否有持仓
|
||
hasLongPosition := len(s.LongOrders) > 0
|
||
hasShortPosition := len(s.ShortOrders) > 0
|
||
|
||
// 计算头寸大小
|
||
balance := m.initialCapital + m.netProfit
|
||
riskAmount := balance * (riskPercent / 100) // 风险金额
|
||
size := riskAmount / stopLossVal // 合约数量
|
||
if size < 0.001 { // 最小合约数量检查
|
||
size = 0.001
|
||
}
|
||
|
||
// 多头交易
|
||
if baseLong && !hasLongPosition && !hasShortPosition {
|
||
s.OpenOrder(&strat.EnterReq{
|
||
Tag: "l_en",
|
||
Amount: size,
|
||
StopLossVal: stopLossVal,
|
||
TakeProfitVal: targetPoints,
|
||
StopLossTag: "stop_loss",
|
||
TakeProfitTag: "take_profit",
|
||
})
|
||
}
|
||
|
||
// 空头交易
|
||
if baseShort && !hasShortPosition && !hasLongPosition {
|
||
s.OpenOrder(&strat.EnterReq{
|
||
Tag: "s_en",
|
||
Short: true,
|
||
Amount: size,
|
||
StopLossVal: stopLossVal,
|
||
TakeProfitVal: targetPoints,
|
||
StopLossTag: "stop_loss",
|
||
TakeProfitTag: "take_profit",
|
||
})
|
||
}
|
||
},
|
||
|
||
OnCheckExit: func(s *strat.StratJob, od *ormo.InOutOrder) *strat.ExitReq {
|
||
// 计算基均线
|
||
highest := ta.Highest(s.Env.High, ksPeriod)
|
||
lowest := ta.Lowest(s.Env.Low, ksPeriod)
|
||
kijunSen := highest.Add(lowest).Div(2)
|
||
kijunSenValue := kijunSen.Get(0)
|
||
|
||
closePrice := s.Env.Close.Get(0)
|
||
|
||
// 多头平仓条件:收盘价低于基均线
|
||
if !od.Short && closePrice < kijunSenValue {
|
||
return &strat.ExitReq{
|
||
Tag: "long_exit",
|
||
}
|
||
}
|
||
|
||
// 空头平仓条件:收盘价高于基均线
|
||
if od.Short && closePrice > kijunSenValue {
|
||
return &strat.ExitReq{
|
||
Tag: "short_exit",
|
||
}
|
||
}
|
||
|
||
return nil
|
||
},
|
||
}
|
||
}
|