Files
banstagy/com/trailing_stop.go
2026-08-24 20:53:21 +08:00

86 lines
2.0 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 com
import (
"github.com/banbox/banbot/strat"
ta "github.com/banbox/banta"
"math"
)
type TRS struct {
MaxLow float64
MinHigh float64
SLLong float64 // 止损的tr倍率,有持仓时,逐渐减小
SLShort float64 // 止损的tr倍率,有持仓时,逐渐减小
InitSLTR float64
minSLTR float64
stepSLTR float64
}
func NewTRS(initSLTR, minRate, costStep float64) *TRS {
var minSLTR = initSLTR * minRate
var stepSLTR = (initSLTR - minSLTR) / costStep
return &TRS{
InitSLTR: initSLTR,
minSLTR: minSLTR,
stepSLTR: stepSLTR,
}
}
func (m *TRS) TrialLong(price float64) {
m.SLLong = m.InitSLTR
m.MaxLow = price
}
func (m *TRS) TrialShort(price float64) {
m.SLShort = m.InitSLTR
m.MinHigh = price
}
func (m *TRS) setTRS(e *ta.BarEnv, longNum, shortNum int) {
h, l := e.High.Get(0), e.Low.Get(0)
if longNum == 0 {
if m.SLLong != m.InitSLTR {
m.MaxLow = 0
}
} else {
m.MaxLow = max(m.MaxLow, l)
if m.SLLong > m.minSLTR+0.01 {
m.SLLong -= m.stepSLTR
}
}
if shortNum == 0 {
if m.SLShort != m.InitSLTR {
m.MinHigh = 0
}
} else {
m.MinHigh = min(m.MinHigh, h)
if m.SLShort > m.minSLTR+0.01 {
m.SLShort -= m.stepSLTR
}
}
}
func (m *TRS) Calc(s *strat.StratJob, atr float64) (float64, float64) {
m.setTRS(s.Env, len(s.LongOrders), len(s.ShortOrders))
var stopLong, stopShort float64
if m.MaxLow > 0 {
stopLong = m.MaxLow - atr*m.SLLong
}
if m.MinHigh > 0 {
stopShort = m.MinHigh + atr*m.SLShort
}
return stopLong, stopShort
}
func (m *TRS) CalcSL(s *strat.StratJob, atr *ta.Series, lenAtr, lenAtrB int, pow, rate float64) (float64, float64) {
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), lenAtrB).Get(0)
atrRate := math.Pow(atr.Get(0)/atrBase, pow)
return m.Calc(s, atrBase*atrRate*rate)
}
func (m *TRS) CalcSL2(s *strat.StratJob, lenAtr, lenAtrB int, pow, rate float64) (float64, float64) {
e := s.Env
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
return m.CalcSL(s, atr, lenAtr, lenAtrB, pow, rate)
}