quant_indicators/
momentum.rs1use quant_primitives::Candle;
4
5use crate::error::IndicatorError;
6use crate::indicator::Indicator;
7use crate::series::Series;
8
9#[derive(Debug, Clone)]
34pub struct Momentum {
35 period: usize,
36 name: String,
37}
38
39impl Momentum {
40 pub fn new(period: usize) -> Result<Self, IndicatorError> {
46 if period == 0 {
47 return Err(IndicatorError::InvalidParameter {
48 message: "Momentum period must be > 0".to_string(),
49 });
50 }
51 Ok(Self {
52 period,
53 name: format!("Momentum({})", period),
54 })
55 }
56}
57
58impl Indicator for Momentum {
59 fn name(&self) -> &str {
60 &self.name
61 }
62
63 fn warmup_period(&self) -> usize {
64 self.period + 1
65 }
66
67 fn compute(&self, candles: &[Candle]) -> Result<Series, IndicatorError> {
68 let required = self.period + 1;
69 if candles.len() < required {
70 return Err(IndicatorError::InsufficientData {
71 required,
72 actual: candles.len(),
73 });
74 }
75
76 let mut values = Vec::with_capacity(candles.len() - self.period);
77
78 for i in self.period..candles.len() {
79 let current = candles[i].close();
80 let past = candles[i - self.period].close();
81 let momentum = current - past;
82 values.push((candles[i].timestamp(), momentum));
83 }
84
85 Ok(Series::new(values))
86 }
87}
88
89#[cfg(test)]
90#[path = "momentum_tests.rs"]
91mod tests;