rustalib/indicators/momentum/
roc.rs

1use crate::util::dataframe_utils::check_window_size;
2use polars::prelude::*;
3
4/// Calculates Rate of Change (ROC)
5/// Formula: ((price / prevPrice) - 1) * 100
6///
7/// # Arguments
8///
9/// * `df` - DataFrame containing the price data
10/// * `window` - Window size for ROC (typically 10)
11/// * `column` - Column name to use for calculations (default "close")
12///
13/// # Returns
14///
15/// Returns a PolarsResult containing the ROC Series
16pub fn calculate_roc(df: &DataFrame, window: usize, column: &str) -> PolarsResult<Series> {
17    check_window_size(df, window, "ROC")?;
18
19    let price = df.column(column)?.f64()?;
20    let prev_price = price.shift(window as i64);
21
22    let mut roc_values = Vec::with_capacity(df.height());
23
24    for i in 0..df.height() {
25        let current = price.get(i).unwrap_or(0.0);
26        let prev = prev_price.get(i).unwrap_or(0.0);
27
28        if prev != 0.0 {
29            let roc = ((current / prev) - 1.0) * 100.0;
30            roc_values.push(roc);
31        } else {
32            roc_values.push(f64::NAN);
33        }
34    }
35
36    Ok(Series::new("roc".into(), roc_values))
37}