ta_lib_in_rust/indicators/oscillators/
ppo.rs1use polars::prelude::*;
2
3pub fn calculate_ppo(
7 df: &DataFrame,
8 close_col: &str,
9 fast_period: usize,
10 slow_period: usize,
11) -> PolarsResult<Series> {
12 let close = df.column(close_col)?.f64()?;
13 let len = df.height();
14 let mut ema_fast = vec![f64::NAN; len];
15 let mut ema_slow = vec![f64::NAN; len];
16 let alpha_fast = 2.0 / (fast_period as f64 + 1.0);
17 let alpha_slow = 2.0 / (slow_period as f64 + 1.0);
18 for i in 0..len {
19 if i == 0 {
20 ema_fast[i] = close.get(i).unwrap_or(f64::NAN);
21 ema_slow[i] = close.get(i).unwrap_or(f64::NAN);
22 } else {
23 ema_fast[i] = alpha_fast * close.get(i).unwrap_or(f64::NAN)
24 + (1.0 - alpha_fast) * ema_fast[i - 1];
25 ema_slow[i] = alpha_slow * close.get(i).unwrap_or(f64::NAN)
26 + (1.0 - alpha_slow) * ema_slow[i - 1];
27 }
28 }
29 let mut ppo = vec![f64::NAN; len];
30 for i in 0..len {
31 if ema_slow[i] != 0.0 {
32 ppo[i] = 100.0 * (ema_fast[i] - ema_slow[i]) / ema_slow[i];
33 }
34 }
35 Ok(Series::new("ppo".into(), ppo))
36}