pub mod volatility;
pub mod candle;
pub mod error;
pub mod momentum;
pub mod traits;
pub mod trend;
pub mod utils;
pub mod volume;
pub use self::candle::{heikin_ashi, Candle};
pub use self::error::IndicatorError;
pub use self::traits::{Indicator, PriceDataAccessor};
pub use self::momentum::{Cci, Rsi, StochasticOscillator, StochasticResult, WilliamsR};
pub use self::volatility::{
Atr, BollingerBands, BollingerBandsResult, Donchian, DonchianResult, KeltnerChannels,
KeltnerChannelsResult, Std,
};
pub use self::trend::{
pivot_camarilla, pivot_classic, pivot_fibonacci, Adx, AdxResult, Dema, Ema, Hma, Ichimoku,
IchimokuResult, Macd, MacdResult, PivotResult, Sar, Sma, Tema, Wma,
};
pub use self::volume::{Adl, Cmf, Mfi, Obv, Vroc, Vwap};
pub use self::utils::{
calculate_ema, calculate_sma, rate_of_change, standard_deviation, validate_data_length,
validate_period,
};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_reexported_types() {
let candle = Candle {
timestamp: 1618185600,
open: 100.0,
high: 105.0,
low: 98.0,
close: 103.0,
volume: 1000.0,
};
assert_eq!(candle.open, 100.0);
assert_eq!(candle.high, 105.0);
assert_eq!(candle.low, 98.0);
assert_eq!(candle.close, 103.0);
assert_eq!(candle.volume, 1000.0);
}
#[test]
fn test_sma_calculation() {
let mut sma = Sma::new(3).unwrap();
let prices = vec![2.0, 4.0, 6.0, 8.0, 10.0];
let result = sma.calculate(&prices).unwrap();
assert_eq!(result.len(), 3); assert_eq!(result[0], 4.0); assert_eq!(result[1], 6.0); assert_eq!(result[2], 8.0); }
#[test]
fn test_indicator_next_method() {
let mut sma = Sma::new(3).unwrap();
assert_eq!(sma.next(2.0).unwrap(), None); assert_eq!(sma.next(4.0).unwrap(), None); assert_eq!(sma.next(6.0).unwrap(), Some(4.0)); assert_eq!(sma.next(8.0).unwrap(), Some(6.0)); assert_eq!(sma.next(10.0).unwrap(), Some(8.0)); }
#[test]
fn test_error_handling() {
let error_result = Sma::new(0);
assert!(error_result.is_err());
match error_result {
Err(IndicatorError::InvalidParameter(msg)) => {
assert!(msg.contains("Period must be greater than"));
}
_ => panic!("Expected InvalidParameter error"),
}
}
#[test]
fn test_utility_functions() {
let result = validate_period(10, 5);
assert!(result.is_ok());
let result = validate_period(4, 5);
assert!(result.is_err());
let prices = vec![2.0, 4.0, 6.0, 8.0, 10.0];
let sma_result = calculate_sma(&prices, 3).unwrap();
assert_eq!(sma_result, vec![4.0, 6.0, 8.0]);
}
}