You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

146 lines
4.0 KiB

package strategy
import (
"sig-pub/pkg/types"
"sig-pub/pkg/utils/lang"
)
type SupertrendBOSWaves struct {
ISigStrategy
atrLength int16
atrMult float64
// radiusStrength float64
// smoothness int16
prevDirection int
// anchorPrice float64
// anchorBar int
// velocity float64
// barCount int
}
func (s *SupertrendBOSWaves) New() ISigStrategy {
return &SupertrendBOSWaves{}
}
func (s *SupertrendBOSWaves) Meta() StrategyMeta {
return StrategyMeta{
Name: "SupertrendBOSWaves",
Desc: "曲线半径超级趋势 [BOSWaves] https://www.tradingview.com/script/v0Fr7PAb-Curved-Radius-Supertrend-BOSWaves/",
Args: []Param{
{Name: "atrLength", Type: ParamTypeUInt, Desc: "atr指标长度,14"},
{Name: "atrMult", Type: ParamTypeUFloat, Desc: "atr倍数,2"},
{Name: "radiusStrength", Type: ParamTypeUFloat, Desc: `
Controls curve acceleration strength.\n\n" +
"Recommended values by timeframe:\n" +
"• 1-5min (Scalping): 0.08-0.12\n" +
"• 15min: 0.12-0.15\n" +
"• 1H: 0.15-0.18\n" +
"• 4H: 0.18-0.22\n" +
"• Daily: 0.20-0.25\n" +
"• Weekly: 0.25-0.30\n\n" +
"Lower = Tighter curves (responsive)\n" +
"Higher = Wider curves (smoother)
`},
{Name: "smoothness", Type: ParamTypeUInt, Desc: "Smoothing applied to curved band. Higher = smoother curves, less noise."},
},
}
}
func (s *SupertrendBOSWaves) Init(param StrategyParam) (err error) { // 校验参数, 并根据参数初始化策略
if s.atrLength, err = param.GetInt16E("atrLength"); err != nil {
return
}
if s.atrMult, err = param.GetFloat64E("atrMult"); err != nil {
return
}
// if s.radiusStrength, err = param.GetFloat64E("radiusStrength"); err != nil {
// return
// }
// if s.smoothness, err = param.GetInt16E("smoothness"); err != nil {
// return
// }
return
}
func (s *SupertrendBOSWaves) MaxWindow() int {
return int(s.atrLength + 1)
}
func (s *SupertrendBOSWaves) Update(ctx ISigStrategyContext) (side types.Side) {
k0 := ctx.Get(0)
high, low, close := k0.HighF64(), k0.LowF64(), k0.CloseF64()
atr := ctx.IndicatorW("atr", s.atrLength).Get(0)
src := (high + low) / 2
// src := k0.HL2()
upperBand := src + (s.atrMult * atr)
lowerBand := src - (s.atrMult * atr)
supertrend := lowerBand
direction := 1
// Standard supertrend logic
prevSupertrend := supertrend
if direction == 1 {
supertrend = lang.Ternary(close < prevSupertrend, upperBand, max(lowerBand, prevSupertrend))
} else {
supertrend = lang.Ternary(close > prevSupertrend, lowerBand, min(upperBand, prevSupertrend))
}
s.prevDirection = direction
if close < supertrend {
direction = -1
}
if close > supertrend {
direction = 1
}
// ============================================================================
// Curved Radius Implementation
// ============================================================================
// Detect trend change - set new anchor
trendChanged := s.prevDirection != 0 && direction != s.prevDirection
buySignal := trendChanged && direction == 1
sellSignal := trendChanged && direction == -1
if buySignal {
return types.SideLong
}
if sellSignal {
return types.SideShort
}
// if trendChanged {
// s.anchorPrice = supertrend
// s.anchorBar = 0 //bar_index
// s.velocity = 0.0
// s.barCount = 0
// }
// // Increment bar counter
// s.barCount = s.barCount + 1
// // Calculate curved offset using acceleration creating a parabolic curve
// // todo if not na(anchorPrice)
// if trendChanged {
// // Acceleration increases with each bar (quadratic growth)
// s.velocity = s.velocity + (s.radiusStrength * float64(s.barCount))
// }
// // Apply velocity in direction of trend
// if direction == 1 {
// // Uptrend - curve upward with acceleration
// supertrend = s.anchorPrice + s.velocity
// } else {
// // Downtrend - curve downward with acceleration
// supertrend = s.anchorPrice - s.velocity
// }
// Apply smoothing to create flowing curves
// curvedBand = ta.sma(supertrend, s.smoothness)
return
}