ta_lib_in_rust/indicators/volume/
adl.rs

1use polars::prelude::*;
2
3/// Calculate Accumulation/Distribution Line (ADL)
4///
5/// Returns a Series with ADL values
6pub fn calculate_adl(
7    df: &DataFrame,
8    high_col: &str,
9    low_col: &str,
10    close_col: &str,
11    volume_col: &str,
12) -> PolarsResult<Series> {
13    let high = df.column(high_col)?.f64()?;
14    let low = df.column(low_col)?.f64()?;
15    let close = df.column(close_col)?.f64()?;
16    let volume = df.column(volume_col)?.f64()?;
17    let len = df.height();
18    let mut adl = vec![0.0; len];
19    for i in 0..len {
20        let high = high.get(i).unwrap_or(f64::NAN);
21        let low = low.get(i).unwrap_or(f64::NAN);
22        let close = close.get(i).unwrap_or(f64::NAN);
23        let volume = volume.get(i).unwrap_or(f64::NAN);
24        let mf_multiplier = if (high - low).abs() < f64::EPSILON {
25            0.0
26        } else {
27            ((close - low) - (high - close)) / (high - low)
28        };
29        let mf_volume = mf_multiplier * volume;
30        adl[i] = if i == 0 {
31            mf_volume
32        } else {
33            adl[i - 1] + mf_volume
34        };
35    }
36    Ok(Series::new("adl".into(), adl))
37}