Files
banstagy/old/rev/01.go
2026-08-24 20:53:21 +08:00

120 lines
3.0 KiB
Go
Raw 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 rev
import (
"github.com/banbox/banbot/config"
"github.com/banbox/banbot/core"
"github.com/banbox/banbot/orm/ormo"
"github.com/banbox/banbot/strat"
"github.com/banbox/banstagy/com"
ta "github.com/banbox/banta"
"math"
)
type MoreRev struct {
thres float64 // 阈值
dirt float64 // 1rsi高于0,-1rsi低于0
hitAt int // 进入极值的BarNum
exmVal float64 // 最大极值
bigRsi float64 // 大周期rsi
}
func (m *MoreRev) update(rsi50 float64, barNum int) {
rsiAbs := math.Abs(rsi50)
if rsiAbs < m.thres {
m.dirt = 0
m.hitAt = 0
m.exmVal = 0
return
}
if m.dirt == 0 {
if rsi50 > 0 {
m.dirt = 1
} else {
m.dirt = -1
}
m.hitAt = barNum
m.exmVal = rsiAbs
} else if m.exmVal < rsiAbs {
m.exmVal = rsiAbs
}
}
func S01V1(pol *config.RunPolicyConfig) *strat.TradeStrat {
var lenRsi = 22
var lenRsi2 = 140
var thresRsi = 20.0
var hitRsi = 22.0
var minKeep = 3
lenAtr := 15
baseAtrLen := int(math.Round(float64(lenAtr) * 4.3))
return &strat.TradeStrat{
Version: 1,
WarmupNum: lenRsi * 2,
MinTfScore: 0.75,
DrawDownExit: true,
OnStartUp: func(s *strat.StratJob) {
s.More = &MoreRev{thres: thresRsi}
},
OnPairInfos: com.MakePairInfos(lenRsi2),
OnBar: func(s *strat.StratJob) {
e := s.Env
m, _ := s.More.(*MoreRev)
rsi := ta.RSI(e.Close, lenRsi)
rsiMa := ta.SMA(rsi, 3)
rsiVal := rsi.Get(0)
rsiX := rsi.Cross(rsiMa)
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
atrRate := math.Sqrt(atr.Get(0) / atrBase)
c := e.Close.Get(0)
bigRsiFit := math.Abs(m.bigRsi) > 5 && m.bigRsi*m.dirt > 0
rsiFit := m.dirt != 0 && m.exmVal >= hitRsi && e.BarNum-m.hitAt >= minKeep
if s.OrderNum == 0 && bigRsiFit && rsiFit && (rsiX == 1 || rsiX == -1) {
// rsi处于极值范围,且触发最大极值,且满足最少极值数量,且和rsi均值交叉
slVal := atrBase * atrRate * 5
slLong, slShort := c-slVal, c+slVal
//entPrice := c - slVal*0.3
//if m.dirt > 0 {
// entPrice = c - slVal*0.3
//}
com.FastOpen(s, -m.dirt, slLong, slShort, 0)
} else if rsiFit && s.EnteredNum > 0 && m.bigRsi*m.dirt > 0 {
if m.dirt == 1 && len(s.LongOrders) > 0 && m.bigRsi > 2 {
// 平多
_ = s.CloseOrders(&strat.ExitReq{
Tag: "exitL",
Dirt: core.OdDirtLong,
})
} else if m.dirt == -1 && len(s.ShortOrders) > 0 && m.bigRsi < -2 {
_ = s.CloseOrders(&strat.ExitReq{
Tag: "exitS",
Dirt: core.OdDirtShort,
})
}
}
m.update(rsiVal-50, e.BarNum)
},
OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
m, _ := s.More.(*MoreRev)
m.bigRsi = ta.RSI50(e.Close, lenRsi2).Get(0)
},
GetDrawDownExitRate: func(s *strat.StratJob, od *ormo.InOutOrder, maxChg float64) float64 {
sl := od.GetStopLoss()
if sl == nil || sl.Range == 0 {
return 0
}
bestRate := maxChg * od.InitPrice / sl.Range
if bestRate > 2 {
return 0.3
} else if bestRate > 1 {
return 0.5
}
return 0
},
}
}