Appearance
FlowRecap
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
A periodic flow recap: option-trade flow aggregated by (symbol, expiration, right) across the whole option chain on a configurable recap window. It sits between two existing analytics in granularity:
- coarser than Option flow, which keys on the full
(symbol, expiration, right, strike)contract and emits one tick per strike per bucket; - finer than the Put-call ratio, which collapses every expiration into one symbol-level ratio.
It answers questions like "how much call vs put premium flowed into SPX's June-26 expiry this window" without the consumer having to sum the per-strike option-flow stream itself.
Per (symbol, expiration, right) bucket, over the recap window, the analytic accumulates the trade count, total_volume (contracts), and total_premium (dollars), plus the Lee-Ready side decomposition — buy / sell / mid volume and premium — and the net directional premium (buy_premium − sell_premium). One tick is emitted per (symbol, expiration, right, window) on window close.
Methodology
Each admitted option trade is classified buyer- / seller- / mid-initiated against the pre-trade NBBO via Lee-Ready (1991) §II.B with a tick-rule fallback for at-mid prints — the same classification path the per-contract option-flow analytic uses, so the side decomposition is consistent between the two analytics:
price >= ask→ buyer-initiated;price <= bid→ seller-initiated;- strictly above / below the NBBO mid → buyer / seller-initiated;
- exactly at the mid → tick-rule fallback against the previous different print for the same contract.
The classified print is accumulated into the (symbol, expiration, right) bucket for the current window. Premium is contract-multiplier adjusted: premium = price × size × 100 (the standard listed-options multiplier). Volume is in contracts. The window boundary follows the configured timeframe, anchored to the session-date midnight so two subscribers agree on every window edge; a session rollover always closes the open window.
References:
- CBOE TradeAlert Flow Recaps and Historical Multi-Day Recaps — periodic aggregated flow grouped by underlying, expiry, and right.
- Lee, C.M.C. & Ready, M.J. "Inferring Trade Direction from Intraday Data". Journal of Finance 46(2), 733-746 (1991).
Inputs
- The admitted option Trade stream sourced from live feed — the flow itself.
- The admitted option Quote stream — the pre-trade NBBO each contract's Lee-Ready classification reads.
Stock and index trades are ignored: the recap groups by (symbol, expiration, right), all of which require an option contract.
Output schema (FlowRecapTick)
The field / type / description table below is regenerated from the FlowRecapTick 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. |
expiration | i32 | Expiration date in YYYYMMDD form. |
right | char | Option right: 'C' (call) or 'P' (put). |
date | i32 | Trading-session date in YYYYMMDD form. |
timeframe | Timeframe | Recap window this snapshot covers. |
bucket_start_ms | i64 | Inclusive start of the window in milliseconds since midnight. |
bucket_end_ms | i64 | Exclusive end of the window in milliseconds since midnight. |
closed | bool | true if the window is closed (one tick per close on [EmitPolicy::OnClose]); false for an intra-window partial snapshot on [EmitPolicy::OnEveryTick]. |
count | u32 | Total trade count in the window across every strike on the (symbol, expiration, right) leg. |
total_volume | u64 | Total volume in the window (contracts). |
total_premium | f64 | Total premium in the window (USD). |
buy_volume | u64 | Buyer-initiated volume (contracts). |
sell_volume | u64 | Seller-initiated volume (contracts). |
mid_volume | u64 | Mid-classified volume (contracts). |
buy_premium | f64 | Buyer-initiated premium (USD). |
sell_premium | f64 | Seller-initiated premium (USD). |
mid_premium | f64 | Mid-classified premium (USD). |
net_directional | f64 | Net directional premium: buy_premium − sell_premium. |
Configuration (FlowRecapRequest)
Regenerated from the FlowRecapRequest Rust source — see the note above.
| Field | Type | Description |
|---|---|---|
contracts | SecurityFilter | Contracts the subscription tracks. The institutional idiom is to subscribe by underlying symbol ([SecurityFilter::Symbols]) — the engine fans out across the chain and the recap groups the resulting flow by (symbol, expiration, right). |
timeframe | Timeframe | Recap window. Defaults to [Timeframe::M1]; common alternatives are [Timeframe::M5] (smoothed recaps) and [Timeframe::H1] (hourly roll-ups). |
emit | EmitPolicy | Whether the analytic emits one tick per closed window ([EmitPolicy::OnClose]) or after every admitted trade ([EmitPolicy::OnEveryTick]). |
conditions | ConditionPolicy | Trade-condition admission policy. Defaults to [ConditionPolicy::OpraRegular] — cancels, openings, late, and halt-rule prints are excluded from the recap. |
venues | ExchangeFilter | Exchange / venue admission policy. Defaults to [ExchangeFilter::Any] — the SIP-consolidated tape. |
classification | SideClassification | Side-classification policy applied to every admitted trade. Defaults to [SideClassification::LeeReady]. |
Operational characteristics
- Per-tick latency. O(1) — one Lee-Ready classification plus one hashed bucket update on the admitted-trade path.
- Emission cadence. One emission per
(symbol, expiration, right, window)— a deep chain does not fan out into one duplicate tick per strike; the analytic de-duplicates so exactly one recap ships per leg per window. - Replay parity. Deterministic given identical input tick order — no wall-clock dependency.
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.