init
This commit is contained in:
249
llmjob/5129.go
Normal file
249
llmjob/5129.go
Normal file
@@ -0,0 +1,249 @@
|
||||
// 修复后的banbot完整策略代码
|
||||
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"
|
||||
"time"
|
||||
)
|
||||
|
||||
type MfiStrategyState struct {
|
||||
DayStart int64
|
||||
DayLow float64
|
||||
DayHigh float64
|
||||
EntryTime int64
|
||||
LongSlPrice float64
|
||||
ShortSlPrice float64
|
||||
LongTpPrice float64
|
||||
ShortTpPrice float64
|
||||
TrailStop float64
|
||||
TrailStopShort float64
|
||||
EntryHigh float64
|
||||
EntryLow float64
|
||||
}
|
||||
|
||||
func J5129(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
mfiPeriod := pol.DefInt("mfiPeriod", 3, core.PNorm(2, 10))
|
||||
barBodySize := pol.Def("barBodySize", 0.65, core.PNorm(0.3, 0.8))
|
||||
maPeriod := pol.DefInt("maPeriod", 120, core.PNorm(20, 200))
|
||||
useMaFilter := pol.Def("useMaFilter", 1.0, nil)
|
||||
useShorts := pol.Def("useShorts", 1.0, nil)
|
||||
slType := pol.Def("slType", 0, nil) // 0:Strategy Stop, 1:Swing, 2:ATR
|
||||
swingLookback := pol.DefInt("swingLookback", 10, core.PNorm(5, 30))
|
||||
swingPercInc := pol.Def("swingPercInc", 0.03, core.PNorm(0.01, 0.1))
|
||||
atrLength := pol.DefInt("atrLength", 14, core.PNorm(7, 30))
|
||||
atrMultiple := pol.Def("atrMultiple", 6.5, core.PNorm(2.0, 10.0))
|
||||
rewardRatio := pol.Def("rewardRatio", 3.2, core.PNorm(1.5, 4.0))
|
||||
useTpSl := pol.Def("useTpSl", 1.0, nil)
|
||||
useTimedExit := pol.Def("useTimedExit", 0.0, nil)
|
||||
useTrailingStop := pol.Def("useTrailingStop", 0.0, nil)
|
||||
allowDirectPositionReverse := pol.Def("allowDirectPositionReverse", 1.0, nil)
|
||||
|
||||
return &strat.TradeStrat{
|
||||
Name: "Money Flow Index 5 min Strategy",
|
||||
Version: 1,
|
||||
WarmupNum: 100,
|
||||
HedgeOff: false,
|
||||
EachMaxLong: 1,
|
||||
EachMaxShort: 1,
|
||||
RunTimeFrames: []string{"15m"},
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
s.More = &MfiStrategyState{
|
||||
DayStart: -1,
|
||||
DayLow: math.Inf(1),
|
||||
DayHigh: math.Inf(-1),
|
||||
EntryTime: 0,
|
||||
LongSlPrice: math.NaN(),
|
||||
ShortSlPrice: math.NaN(),
|
||||
LongTpPrice: math.NaN(),
|
||||
ShortTpPrice: math.NaN(),
|
||||
TrailStop: math.NaN(),
|
||||
TrailStopShort: math.NaN(),
|
||||
EntryHigh: math.NaN(),
|
||||
EntryLow: math.NaN(),
|
||||
}
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
now := e.TimeStop
|
||||
c, h, l, o := e.Close.Get(0), e.High.Get(0), e.Low.Get(0), e.Open.Get(0)
|
||||
if math.IsNaN(c) || math.IsNaN(h) || math.IsNaN(l) {
|
||||
return
|
||||
}
|
||||
|
||||
// 更新交易日状态
|
||||
t := time.UnixMilli(now)
|
||||
dayStartMs := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()).UnixMilli()
|
||||
m := s.More.(*MfiStrategyState)
|
||||
if m.DayStart != dayStartMs {
|
||||
m.DayStart = dayStartMs
|
||||
m.DayLow = l
|
||||
m.DayHigh = h
|
||||
} else {
|
||||
if l < m.DayLow {
|
||||
m.DayLow = l
|
||||
}
|
||||
if h > m.DayHigh {
|
||||
m.DayHigh = h
|
||||
}
|
||||
}
|
||||
|
||||
// 计算指标
|
||||
mfi := ta.MFI(e, mfiPeriod)
|
||||
smaVal := ta.SMA(e.Close, maPeriod)
|
||||
maFilter := c > smaVal.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, atrLength).Get(0)
|
||||
|
||||
// K线实体判断 - 修复错误3:与原始策略保持一致
|
||||
barSize := h - l
|
||||
var barBodySizeVal float64
|
||||
if c > o {
|
||||
barBodySizeVal = (o - c) * -1
|
||||
} else {
|
||||
barBodySizeVal = (o - c)
|
||||
}
|
||||
shortWicks := barBodySizeVal > barSize*barBodySize
|
||||
|
||||
// 交易信号
|
||||
prevMfi := mfi.Get(1)
|
||||
buySignal := !math.IsNaN(prevMfi) && prevMfi == 100 && c > o && shortWicks && (useMaFilter == 0.0 || maFilter)
|
||||
sellSignal := false
|
||||
if useShorts == 1.0 {
|
||||
sellSignal = !math.IsNaN(prevMfi) && prevMfi == 0 && c < o && shortWicks && (useMaFilter == 0.0 || !maFilter)
|
||||
}
|
||||
|
||||
// 检查60分钟退出规则 - 修复错误2:添加60分钟退出规则
|
||||
if useTimedExit == 1.0 && m.EntryTime > 0 {
|
||||
timeSinceEntry := (now - m.EntryTime) / 60000 // 转换为分钟
|
||||
if timeSinceEntry >= 60 {
|
||||
// 60分钟后平仓
|
||||
if len(s.LongOrders) > 0 || len(s.ShortOrders) > 0 {
|
||||
s.CloseOrders(&strat.ExitReq{Dirt: core.OdDirtBoth})
|
||||
m.EntryTime = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 计算止损止盈 - 修复错误1和4:记录开仓时的止损价格
|
||||
var longSl, shortSl, longTp, shortTp float64
|
||||
if useTpSl == 1.0 {
|
||||
switch int(slType) {
|
||||
case 0: // Strategy Stop
|
||||
longSl = m.DayLow * (1 - swingPercInc)
|
||||
shortSl = m.DayHigh * (1 + swingPercInc)
|
||||
case 1: // Swing Lo/Hi
|
||||
ll := ta.Lowest(e.Low, swingLookback).Get(0) * (1 - swingPercInc)
|
||||
hh := ta.Highest(e.High, swingLookback).Get(0) * (1 + swingPercInc)
|
||||
longSl = ll
|
||||
shortSl = hh
|
||||
case 2: // ATR Stop
|
||||
ohlc4 := (o + h + l + c) / 4
|
||||
longSl = ohlc4 - atr*atrMultiple
|
||||
shortSl = ohlc4 + atr*atrMultiple
|
||||
}
|
||||
longTp = c + (c-longSl)*rewardRatio
|
||||
shortTp = c - (shortSl-c)*rewardRatio
|
||||
}
|
||||
|
||||
// 更新追踪止损 - 修复错误5:添加追踪止损功能
|
||||
if useTrailingStop == 1.0 {
|
||||
if len(s.LongOrders) > 0 {
|
||||
for _, pos := range s.LongOrders {
|
||||
if pos.Status == ormo.InOutStatusFullEnter { // 多头仓位
|
||||
if math.IsNaN(m.EntryHigh) || h > m.EntryHigh {
|
||||
m.EntryHigh = h
|
||||
}
|
||||
trailOffset := pos.InitPrice - m.LongSlPrice
|
||||
newTrailStop := m.EntryHigh - trailOffset
|
||||
if math.IsNaN(m.TrailStop) || newTrailStop > m.TrailStop {
|
||||
m.TrailStop = newTrailStop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(s.ShortOrders) > 0 {
|
||||
for _, pos := range s.ShortOrders {
|
||||
if pos.Status == ormo.InOutStatusFullEnter { // 空头仓位
|
||||
if math.IsNaN(m.EntryLow) || l < m.EntryLow {
|
||||
m.EntryLow = l
|
||||
}
|
||||
trailOffset := m.ShortSlPrice - pos.InitPrice
|
||||
newTrailStop := m.EntryLow + trailOffset
|
||||
if math.IsNaN(m.TrailStopShort) || newTrailStop < m.TrailStopShort {
|
||||
m.TrailStopShort = newTrailStop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 开仓 - 修复错误6:检查持仓数量和挂单数量
|
||||
canOpenLong := len(s.LongOrders) == 0 && (len(s.ShortOrders) == 0 || (allowDirectPositionReverse == 1.0 && len(s.ShortOrders) > 0))
|
||||
canOpenShort := len(s.ShortOrders) == 0 && (len(s.LongOrders) == 0 || (allowDirectPositionReverse == 1.0 && len(s.LongOrders) > 0))
|
||||
|
||||
if buySignal && canOpenLong {
|
||||
// 记录开仓时的止损价格
|
||||
m.LongSlPrice = longSl
|
||||
m.LongTpPrice = longTp
|
||||
m.EntryHigh = h
|
||||
m.EntryTime = now
|
||||
|
||||
req := &strat.EnterReq{
|
||||
Tag: "long",
|
||||
StopLoss: longSl,
|
||||
TakeProfit: longTp,
|
||||
StopLossTag: "sl",
|
||||
TakeProfitTag: "tp",
|
||||
}
|
||||
s.OpenOrder(req)
|
||||
}
|
||||
|
||||
if sellSignal && canOpenShort {
|
||||
// 记录开仓时的止损价格
|
||||
m.ShortSlPrice = shortSl
|
||||
m.ShortTpPrice = shortTp
|
||||
m.EntryLow = l
|
||||
m.EntryTime = now
|
||||
|
||||
req := &strat.EnterReq{
|
||||
Tag: "short",
|
||||
Short: true,
|
||||
StopLoss: shortSl,
|
||||
TakeProfit: shortTp,
|
||||
StopLossTag: "sl",
|
||||
TakeProfitTag: "tp",
|
||||
}
|
||||
s.OpenOrder(req)
|
||||
}
|
||||
|
||||
// 更新现有订单的止损止盈
|
||||
if len(s.LongOrders) > 0 && !math.IsNaN(m.LongSlPrice) {
|
||||
for _, order := range s.LongOrders {
|
||||
if order.Status == ormo.InOutStatusInit {
|
||||
order.SetStopLoss(&ormo.ExitTrigger{Price: m.LongSlPrice, Tag: "sl"})
|
||||
order.SetTakeProfit(&ormo.ExitTrigger{Price: m.LongTpPrice, Tag: "tp"})
|
||||
if useTrailingStop == 1.0 && !math.IsNaN(m.TrailStop) {
|
||||
order.SetStopLoss(&ormo.ExitTrigger{Price: m.TrailStop, Tag: "sl"})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(s.ShortOrders) > 0 && !math.IsNaN(m.ShortSlPrice) {
|
||||
for _, order := range s.ShortOrders {
|
||||
if order.Status == ormo.InOutStatusInit {
|
||||
order.SetStopLoss(&ormo.ExitTrigger{Price: m.ShortSlPrice, Tag: "sl"})
|
||||
order.SetTakeProfit(&ormo.ExitTrigger{Price: m.ShortTpPrice, Tag: "tp"})
|
||||
if useTrailingStop == 1.0 && !math.IsNaN(m.TrailStopShort) {
|
||||
order.SetStopLoss(&ormo.ExitTrigger{Price: m.TrailStopShort, Tag: "sl"})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user