Files
banstagy/llmjob/587.go
2026-08-24 20:53:21 +08:00

145 lines
4.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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"
)
// MartingaleState 存储马丁格尔策略的状态
type MartingaleState struct {
ContractSize float64 // 当前合约数量
MartingaleCount int // 马丁格尔计数器
LastTradeResult float64 // 上次交易结果
}
func J587(pol *config.RunPolicyConfig) *strat.TradeStrat {
// 定义可调超参数
fastLength := pol.DefInt("fastLength", 15, core.PNorm(5, 30))
maRate := pol.Def("maRate", 2.0, core.PNorm(1.5, 4.0))
maxMartingaleCount := pol.DefInt("maxMartingaleCount", 3, core.PNorm(1, 5))
martingaleMultiplier := pol.Def("martingaleMultiplier", 2.0, core.PNorm(1.5, 3.0))
// 计算慢线周期
slowLength := int(float64(fastLength) * maRate)
signalSmoothing := 9
// 止盈止损比例
longTakeProfit := 1.015 // 多头止盈1.5%
longStopLoss := 0.99 // 多头止损1%
shortTakeProfit := 1.01 // 空头止盈1%
shortStopLoss := 0.99 // 空头止损1%
return &strat.TradeStrat{
WarmupNum: slowLength + signalSmoothing, // 确保有足够的数据计算MACD
HedgeOff: true, // 单向持仓模式
RunTimeFrames: []string{"3d"},
OnStartUp: func(s *strat.StratJob) {
// 初始化马丁格尔状态
s.More = &MartingaleState{
ContractSize: 0.02,
MartingaleCount: 0,
LastTradeResult: 0,
}
},
OnBar: func(s *strat.StratJob) {
e := s.Env
state, _ := s.More.(*MartingaleState)
// 计算MACD指标
macdLine, signalLine := ta.MACD(e.Close, fastLength, slowLength, signalSmoothing)
// 检测MACD交叉信号(只计算一次)
macdCross := macdLine.Cross(signalLine)
longCondition := macdCross == 1 // 上穿
shortCondition := macdCross == -1 // 下穿
// 获取当前价格
currentPrice := e.Close.Get(0)
if math.IsNaN(currentPrice) {
return
}
// 多头信号
if longCondition && s.Position(1, "") == 0 {
// 计算止盈止损价格
takeProfitPrice := currentPrice * longTakeProfit
stopLossPrice := currentPrice * longStopLoss
takeProfitVal := takeProfitPrice - currentPrice
stopLossVal := currentPrice - stopLossPrice
// 开多单
s.OpenOrder(&strat.EnterReq{
Tag: "Long",
OrderType: core.OrderTypeMarket,
Short: false,
TakeProfitVal: takeProfitVal,
StopLossVal: stopLossVal,
TakeProfitTag: "long_take_profit",
StopLossTag: "long_stop_loss",
CostRate: state.ContractSize / 0.02, // 根据合约数量调整开仓金额
})
// 记录当前交易结果
state.LastTradeResult = 0
}
// 空头信号
if shortCondition && s.Position(-1, "") == 0 {
// 计算止盈止损价格
takeProfitPrice := currentPrice / shortTakeProfit
stopLossPrice := currentPrice / shortStopLoss
takeProfitVal := currentPrice - takeProfitPrice
stopLossVal := stopLossPrice - currentPrice
// 开空单
s.OpenOrder(&strat.EnterReq{
Tag: "Short",
OrderType: core.OrderTypeMarket,
Short: true,
TakeProfitVal: takeProfitVal,
StopLossVal: stopLossVal,
TakeProfitTag: "short_take_profit",
StopLossTag: "short_stop_loss",
CostRate: state.ContractSize / 0.02, // 根据合约数量调整开仓金额
})
// 记录当前交易结果
state.LastTradeResult = 0
}
},
OnOrderChange: func(s *strat.StratJob, od *ormo.InOutOrder, chgType int) {
state, _ := s.More.(*MartingaleState)
// 当订单完全平仓时更新马丁格尔状态
if chgType == strat.OdChgExitFill && od.Status == ormo.InOutStatusFullExit {
// 获取当前交易结果
currentProfit := od.ProfitRate
if currentProfit < state.LastTradeResult {
// 上次交易亏损
if state.MartingaleCount < maxMartingaleCount {
// 增加马丁格尔计数并加倍合约数量
state.ContractSize *= martingaleMultiplier
state.MartingaleCount++
} else {
// 达到最大马丁格尔次数,重置
state.ContractSize = 0.02
state.MartingaleCount = 0
}
} else {
// 盈利或持平,重置马丁格尔状态
state.ContractSize = 0.02
state.MartingaleCount = 0
}
// 更新交易结果
state.LastTradeResult = currentProfit
}
},
}
}