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.
RustyTrader/src/indicators/rsi.rs

45 lines
1.3 KiB

use crate::data::quotes::HOLC;
pub fn relative_strength_index<C: HOLC>(data: Vec<C>, period: usize) -> Vec<f64> {
assert!(data.len() >= period + 2);
let mut rsi_data: Vec<f64> = vec![];
let n = period as f64;
let mut g_avg = 0.0;
let mut l_avg = 0.0;
for (i, d) in data[1..period+1].iter().enumerate() {
let chg = d.close() - data[i].close();
if chg >= 0.0 {g_avg += chg;}
else if chg <= 0.0 { l_avg += chg.abs();}
if i == period -1 {
g_avg /=n;
l_avg /=n;
rsi_data.push(100.0 - (100.0/(1.0+((g_avg)/(l_avg)))));
}
}
// This is magic. Don't touch it. The periods just work.
for (i, d) in data[period+1..].iter().enumerate() {
let chg = d.close() - data[period + i ].close();
if chg > 0.0 {
g_avg = (g_avg * (n - 1.0) + chg) / n;
l_avg = (l_avg * (n - 1.0) + 0.0) / n;
} else if chg < 0.0 {
g_avg = (g_avg * (n - 1.0) + 0.0) / n;
l_avg = (l_avg * (n - 1.0) + chg.abs()) / n;
}
else {
g_avg = (g_avg * (n - 1.0) + 0.0) / n;
l_avg = (l_avg * (n - 1.0) + 0.0) / n;
}
rsi_data.push(100.0 - (100.0/(1.0+((g_avg)/(l_avg)))));
}
rsi_data
}