Expand description
Incremental state machines for live / streaming bar updates.
§What this is
Pure math state: push one bar at a time, push_bars
for multi-bar payloads, or seed with from_history.
Not a market-data engine — your quant system owns the feed, symbols, and calendars.
§Constructor naming: new → FinanceResult (not try_new)
Fallible construction uses new, matching this crate’s Result-only style
(Schedule::new_repeating, File::open in the standard library — fallibility lives in the
return type, not a try_ prefix). There is no panicking twin.
§What this is not
- No sockets, no multi-symbol registry, no auto “session open”
- Day reset of VWAP/RVOL is your call to
VwapState::reset/ rebuild
§Quant engine sketch — all TA on one symbol, every 5s bar
Desks often want every indicator updated on each bar. That is the intended use of
*State: one pipeline struct per symbol, sequential push (microseconds), and
HashMap<Symbol, Pipeline> + optional rayon across symbols. The crate does not
parallelize indicators for a single bar (shared inputs; overhead dominates).
use finance_solution::stocks::ta::*;
const FAST: StochasticParams = StochasticParams::fast(9, 3);
const MACD: MacdParams = MacdParams::standard();
const BB: BollingerParams = BollingerParams::standard();
/// Caller-owned: pack as many `*State` fields as the strategy needs.
struct SymbolTa {
sma20: SmaState,
ema20: EmaState,
hma16: HmaState,
stoch: StochState,
macd: MacdState,
bb: BollingerState,
atr: AtrState,
rsi: RsiState,
vwap: VwapState,
donchian: DonchianState,
// …add LinReg, RVOL, Keltner, WMA, …
}
impl SymbolTa {
fn new() -> finance_solution::FinanceResult<Self> {
Ok(Self {
sma20: SmaState::new(20)?,
ema20: EmaState::new(20)?,
hma16: HmaState::new(16)?,
stoch: StochState::new(FAST)?,
macd: MacdState::new(MACD)?,
bb: BollingerState::new(BB)?,
atr: AtrState::new(AtrParams::period_14())?,
rsi: RsiState::new(RsiParams::period_14())?,
vwap: VwapState::new(VwapParams::cumulative_typical())?,
donchian: DonchianState::new(DonchianParams::period_20())?,
})
}
fn on_5s_bar(
&mut self,
high: f64,
low: f64,
close: f64,
volume: f64,
) -> finance_solution::FinanceResult<()> {
let _ = self.sma20.push(close)?;
let _ = self.ema20.push(close)?;
let _ = self.hma16.push(close)?;
let _ = self.stoch.push(high, low, close)?;
let _ = self.macd.push(close)?;
let _ = self.bb.push(close)?;
let _ = self.atr.push(high, low, close)?;
let _ = self.rsi.push(close)?;
let _ = self.vwap.push(high, low, close, volume)?;
let _ = self.donchian.push(high, low)?;
Ok(())
}
}
§Parity with batch
Batch free functions and Validated*::compute call the same *State path as live
push (parity by construction). Prefer batch for research notebooks; prefer holding
state for multi-symbol live updates.
Re-exports§
pub use crate::stocks::ta::moving_average::EmaState;pub use crate::stocks::ta::moving_average::SmaState;
Structs§
- Bollinger
BarOutput - One-bar Bollinger output.
- Bollinger
State - Incremental Bollinger Bands.
- Keltner
BarOutput - Keltner
State - Incremental Keltner (EMA mid + Wilder ATR).
- Macd
BarOutput - One-bar MACD output (signal/hist may still be warming up).
- Macd
State - Incremental MACD (fast/slow/signal EMAs).
- Rvol
State - Incremental relative volume.
- Stoch
BarOutput - One-bar stochastic output (warm-up allowed as
None). - Stoch
State - Incremental stochastic (fast/full via
StochasticParams). - Vwap
State - Incremental VWAP (cumulative or rolling). Call
VwapState::resetat session open if desired.