113c6dfd71
11 funciones puras con implementación real: SMA, EMA, RSI, BollingerBands, VWAP, LogReturn, AnnualizedVolatility, SharpeRatio, MaxDrawdown, NormalizeOHLCV, TickToOHLCV 4 funciones impuras (stubs): FetchOHLCV, StreamTicks, WriteOHLCVToParquet, LoadOHLCVFromDuckDB Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
48 lines
1.1 KiB
Go
48 lines
1.1 KiB
Go
package finance
|
|
|
|
// RSI calcula el Relative Strength Index.
|
|
// Usa el metodo de suavizado de Wilder (EMA con alpha = 1/period).
|
|
// Los primeros period elementos del resultado son 0.
|
|
func RSI(data []float64, period int) []float64 {
|
|
n := len(data)
|
|
result := make([]float64, n)
|
|
if period <= 0 || n < period+1 {
|
|
return result
|
|
}
|
|
var gainSum, lossSum float64
|
|
for i := 1; i <= period; i++ {
|
|
change := data[i] - data[i-1]
|
|
if change > 0 {
|
|
gainSum += change
|
|
} else {
|
|
lossSum -= change
|
|
}
|
|
}
|
|
avgGain := gainSum / float64(period)
|
|
avgLoss := lossSum / float64(period)
|
|
if avgLoss == 0 {
|
|
result[period] = 100
|
|
} else {
|
|
rs := avgGain / avgLoss
|
|
result[period] = 100 - 100/(1+rs)
|
|
}
|
|
for i := period + 1; i < n; i++ {
|
|
change := data[i] - data[i-1]
|
|
var gain, loss float64
|
|
if change > 0 {
|
|
gain = change
|
|
} else {
|
|
loss = -change
|
|
}
|
|
avgGain = (avgGain*float64(period-1) + gain) / float64(period)
|
|
avgLoss = (avgLoss*float64(period-1) + loss) / float64(period)
|
|
if avgLoss == 0 {
|
|
result[i] = 100
|
|
} else {
|
|
rs := avgGain / avgLoss
|
|
result[i] = 100 - 100/(1+rs)
|
|
}
|
|
}
|
|
return result
|
|
}
|