86 lines
2.0 KiB
Go
86 lines
2.0 KiB
Go
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)
|
||
}
|