ta_lib_in_rust/indicators/oscillators/
trix.rs

1use polars::prelude::*;
2
3/// Calculate TRIX (Triple Exponential Average)
4///
5/// Returns a Series with TRIX values
6pub fn calculate_trix(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 ema1 = vec![f64::NAN; len];
10    let mut ema2 = vec![f64::NAN; len];
11    let mut ema3 = vec![f64::NAN; len];
12    let alpha = 2.0 / (period as f64 + 1.0);
13    // First EMA
14    for i in 0..len {
15        if i == 0 {
16            ema1[i] = close.get(i).unwrap_or(f64::NAN);
17        } else {
18            ema1[i] = alpha * close.get(i).unwrap_or(f64::NAN) + (1.0 - alpha) * ema1[i - 1];
19        }
20    }
21    // Second EMA
22    for i in 0..len {
23        if i == 0 {
24            ema2[i] = ema1[i];
25        } else {
26            ema2[i] = alpha * ema1[i] + (1.0 - alpha) * ema2[i - 1];
27        }
28    }
29    // Third EMA
30    for i in 0..len {
31        if i == 0 {
32            ema3[i] = ema2[i];
33        } else {
34            ema3[i] = alpha * ema2[i] + (1.0 - alpha) * ema3[i - 1];
35        }
36    }
37    // TRIX: 1-period percent rate of change of triple EMA
38    let mut trix = vec![f64::NAN; len];
39    for i in 1..len {
40        if ema3[i - 1] != 0.0 {
41            trix[i] = 100.0 * (ema3[i] - ema3[i - 1]) / ema3[i - 1];
42        }
43    }
44    Ok(Series::new("trix".into(), trix))
45}