quant-indicators 0.7.0

Pure indicator math library for trading — MA, RSI, Bollinger, MACD, ATR, HRP
Documentation
use rust_decimal::Decimal;
use rust_decimal_macros::dec;

use crate::test_helpers::helpers::{make_candle, ts};
use crate::{Ma, MaType};

fn candles(count: usize) -> Vec<quant_primitives::Candle> {
    (0..count)
        .map(|i| make_candle(dec!(100) + Decimal::from(i), ts(i as i64)))
        .collect()
}

#[test]
fn new_ema_creates_ema_variant() {
    let ma = Ma::new(10, MaType::Ema).unwrap();
    assert!(matches!(ma, Ma::Ema(_)));
}

#[test]
fn new_hull_creates_hull_variant() {
    let ma = Ma::new(10, MaType::Hull).unwrap();
    assert!(matches!(ma, Ma::Hull(_)));
}

#[test]
fn new_sma_creates_sma_variant() {
    let ma = Ma::new(10, MaType::Sma).unwrap();
    assert!(matches!(ma, Ma::Sma(_)));
}

#[test]
fn name_returns_correct_name_for_each_type() {
    let ema = Ma::new(12, MaType::Ema).unwrap();
    assert_eq!(ema.name(), "EMA(12)");

    let hull = Ma::new(20, MaType::Hull).unwrap();
    assert_eq!(hull.name(), "HullMA(20)");

    let sma = Ma::new(50, MaType::Sma).unwrap();
    assert_eq!(sma.name(), "SMA(50)");
}

#[test]
fn to_boxed_returns_working_indicator() {
    let ma = Ma::new(5, MaType::Sma).unwrap();
    let boxed = ma.to_boxed();
    let data = candles(10);
    let series = boxed.compute(&data).unwrap();
    assert!(!series.is_empty());
}

#[test]
fn ma_type_display_ema() {
    assert_eq!(MaType::Ema.to_string(), "EMA");
}

#[test]
fn ma_type_display_hull() {
    assert_eq!(MaType::Hull.to_string(), "Hull");
}

#[test]
fn ma_type_display_sma() {
    assert_eq!(MaType::Sma.to_string(), "SMA");
}

#[test]
fn ma_type_serde_roundtrip() {
    for variant in [MaType::Ema, MaType::Hull, MaType::Sma] {
        let json = serde_json::to_string(&variant).unwrap();
        let deserialized: MaType = serde_json::from_str(&json).unwrap();
        assert_eq!(variant, deserialized);
    }
}

#[test]
fn new_with_zero_period_returns_error() {
    let result = Ma::new(0, MaType::Ema);
    assert!(result.is_err());

    let result = Ma::new(0, MaType::Sma);
    assert!(result.is_err());
}