ta_lib_in_rust/indicators/moving_averages/
hull.rs

1use polars::prelude::*;
2
3/// Calculate Hull Moving Average
4///
5/// HMA = WMA(2*WMA(n/2) - WMA(n)), sqrt(n)
6pub fn calculate_hma(df: &DataFrame, column: &str, period: usize) -> PolarsResult<Series> {
7    // Calculate half period
8    let half_period = period / 2;
9
10    // Calculate WMA with period and half period
11    let wma_full = super::wma::calculate_wma(df, column, period)?;
12    let wma_half = super::wma::calculate_wma(df, column, half_period)?;
13
14    // Calculate 2 * WMA(half period) - WMA(full period)
15    let raw_hma = wma_half
16        .multiply(&Series::new("mult".into(), &[2.0f64]))?
17        .subtract(&wma_full)?;
18
19    // Create a temporary dataframe with the raw_hma
20    let temp_df = DataFrame::new(vec![raw_hma.clone().into()])?;
21
22    // Calculate WMA of the result with period = sqrt(n)
23    let sqrt_period = (period as f64).sqrt().round() as usize;
24    super::wma::calculate_wma(&temp_df, raw_hma.name(), sqrt_period)
25}