Appearance
Technical indicators
What they do
Six stateful primitives composing against any bar stream — typically the engine's Ohlcvc output:
| Indicator | Surface | Reference |
|---|---|---|
Ema | Exponential moving average. | Hull, Options, Futures, and Other Derivatives, §22. |
Sma | Simple moving average. | Standard. |
Rsi | Wilder's Relative Strength Index. | Wilder (1978), New Concepts in Technical Trading Systems. |
Macd | Moving Average Convergence Divergence. | Appel (1979). |
Mfi | Money Flow Index. | Standard volume-weighted RSI variant. |
Aroon | Aroon Up / Aroon Down. | Chande (1995). |
Admission contract
Each primitive exposes a small admit surface and stays single-pass per admission. The math is deterministic by construction.
rust
let mut ema = Ema::new(20);
let value = ema.admit(bar.close); // `admit` returns the current EMA valueEma::admit returns the running EMA value directly — there is no separate value() accessor. Other indicators in the namespace expose sample-typed return values:
Rsi::admit(price) -> f64Mfi::admit(typical, volume) -> f64Macd::admit(price) -> MacdSample(macd / signal / histogram)Aroon::admit(high, low) -> AroonSample(up / down)Sma::admit(value) -> f64
Mfi correctness
Mfi requires period + 1 admissions before emitting a finite value. Earlier implementations seeded the window with a zero signed-flow on the first bar (no prior typical price to compare against), so the first finite emission was computed off period − 1 real directional flows plus one zero — systematically understated by one bar. The current implementation drops the zero-seed: the first admission only seeds last_typical, the history admits only flows derived against a prior typical.
Replay parity
Each primitive holds its own state and is deterministic. Feed the same bar sequence twice; the indicator emits the same values.
Why primitives
Technical indicators are common downstream consumers. Factoring the six core indicators into the analytics::common::indicators namespace gives every consumer a vetted single-pass implementation without each analytic re-rolling its own EMA / SMA loop.