44 lines
1011 B
Go
44 lines
1011 B
Go
package indicators
|
|
|
|
// RSI calcule le Relative Strength Index (Wilder's smoothing, période 14).
|
|
// Retourne NaN si pas assez de données.
|
|
func RSI(closes []float64, period int) float64 {
|
|
if period <= 0 {
|
|
period = 14
|
|
}
|
|
if len(closes) < period+1 {
|
|
return -1
|
|
}
|
|
|
|
var gains, losses float64
|
|
for i := 1; i <= period; i++ {
|
|
delta := closes[i] - closes[i-1]
|
|
if delta > 0 {
|
|
gains += delta
|
|
} else {
|
|
losses -= delta
|
|
}
|
|
}
|
|
|
|
avgGain := gains / float64(period)
|
|
avgLoss := losses / float64(period)
|
|
|
|
// Wilder's smoothing pour le reste
|
|
for i := period + 1; i < len(closes); i++ {
|
|
delta := closes[i] - closes[i-1]
|
|
if delta > 0 {
|
|
avgGain = (avgGain*float64(period-1) + delta) / float64(period)
|
|
avgLoss = (avgLoss * float64(period-1)) / float64(period)
|
|
} else {
|
|
avgGain = (avgGain * float64(period-1)) / float64(period)
|
|
avgLoss = (avgLoss*float64(period-1) - delta) / float64(period)
|
|
}
|
|
}
|
|
|
|
if avgLoss == 0 {
|
|
return 100
|
|
}
|
|
rs := avgGain / avgLoss
|
|
return 100 - (100 / (1 + rs))
|
|
}
|