use crate::Series;
use std::collections::VecDeque;
pub(crate) fn calculate_rsi(series: &[Series], period: usize) -> VecDeque<f32> {
if series.len() <= period {
return VecDeque::new();
}
let mut gain_sum = 0.0;
let mut loss_sum = 0.0;
for i in 1..=period {
let price_diff = series[i].close - series[i - 1].close;
if price_diff > 0.0 {
gain_sum += price_diff;
} else {
loss_sum += price_diff.abs();
}
}
let mut rsi_values = VecDeque::new();
for i in period..series.len() {
let price_diff = series[i].close - series[i - 1].close;
if price_diff > 0.0 {
gain_sum += price_diff;
} else {
loss_sum += price_diff.abs();
}
let avg_gain = gain_sum / period as f32;
let avg_loss = loss_sum / period as f32;
let rs = if avg_loss != 0.0 {
avg_gain / avg_loss
} else {
f32::INFINITY
};
let rsi = 100.0 - (100.0 / (1.0 + rs));
rsi_values.push_back(rsi);
gain_sum -= gain_sum / period as f32;
loss_sum -= loss_sum / period as f32;
}
for _ in 1..period + 1 {
rsi_values.push_front(0.0);
}
assert!(rsi_values.len() == series.len());
rsi_values
}