Files
banstagy/flux/grid/inv.go
2026-08-24 20:53:21 +08:00

82 lines
2.0 KiB
Go

package grid
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"
)
/*
多头网格,下跌买入,上涨卖出。适合波动性较强,方向不明的市场。
以大周期atrBase的一定比例作为网格的单位大小
初始倍率: InitRate
初次开仓条件:
大周期ER20 < 0.3
小周期MA5 < MA20 看多网格;否则看空网格
持有仓位:
*/
type GridV1 struct {
*Grid
bigER float64 // 大周期ER系数
}
func InvGrid(pol *config.RunPolicyConfig) *strat.TradeStrat {
lenAtr := 20
baseAtrLen := int(float64(lenAtr) * 4.3)
unitRate := pol.Def("unitRate", 2, core.PNorm(0.5, 5))
initRate := int(pol.Def("initRate", 4, core.PNorm(0.7, 7.3)))
maxAdd := 5
return &strat.TradeStrat{
WarmupNum: 100,
StopEnterBars: 9999999,
TimeFrames: "1m",
OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
return []*strat.PairSub{
{"_cur_", "4h", 100},
}
},
OnStartUp: func(s *strat.StratJob) {
s.More = &GridV1{Grid: NewGrid(initRate, maxAdd, 6, false)}
},
OnBar: func(s *strat.StratJob) {
m, _ := s.More.(*GridV1)
if s.OrderNum == 0 {
if m.Unit == 0 || m.bigER >= 0.1 || s.IsWarmUp {
return
}
m.Open(s)
} else {
m.CheckPos(s)
}
},
OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
m, _ := s.More.(*GridV1)
m.bigER = ta.ER(e.Close, 20).Get(0)
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
ma5 := ta.SMA(e.Close, 10).Get(0)
ma20 := ta.SMA(e.Close, 50).Get(0)
if s.OrderNum == 0 && !math.IsNaN(atrBase) {
// 未持仓时更新网格单元大小
m.Unit = atrBase * unitRate
m.Dirt = core.OdDirtShort
if ma5 < ma20 {
m.Dirt = core.OdDirtLong
}
}
},
OnOrderChange: func(s *strat.StratJob, od *ormo.InOutOrder, chgType int) {
m, _ := s.More.(*GridV1)
m.OnOrderChange(s, od, chgType)
},
}
}