Obscura

Options Flow Daily

End-of-day options flow per underlying, aggregated from the full option chain: volume, open interest, notional premium, put/call ratios and implied-volatility summaries.

options_flow_daily — the dataset name to pass to the Obscura API.

Category Markets Columns 18 Refresh Daily Entity key ticker Point-in-time available_date

What one row means

One row is the aggregated end-of-day options-flow summary for a single (ticker, trading day): every per-strike/per-expiry row of that day's end-of-day option chain for that ticker folded into one record of summed call/put volume, open interest, notional premium, put/call ratios, and volume-weighted implied vol. A plain table (not partitioned): ~22M rows over the full history.

One row per (ticker, occurred_on).

Point-in-time availability

Every Obscura dataset carries available_date: the calendar day the publisher made the row available, day-of, with no session rounding. It is the one column a backtest filters on, and it means the same thing on every dataset in the catalog.

For options_flow_daily: released: available_date = occurred_on (the chain's trade day) + 1 business day — the EOD chain is usable the following session; materialized by the collector.

Known limitation

Rolling recent window only; deep options history is not yet collected.

Refresh cadence

Obscura refreshes options_flow_daily daily — the most frequent scheduled job that re-collects or re-exports it. This is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when a row became public is recorded per row in available_date.

Schema — 18 columns

The full public column list for options_flow_daily, with the meaning of every field. The same schema is served unauthenticated at https://api.obscura.trade/v1/catalog/options_flow_daily.

ColumnTypeDescription
tickertext · not nullUnderlying equity ticker symbol, uppercase, as reported on the option chain. Part of the composite key with occurred_on; every strike/expiry for this ticker on the trade date folds into this one row via Aggregator::add.
occurred_ondate · not nullThe trading day this row summarizes, taken from the end-of-day chain snapshot's own dated identity rather than any per-row cell. Composite PK with ticker.
available_datedatePUBLIC-availability date = occurred_on (trade day) + 1 business day (the end-of-day chain is usable the next session); materialized by the collector. The point-in-time column to filter/join on.
stock_pxdouble precisionUnderlying stock's closing price for the day, taken from the first strike row's `stkPx` cell seen for this ticker while streaming the chain (stkPx is constant per ticker/day). NULL if every strike row had an empty stkPx cell.
div_ratedouble precisionUnderlying's annualized dividend rate/yield used as an option pricing-model input, from the chain's `divRate` cell. Constant per ticker/day, so taken from the first strike row seen for this ticker while streaming the CSV (same convention as stock_px). NULL if every strike row had an empty divRate cell.
i_ratedouble precisionRisk-free interest rate used in the chain's option pricing, from the `iRate` cell. Effectively market-wide per day; taken from the first row seen for this ticker (same convention as stock_px). NULL if every strike row had an empty iRate cell.
call_volumebigint · not nullSum of `cVolu` (call contract trading volume) across every strike/expiry row for this ticker/day. Missing/empty cells contribute 0, not NULL, to the sum.
put_volumebigint · not nullSum of `pVolu` (put contract trading volume) across every strike/expiry row for this ticker/day; empty cells contribute 0.
call_oibigint · not nullSum of `cOi` (call open interest, contracts outstanding as of that day's close) across every strike/expiry row for this ticker/day.
put_oibigint · not nullSum of `pOi` (put open interest) across every strike/expiry row for this ticker/day.
call_premiumdouble precision · not nullNotional dollar premium traded on calls: Σ over strikes of (cVolu × cValue × 100), where cValue is the chain's theoretical/mid option value used as the price proxy and 100 is the standard contract share multiplier. Strikes with 0 volume contribute 0 regardless of cValue.
put_premiumdouble precision · not nullNotional dollar premium traded on puts: Σ over strikes of (pVolu × pValue × 100), the put-side analogue of call_premium.
put_call_volume_ratiodouble precisionput_volume / call_volume for the ticker/day. NULL only when call_volume is 0 (undefined denominator); a nonzero call_volume with zero put_volume yields the literal value 0.0, not NULL.
put_call_oi_ratiodouble precisionput_oi / call_oi for the ticker/day. NULL only when call_oi is 0; otherwise 0.0 or a positive ratio, same convention as put_call_volume_ratio.
avg_call_ivdouble precisionVolume-weighted average call implied volatility: Σ(cVolu × cMidIv) / Σ cVolu across all call strikes for the ticker/day. NULL when call_volume is 0 — there is no volume to weight by.
avg_put_ivdouble precisionVolume-weighted average put implied volatility: Σ(pVolu × pMidIv) / Σ pVolu across all put strikes for the ticker/day. NULL when put_volume is 0.
num_strikesinteger · not nullCount of raw per-strike/expiry CSV rows folded into this ticker/day. Each row already carries both the call and put side of one strike/expiry combination, so this is strikes×expiries seen, not a distinct-strike-price count.
num_expiriesinteger · not nullCount of distinct option expiration dates (`expirDate`) observed across this ticker's strikes on the day — how many expiry cycles were actively quoted/traded.

Access options_flow_daily

Two delivery paths, one identifier. Both require an Obscura account and an active subscription; the catalog entry and the schema above are public.

import obscura

client = obscura.Client("obs_live_…")

df = client.query(
    dataset="options_flow_daily",
    symbols=["NVDA", "AAPL"],
    start="2024-01-01",
)

Create a free account Browse all 95 datasets

Frequently asked questions

What is in the options_flow_daily dataset?

End-of-day options flow per underlying, aggregated from the full option chain: volume, open interest, notional premium, put/call ratios and implied-volatility summaries. One row is the aggregated end-of-day options-flow summary for a single (ticker, trading day): every per-strike/per-expiry row of that day's end-of-day option chain for that ticker folded into one record of summed call/put volume, open interest, notional premium, put/call ratios, and volume-weighted implied vol. A plain table (not partitioned): ~22M rows over the full history.

How do I avoid look-ahead bias with options_flow_daily?

Filter on options_flow_daily.available_date, the day the publisher made the row public. For this dataset that date is derived as follows — released: available_date = occurred_on (the chain's trade day) + 1 business day — the EOD chain is usable the following session; materialized by the collector. A query of the form WHERE available_date <= '<as-of date>' never sees a row before it existed.

In what formats can I get options_flow_daily?

As a Parquet bulk export (POST https://api.obscura.trade/v1/download) or as JSON from the typed query API (POST https://api.obscura.trade/v1/query), both with dataset="options_flow_daily". The column schema is public at https://api.obscura.trade/v1/catalog/options_flow_daily.

Can I filter options_flow_daily by company or symbol?

Yes. options_flow_daily carries ticker, the column the API's symbols filter resolves against.

Is options_flow_daily complete?

Not yet, and the limitation is declared rather than hidden: Rolling recent window only; deep options history is not yet collected.

How often is options_flow_daily updated?

Obscura refreshes options_flow_daily on a daily schedule — that is the most frequent scheduled job that re-collects or re-exports the table. It is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when the publisher makes a row available is described by the availability rule above, and is recorded per row in available_date.

Related datasets

Cboe IndicesDaily history of Cboe's volatility indices, including VIX, sourced directly from Cboe. Crypto MarketsPer-coin market data from CoinGecko: price, market cap and volume across thousands of cryptocurrencies. DeFiLlama ProtocolsTotal value locked in each DeFi protocol, tracked by DeFiLlama. DeFiLlama StablecoinsCirculating supply of each stablecoin over time, from DeFiLlama. DeFiLlama TVLTotal value locked on each blockchain, from DeFiLlama. Flow MetricsTrade-flow metrics per symbol in fixed time windows: taker (aggressor) buy versus sell volume and trade counts, broken o… Forex OrderbookOANDA's order book and position book by currency pair: where retail traders' open orders and positions sit relative to p… Forex PositionsRetail forex positioning by pair (share of traders long versus short), collected from several broker sentiment feeds.