Expand description
§Simple & exponential moving averages (SMA / EMA)
Teaching + production building blocks for price smoothers. Batch APIs
(sma, ema) and incremental APIs (SmaState, EmaState) share one
implementation path: batch is “create state → push_bars”.
§Word problem
A stock closed at 10, 11, 12, 13, 14 over five days. What is the 3-day SMA on day 5?
Expect: (12 + 13 + 14) / 3 = 13.
use finance_solution::stocks::ta::sma;
let closes = [10.0, 11.0, 12.0, 13.0, 14.0];
let s = sma(&closes, 3).unwrap();
// period index: 0 1 2 3 4
// warm-up: None None Some Some Some
assert_eq!(s[0], None);
assert_eq!(s[1], None);
assert!((s[2].unwrap() - 11.0).abs() < 1e-12); // (10+11+12)/3
assert!((s[4].unwrap() - 13.0).abs() < 1e-12); // (12+13+14)/3§Quant pattern — one pack, many symbols
use finance_solution::stocks::ta::{SmaState, EmaState};
// Live: hold state per symbol (your engine's HashMap)
let mut sma20 = SmaState::new(20).unwrap();
let mut ema20 = EmaState::new(20).unwrap();
// One streaming payload with several bars:
let _ = sma20.push_bars(&payload).unwrap();
let _ = ema20.push_bars(&payload).unwrap();
// Or single bar:
let last_sma = sma20.push(101.2).unwrap(); // Option after warm-up§Formulas
SMA over window of length n:
SMA_t = (P_{t-n+1} + … + P_t) / nEMA with span n (α = 2/(n+1)), seed = SMA of first n closes:
EMA_seed = SMA(P_0..P_{n-1})
EMA_t = α * P_t + (1-α) * EMA_{t-1}§Warm-up
Output length = input length. Indices 0 .. n-2 are None until the window is full.
§Related
- Incremental:
SmaState,EmaStateincrate::stocks::ta::state - Used by: Bollinger (SMA mid), Keltner/MACD (EMA)
Structs§
- EmaState
- Incremental EMA (α = 2/(period+1), seed = SMA of first
periodcloses). - SmaState
- Incremental SMA. After warm-up, each
SmaState::pushis O(1).