ta_lib_in_rust/indicators/oscillators/
dpo.rs

1use polars::prelude::*;
2
3/// Calculate Detrended Price Oscillator (DPO)
4///
5/// Returns a Series with DPO values
6pub fn calculate_dpo(df: &DataFrame, close_col: &str, period: usize) -> PolarsResult<Series> {
7    let close = df.column(close_col)?.f64()?;
8    let len = df.height();
9    let mut dpo = vec![f64::NAN; len];
10    let shift = period / 2 + 1;
11
12    for (i, _) in (0..len).enumerate() {
13        if i + 1 >= period {
14            let sma: f64 = close
15                .slice((i + 1 - period) as i64, period)
16                .mean()
17                .unwrap_or(f64::NAN);
18            if i >= shift {
19                dpo[i] = close.get(i - shift).unwrap_or(f64::NAN) - sma;
20            }
21        }
22    }
23    Ok(Series::new("dpo".into(), dpo))
24}