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.
45 lines
1.3 KiB
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
|
|
|
|
} |