Appearance
TechnicalIndicators
Preview on the public Rust client. The analytic ships in the engine and is reachable today through the Python wheel and the TypeScript / Node addon; a per-analytic builder on the public Rust thin client (
kairos::Client) is tracked on the roadmap. The output tick schema below is stable.
What it computes
The six classic technical indicators per symbol, emitted on a bar cadence. Technical indicators run on bars (OHLCV), not raw ticks, so the analytic builds its own bars internally from the admitted stock-trade stream and feeds each closed bar's (high, low, close, volume) to six stateful indicators:
ema— exponential moving average of the bar close.sma— simple moving average of the bar close.rsi— Wilder's Relative Strength Index of the bar close.macd/macd_signal/macd_histogram— moving-average convergence / divergence of the bar close (standard 12 / 26 / 9).mfi— Money Flow Index over(high, low, close, volume).aroon_up/aroon_down— Aroon Up / Aroon Down over(high, low).
One tick is emitted per closed bar. Each indicator returns a non-finite value during its warm-up window; the tick carries a warming flag that is true while ANY of the six outputs is still non-finite. Consumers gate on warming rather than NaN-probing every field.
Methodology
Standard, textbook indicator definitions:
- EMA —
EMA_t = close_t × k + EMA_{t-1} × (1 − k),k = 2 / (period + 1), seeded from the first SMA window. - SMA — arithmetic mean of the last
periodbar closes. - RSI — Wilder's smoothing:
RSI = 100 − 100 / (1 + RS)whereRS = avg_gain / avg_lossoverperiodprice deltas. - MACD —
macd = EMA(close, 12) − EMA(close, 26),signal = EMA(macd, 9),histogram = macd − signal. - MFI —
MFI = 100 − 100 / (1 + positive_flow / negative_flow)where flows are typical-price × volume bucketed by directional move overperiodbars. - Aroon —
aroon_up = 100 × (period − bars_since_high) / period,aroon_down = 100 × (period − bars_since_low) / period.
Bar construction follows the same SIP consolidated-tape rules the OHLCVC analytic uses: open / close anchoring, per-field high / low / volume eligibility, out-of-sequence HLC skip, and a session-rollover flush. A bar that takes only a volume-only print (non-finite close) is skipped rather than fed to the indicators, so an opening cross never poisons an indicator's seeding window.
Inputs
- The admitted stock-trade stream sourced from live feed. Bars are aggregated internally on the configured timeframe, so no separate bar subscription is required.
Technical indicators are conventionally computed on stocks / ETFs, so option / index / rate trades are silently ignored.
Output schema (TechnicalIndicatorsTick)
The field / type / description table below is regenerated from the TechnicalIndicatorsTick Rust source by docs-site/scripts/inject-doc-tables.ts on every npm run docs:build. Do not hand-edit between the sentinels.
| Field | Type | Description |
|---|---|---|
symbol | Arc<str> | Underlying symbol (interned). |
date | i32 | Session date of the bar that just closed (YYYYMMDD). |
ms_of_day | i64 | Bar-close time, in milliseconds since midnight ET (the closed bucket's exclusive upper edge). |
ema | f64 | Exponential moving average of the bar close. NaN until the EMA's seeding window has filled. |
sma | f64 | Simple moving average of the bar close. NaN until the SMA window has filled. |
rsi | f64 | Wilder's RSI of the bar close, in [0, 100]. NaN until the RSI has seen rsi_period price deltas. |
macd | f64 | MACD line — EMA(close, 12) − EMA(close, 26). NaN until both EMAs have seeded. |
macd_signal | f64 | MACD signal line — EMA(macd, 9). NaN until the signal EMA has seeded. |
macd_histogram | f64 | MACD histogram — macd − macd_signal. NaN until both the MACD and signal lines are finite. |
mfi | f64 | Money Flow Index over (high, low, close, volume), in [0, 100]. NaN until mfi_period + 1 bars have closed. |
aroon_up | f64 | Aroon Up, in [0, 100]. NaN until aroon_period + 1 bars have closed. |
aroon_down | f64 | Aroon Down, in [0, 100]. NaN until aroon_period + 1 bars have closed. |
warming | bool | true while ANY of the six indicators is still in its warm-up window (i.e. any of the outputs above is non-finite). Consumers gate on this flag instead of NaN-probing every field. Mirrors the warming convention the volume-anomaly / open-interest analytics use for their first emissions. |
Configuration (TechnicalIndicatorsRequest)
Regenerated from the TechnicalIndicatorsRequest Rust source — see the note above.
| Field | Type | Description |
|---|---|---|
contracts | SecurityFilter | Contracts the subscription tracks. Stocks only. |
timeframe | Timeframe | Bar period the indicators run on. Default [Timeframe::M1] — the SIP / ThetaData hosted 1-minute bar grid most consumers reconcile against. Reuses the same [Timeframe] type the OHLCVC analytic uses, so the bar boundaries align across both. |
conditions | ConditionPolicy | Trade-condition admission policy. Default [ConditionPolicy::OpraRegular]. |
venues | ExchangeFilter | Exchange / venue admission policy. Default [ExchangeFilter::Any]. |
ema_period | usize | EMA period. Default [DEFAULT_EMA_PERIOD] (12). |
sma_period | usize | SMA period. Default [DEFAULT_SMA_PERIOD] (20). |
rsi_period | usize | RSI period. Default [DEFAULT_RSI_PERIOD] (14). |
mfi_period | usize | MFI period. Default [DEFAULT_MFI_PERIOD] (14). |
aroon_period | usize | Aroon period. Default [DEFAULT_AROON_PERIOD] (25). |
Operational characteristics
- Per-tick latency. O(1) amortised — one bar-fold per trade, plus six single-pass indicator admissions on bar close.
- Allocation discipline. The per-symbol analytic instance holds the in-progress bar accumulator and the six indicator windows; no hot-path allocations in steady state.
- Emission cadence. One emission per closed bar per symbol on the configured timeframe (default 1 minute).
- Replay parity. Deterministic given identical input tick order.
Example
Preview. This analytic ships in the engine and is reachable today through the Python wheel and the TypeScript / Node addon. A per-analytic builder on the public Rust thin client (
kairos::Client) is tracked on the roadmap — bare-string symbol filters passed to the analytic accessor will match the other analytics already exposed there. The output tick rows are stable and documented above.