Skip to main content

quant_indicators/
indicator.rs

1//! Core indicator trait definitions.
2//!
3//! These are domain abstractions: pure computation contracts with no I/O.
4//! Concrete implementations live alongside these traits in `quant-indicators`.
5
6use quant_primitives::Candle;
7
8use crate::{IndicatorError, Series};
9
10/// A technical indicator that computes a continuous numeric time series.
11///
12/// All indicators are pure functions - no I/O, no async, no side effects.
13/// This makes them easy to test, compose, and potentially compile to WASM.
14///
15/// For discrete classification outputs (e.g., `VolumeAnomaly`), use
16/// [`ClassificationIndicator<T>`] instead.
17pub trait Indicator: Send + Sync {
18    /// The name of this indicator (e.g., "SMA(20)").
19    #[must_use]
20    fn name(&self) -> &str;
21
22    /// Minimum number of candles required before output is valid.
23    #[must_use]
24    fn warmup_period(&self) -> usize;
25
26    /// Compute the indicator values from candle data.
27    fn compute(&self, candles: &[Candle]) -> Result<Series, IndicatorError>;
28}
29
30/// A classification indicator that maps each candle to a typed domain outcome.
31///
32/// Unlike [`Indicator`] (which produces a continuous `Decimal` series),
33/// `ClassificationIndicator<T>` produces rich domain types (enums, structs).
34///
35/// Returns `None` for candles within the warmup window, and `Some(T)` once
36/// sufficient history is available.
37pub trait ClassificationIndicator<T>: Send + Sync {
38    /// Number of prior candles consumed before first `Some` result is emitted.
39    #[must_use]
40    fn lookback(&self) -> usize;
41
42    /// Classify each candle. Returns one `Option<T>` per input candle.
43    fn compute(&self, candles: &[Candle]) -> Result<Vec<Option<T>>, IndicatorError>;
44}