quant-indicators 0.7.0

Pure indicator math library for trading — MA, RSI, Bollinger, MACD, ATR, HRP
Documentation
use super::*;
use crate::test_helpers::helpers::{make_candle, ts};
use rust_decimal_macros::dec;

#[test]
fn wma_basic() {
    // Period 3: weights are 1, 2, 3. Sum = 6
    let candles: Vec<Candle> = vec![
        make_candle(dec!(10), ts(0)),
        make_candle(dec!(20), ts(1)),
        make_candle(dec!(30), ts(2)),
    ];

    let wma = Wma::new(3).expect("valid WMA period");
    let series = wma.compute(&candles).expect("sufficient data for WMA");

    // WMA = (10*1 + 20*2 + 30*3) / 6 = (10 + 40 + 90) / 6 = 140/6 ≈ 23.33
    let values = series.decimal_values();
    let expected = dec!(140) / dec!(6);
    assert!(
        (values[0] - expected).abs() < dec!(0.01),
        "WMA {} != expected {}",
        values[0],
        expected
    );
}

#[test]
fn wma_emphasizes_recent() {
    // WMA(2) with prices [100, 200]
    // WMA = (100*1 + 200*2) / 3 = 500/3 ≈ 166.67
    // SMA = (100 + 200) / 2 = 150
    // WMA should be > SMA when recent price is higher
    let candles: Vec<Candle> = vec![make_candle(dec!(100), ts(0)), make_candle(dec!(200), ts(1))];

    let wma = Wma::new(2).expect("valid WMA period");
    let series = wma.compute(&candles).expect("sufficient data for WMA");
    let values = series.decimal_values();

    assert!(
        values[0] > dec!(150),
        "WMA {} should be > SMA 150 for recent higher prices",
        values[0]
    );
}

#[test]
fn wma_insufficient_data() {
    let candles: Vec<Candle> = vec![make_candle(dec!(100), ts(0)), make_candle(dec!(102), ts(1))];

    let wma = Wma::new(3).expect("valid WMA period");
    let result = wma.compute(&candles);

    assert!(matches!(
        result,
        Err(IndicatorError::InsufficientData {
            required: 3,
            actual: 2
        })
    ));
}

#[test]
fn wma_period_zero() {
    let result = Wma::new(0);
    assert!(matches!(
        result,
        Err(IndicatorError::InvalidParameter { .. })
    ));
}

#[test]
fn wma_name() {
    let wma = Wma::new(20).expect("valid WMA period");
    assert_eq!(wma.name(), "WMA(20)");
}