equity_scanner/utils/
indicators.rs1use crate::equity::InvalidData;
2
3pub fn calculate_rsi(prices: &Vec<f64>, period: usize) -> Result<Vec<f64>, InvalidData> {
4 let mut rsi_values = Vec::new();
5 let mut avg_gain = 0.0;
6 let mut avg_loss = 0.0;
7
8 if prices.len() <= period {
9 return Err(InvalidData);
10 }
11
12 for i in 1..=period {
13 let change = prices[i] - prices[i - 1];
14 if change > 0.0 {
15 avg_gain += change;
16 } else {
17 avg_loss -= change;
18 }
19 }
20
21 avg_gain /= period as f64;
22 avg_loss /= period as f64;
23
24 let first_rsi = 100.0 - (100.0 / (1.0 + (avg_gain / avg_loss)));
25 rsi_values.push(first_rsi);
26
27 for i in (period + 1)..prices.len() {
28 let change = prices[i] - prices[i - 1];
29 let gain = if change > 0.0 { change } else { 0.0 };
30 let loss = if change < 0.0 { -change } else { 0.0 };
31
32 avg_gain = (avg_gain * (period as f64 - 1.0) + gain) / period as f64;
33 avg_loss = (avg_loss * (period as f64 - 1.0) + loss) / period as f64;
34
35 let rs = avg_gain / avg_loss;
36 let rsi = 100.0 - (100.0 / (1.0 + rs));
37 rsi_values.push(rsi);
38 }
39
40 Ok(rsi_values)
41}
42
43pub fn max(sizes: &[usize]) -> usize {
44 *sizes.iter().max().unwrap()
45}