-
Notifications
You must be signed in to change notification settings - Fork 9
Open
Description
From 微信:阿薛
// SuperTrend 超级趋势指标
// period: ATR周期,通常为10
// multiplier: ATR乘数,通常为3.0
// 返回 [st, upper band, lower band]
// st: 1表示看涨,-1表示看跌
func SuperTrend(high, low, close *ta.Series, period int, multiplier float64) (*ta.Series, *ta.Series, *ta.Series) {
// Create result series with cache key based on period and multiplier
res := close.To("supertrend", period*10+int(multiplier))
if res.Cached() {
return res, res.Cols[0], res.Cols[1]
}
res.LockData.Lock()
if !res.Cached() {
// Calculate ATR (Average True Range)
atr := ta.ATR(high, low, close, period)
// Calculate mid price (High + Low) / 2
midPrice := ta.HL2(high, low)
// Calculate basic upper and lower bands
upperBasic := midPrice.Add(atr.Mul(multiplier))
lowerBasic := midPrice.Sub(atr.Mul(multiplier))
// Create state storage struct to save previous period's bands and trend
type state struct {
prevUpper float64
prevLower float64
trend int
}
// Initialize state
var s state
if m, ok := res.More.(state); ok {
s = m
} else {
// Initial state with NaN and trend 0
s = state{math.NaN(), math.NaN(), 0}
}
// Get current close price
currentClose := close.Get(0)
// Calculate current upper and lower bands
var currentUpper, currentLower float64
// Update bands based on trend and close price
if math.IsNaN(s.prevUpper) || math.IsNaN(s.prevLower) {
// Initial period, use basic bands directly
currentUpper = upperBasic.Get(0)
currentLower = lowerBasic.Get(0)
s.trend = 1 // No initial trend
} else {
var adjustedUpper, adjustedLower float64
if res.Get(0) == -1 { // 这里因为还有没走append,所以0就是上一个
adjustedUpper = math.Min(upperBasic.Get(0), s.prevUpper)
adjustedLower = lowerBasic.Get(0)
} else {
adjustedUpper = upperBasic.Get(0)
adjustedLower = math.Max(lowerBasic.Get(0), s.prevLower)
}
currentLower = adjustedLower
currentUpper = adjustedUpper
if currentClose > adjustedUpper {
// Close breaks above upper band, bullish trend
s.trend = 1
} else if currentClose < adjustedLower {
// Close breaks below lower band, bearish trend
s.trend = -1
} else {
// Maintain previous trend
s.trend = int(res.Get(0))
}
}
// Update state with current values
s.prevUpper = currentUpper
s.prevLower = currentLower
res.More = s
// Append results: trend, upper band, lower band
res.Append([]float64{float64(s.trend), currentUpper, currentLower})
}
res.LockData.Unlock()
return res, res.Cols[0], res.Cols[1]
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels