Obscura

Flow Metrics

Trade-flow metrics per symbol in fixed time windows: taker (aggressor) buy versus sell volume and trade counts, broken out by order size.

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

Category Markets Columns 126 Refresh Every 6 hours Entity key symbol Point-in-time available_date

What one row means

One row is the finalized set of ~119 derived order-flow microstructure factors for one equity symbol over one aggregation bucket (currently only daily, bucket_seconds=86400): every top-of-book trade print during that bucket is aggressor-classified (quote-rule with tick-rule fallback) and folded into taker buy/sell flow, order-size composition, price/tick distributions, volatility, impact/slippage, run-structure, and order-flow-imbalance factors, plus a cross-bar flow_toxicity_score.

One row per (symbol, bucket_seconds, event_time).

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 flow_metrics: published: available_date = date(event_time) — the session's own day. WHY: event_time marks the START of the daily bucket, i.e. the trading session the bar aggregates, and the session's order flow is available on the session day itself. So the day the data was published is the session day, and that is what this column records. WHAT IT IS NOT: this was previously date(event_time) + 1, on two arguments that are both rejected. (a) 'the bar only settles after the close, so it is a T+1 fact' — an availability date is the day the publisher published, never an adjustment for when a consumer could act; the next tradeable session is always derivable forward from this date, and is never recoverable once a lag has been baked in. (b) 'the vendor file's last_modified_date lands on session+1' — an mtime is evidence about a filesystem, not about publication, and it moves for unrelated reasons (a site migration once touched 257 SEC FTD files to one 2020 date, which would have dated 11 years of history 11.5 years late). Corrected by migration m20260702_000204.

Refresh cadence

Obscura refreshes flow_metrics every 6 hours — 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 — 126 columns

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

ColumnTypeDescription
symboltext · not nullEquity ticker symbol (uppercase), resolved from the source feed's raw-symbol map at decode time. Part of the primary key.
bucket_secondsinteger · not nullAggregation bucket width in seconds; defaults to 86400 (daily bars) and is the only value the scheduled collector produces today. Part of the primary key.
event_timetimestamp with time zone · not nullUTC midnight timestamp marking the START of the bucket (the trading day/session the bar aggregates). Renamed from bucket_start. Part of the primary key with symbol + bucket_seconds; source column for the generated available_date column.
datasettext · not nullInternal feed code identifying which consolidated equities tape the bar was built from; constant for a given collection run and carried for lineage.
taker_buy_volumedouble precision · not nullTotal traded quantity (shares) across prints where the aggressor (price-crossing taker) was classified Buy via the quote rule (price vs. BBO mid) with tick-rule fallback.
taker_sell_volumedouble precision · not nullTotal traded quantity (shares) across prints classified taker-Sell.
taker_buy_countbigint · not nullNumber of individual tbbo prints classified taker-Buy in the bucket.
taker_sell_countbigint · not nullNumber of individual tbbo prints classified taker-Sell in the bucket.
volume_deltadouble precision · not nullNet signed taker volume in shares: taker_buy_volume − taker_sell_volume.
volume_delta_notionaldouble precision · not nullNet signed taker flow in dollars (buy_notional − sell_notional). Feeds flow_toxicity_score as one of its two z-scored inputs.
flow_entropydouble precision · not nullShannon entropy (nats) of the {buy, sell} volume split. Low ⇒ concentrated, one-sided flow; higher (max ln2) ⇒ balanced buy/sell activity.
taker_buy_sell_ratiodouble precision · not nulltaker_buy_volume / taker_sell_volume — volume-weighted buy/sell skew.
taker_buy_sell_count_ratiodouble precision · not nulltaker_buy_count / taker_sell_count — print-count buy/sell skew.
taker_buy_sell_percentagedouble precision · not nulltaker_buy_volume as a share (0-1) of (taker_buy_volume + taker_sell_volume).
taker_buy_sell_count_percentagedouble precision · not nulltaker_buy_count as a share (0-1) of (taker_buy_count + taker_sell_count).
taker_buy_small_order_volumedouble precision · not nullNOTIONAL DOLLARS from taker-Buy prints whose per-print notional is < $100. Despite the `_volume` suffix this is money, not shares: the collector sums `price * size` per print into the size buckets. Dividing it by `taker_buy_volume` (which IS shares) yields a number that just tracks the share price — compare against `buy_notional`-scaled quantities instead.
taker_buy_small_order_countbigint · not nullCount of taker-Buy prints with per-print notional < $100.
taker_buy_medium_order_volumedouble precision · not nullNotional DOLLARS from taker-Buy prints with per-print notional in [$100, $1000). Money, not shares — see `taker_buy_small_order_volume`.
taker_buy_medium_order_countbigint · not nullCount of taker-Buy prints with per-print notional in [$100, $1000).
taker_buy_large_order_volumedouble precision · not nullNotional DOLLARS from taker-Buy prints with per-print notional ≥ $1000. Money, not shares — see `taker_buy_small_order_volume`.
taker_buy_large_order_countbigint · not nullCount of taker-Buy prints with per-print notional ≥ $1000.
taker_sell_small_order_volumedouble precision · not nullNotional DOLLARS from taker-Sell prints with per-print notional < $100. Money, not shares — see `taker_buy_small_order_volume`.
taker_sell_small_order_countbigint · not nullCount of taker-Sell prints with per-print notional < $100.
taker_sell_medium_order_volumedouble precision · not nullNotional DOLLARS from taker-Sell prints with per-print notional in [$100, $1000). Money, not shares — see `taker_buy_small_order_volume`.
taker_sell_medium_order_countbigint · not nullCount of taker-Sell prints with per-print notional in [$100, $1000).
taker_sell_large_order_volumedouble precision · not nullNotional DOLLARS from taker-Sell prints with per-print notional ≥ $1000. Money, not shares — see `taker_buy_small_order_volume`.
taker_sell_large_order_countbigint · not nullCount of taker-Sell prints with per-print notional ≥ $1000.
taker_buy_large_order_percentagedouble precision · not nulltaker_buy_large_order_volume as a share (0-1) of taker-buy NOTIONAL — how much buy flow is institutional-sized. Dollars over dollars, so this ratio is sound; the denominator is buy notional, NOT `taker_buy_volume`.
taker_sell_large_order_percentagedouble precision · not nulltaker_sell_large_order_volume as a share (0-1) of taker-sell NOTIONAL (dollars over dollars).
large_order_volumedouble precision · not nullCombined large-order (≥$1000 notional) DOLLARS across both sides: taker_buy_large_order_volume + taker_sell_large_order_volume.
trade_countbigint · not nullTotal number of tbbo prints (both sides) in the bucket; legacy name for n_trades in the factor catalog. Same underlying count as n_prints.
mean_trade_sizedouble precision · not nullMean per-print notional ($) across all prints in the bucket. Trade-size basis is dollar notional, not share quantity.
trade_size_skewnessdouble precision · not nullSkewness of the per-print notional ($) distribution; high ⇒ a few outsized prints dominate the bar's flow.
range_bpsdouble precision · not nullIntrabar (high − low) / mean_price, in basis points — normalized trading range.
mean_pricedouble precision · not nullArithmetic (unweighted) mean of trade prices across all prints in the bucket.
price_stddouble precision · not nullStandard deviation of trade prices across prints in the bucket.
price_skewnessdouble precision · not nullSkewness of the intrabar trade-price distribution.
price_kurtosisdouble precision · not nullKurtosis of the intrabar trade-price distribution.
price_cvdouble precision · not nullCoefficient of variation of price: price_std / mean_price. Scale-free price dispersion, comparable across symbols at very different price levels.
vwapdouble precision · not nullNotional-weighted average trade price across the bucket: sum(price×size)/sum(size).
opendouble precision · not nullFirst trade price recorded in the bucket.
highdouble precision · not nullMaximum trade price recorded in the bucket.
lowdouble precision · not nullMinimum trade price recorded in the bucket.
closedouble precision · not nullLast trade price recorded in the bucket.
uptick_volumedouble precision · not nullVolume (shares) traded on prints whose price rose vs. the immediately preceding print (tick rule).
downtick_volumedouble precision · not nullVolume (shares) traded on prints whose price fell vs. the immediately preceding print.
unchanged_volume_pctdouble precision · not nullZero-tick volume as a share (0-1) of ALL tick volume (uptick + downtick + unchanged). Legacy pre-existing column.
uptick_volume_pctdouble precision · not nulluptick_volume / (uptick_volume + downtick_volume) — legacy column; denominator EXCLUDES unchanged-tick volume, unlike the newer *_percentage siblings below.
uptick_count_pctdouble precision · not nulluptick_count / (uptick_count + downtick_count) — legacy column; denominator excludes unchanged-tick prints.
uptick_downtick_volume_ratiodouble precision · not nulluptick_volume / downtick_volume.
uptick_downtick_count_ratiodouble precision · not nulluptick_count / downtick_count.
realized_voldouble precision · not nullRealized volatility: sqrt(Σ r_t²) over intrabar log returns between consecutive prints. Feeds flow_toxicity_score as its second z-scored input.
bipower_variationdouble precision · not null(π/2)·Σ|r_t||r_t-1| — the jump-robust (continuous) component of realized variation (Barndorff-Nielsen & Shephard).
jump_ratiodouble precision · not nullmax(0, (realized_vol² − bipower_variation) / realized_vol²) — the fraction of the bar's variance attributable to price jumps rather than continuous diffusion.
trendinessdouble precision · not nullDirectional efficiency of the intrabar price path: |Σ r_t| / Σ|r_t|. 1 ⇒ pure trend, 0 ⇒ pure chop.
amihud_illiquiditydouble precision · not nullAmihud (2002) illiquidity: |bar log-return| / dollar volume traded in the bucket. Higher ⇒ price moves more per dollar of gross flow (less liquid).
kyle_lambdadouble precision · not nullKyle's λ price-impact coefficient: slope of per-print price change on signed trade size, Σ(Δp·q)/Σq². Higher ⇒ more price impact per unit of signed order flow.
vwap_slippage_bpsdouble precision · not nullSigned gap between the simple mean print price and VWAP, in bps: (mean_price − vwap)/vwap × 10,000. A VWAP-dispersion proxy requiring no quote data.
slippage_std_bpsdouble precision · not nullStandard deviation of print prices around their mean, expressed in bps of VWAP.
max_buy_run_lengthbigint · not nullLongest consecutive streak of taker-Buy-classified prints in the bucket (run-length in trade count).
max_sell_run_lengthbigint · not nullLongest consecutive streak of taker-Sell-classified prints in the bucket.
flip_ratedouble precision · not nullFraction of prints where the aggressor side flips vs. the immediately preceding print (flip_count / total prints).
price_change_on_flipdouble precision · not nullMean absolute price move at the moment the aggressor side flips.
taker_buy_small_order_percentagedouble precision · not nulltaker_buy_small_order_volume as a share (0-1) of taker-buy NOTIONAL (dollars over dollars).
taker_buy_medium_order_percentagedouble precision · not nulltaker_buy_medium_order_volume as a share (0-1) of taker-buy NOTIONAL (dollars over dollars).
taker_sell_small_order_percentagedouble precision · not nulltaker_sell_small_order_volume as a share (0-1) of taker-sell NOTIONAL (dollars over dollars).
taker_sell_medium_order_percentagedouble precision · not nulltaker_sell_medium_order_volume as a share (0-1) of taker-sell NOTIONAL (dollars over dollars).
taker_buy_small_order_count_percentagedouble precision · not nulltaker_buy_small_order_count as a share (0-1) of taker_buy_count.
taker_buy_medium_order_count_percentagedouble precision · not nulltaker_buy_medium_order_count as a share (0-1) of taker_buy_count.
taker_buy_large_order_count_percentagedouble precision · not nulltaker_buy_large_order_count as a share (0-1) of taker_buy_count.
taker_sell_small_order_count_percentagedouble precision · not nulltaker_sell_small_order_count as a share (0-1) of taker_sell_count.
taker_sell_medium_order_count_percentagedouble precision · not nulltaker_sell_medium_order_count as a share (0-1) of taker_sell_count.
taker_sell_large_order_count_percentagedouble precision · not nulltaker_sell_large_order_count as a share (0-1) of taker_sell_count.
small_order_volumedouble precision · not nullCombined (buy+sell) NOTIONAL DOLLARS from prints with per-print notional < $100: taker_buy_small_order_volume + taker_sell_small_order_volume.
small_order_countbigint · not nullCombined (buy+sell) count of prints with per-print notional < $100.
medium_order_volumedouble precision · not nullCombined (buy+sell) NOTIONAL DOLLARS from prints with per-print notional in [$100, $1000).
medium_order_countbigint · not nullCombined (buy+sell) count of prints with per-print notional in [$100, $1000).
large_order_countbigint · not nullCombined (buy+sell) count of prints with per-print notional ≥ $1000.
volumedouble precision · not nullTotal traded quantity (shares) across all prints in the bucket, both sides: taker_buy_volume + taker_sell_volume.
small_order_percentagedouble precision · not nullsmall_order_volume as a share (0-1) of `dollar_volume` — dollars over dollars, NOT of `volume` (shares).
medium_order_percentagedouble precision · not nullmedium_order_volume as a share (0-1) of `dollar_volume` — dollars over dollars, NOT of `volume` (shares).
large_order_percentagedouble precision · not nulllarge_order_volume as a share (0-1) of `dollar_volume` — dollars over dollars, NOT of `volume` (shares).
small_order_count_percentagedouble precision · not nullsmall_order_count as a share (0-1) of trade_count.
medium_order_count_percentagedouble precision · not nullmedium_order_count as a share (0-1) of trade_count.
large_order_count_percentagedouble precision · not nulllarge_order_count as a share (0-1) of trade_count.
trade_amount_mediandouble precision · not nullMedian per-print notional ($) in the bucket. Streaming P² estimate — exact below 5 prints, ~1-2% error on well-mixed streams.
trade_amount_stddouble precision · not nullStandard deviation of per-print notional ($) across the bucket.
trade_amount_variancedouble precision · not nullVariance of per-print notional ($) across the bucket.
trade_amount_kurtosisdouble precision · not nullKurtosis of the per-print notional ($) distribution.
trade_amount_mindouble precision · not nullSmallest per-print notional ($) observed in the bucket (0 if no prints).
trade_amount_maxdouble precision · not nullLargest per-print notional ($) observed in the bucket (0 if no prints).
trade_amount_range_ratiodouble precision · not nulltrade_amount_max / trade_amount_min — spread of print sizes traded in the bucket.
trade_amount_cvdouble precision · not nullCoefficient of variation of per-print notional: trade_amount_std / mean_trade_size.
price_mediandouble precision · not nullMedian trade price across prints in the bucket.
price_variancedouble precision · not nullVariance of trade prices across prints in the bucket (price_std squared).
rangedouble precision · not nullRaw intrabar trading range in price units: high − low.
price_range_ratiodouble precision · not nullhigh / low — multiplicative intrabar range.
uptick_countbigint · not nullNumber of prints classified as an uptick (price rose vs. prior print).
downtick_countbigint · not nullNumber of prints classified as a downtick (price fell vs. prior print).
unchanged_countbigint · not nullNumber of prints with unchanged price vs. the prior print (zero tick).
unchanged_volumedouble precision · not nullVolume (shares) traded on zero-tick prints.
downtick_count_percentagedouble precision · not nulldowntick_count as a share (0-1) of ALL tick events (uptick+downtick+unchanged counts). Unlike the legacy uptick_count_pct, this denominator includes unchanged ticks.
unchanged_count_percentagedouble precision · not nullunchanged_count as a share (0-1) of ALL tick events (uptick+downtick+unchanged).
downtick_volume_percentagedouble precision · not nulldowntick_volume as a share (0-1) of ALL tick volume (uptick+downtick+unchanged), unlike the legacy uptick_volume_pct which excludes unchanged volume from its denominator.
buy_run_mean_lendouble precision · not nullMean length of taker-Buy runs: total buy-print count / number of distinct buy runs.
sell_run_mean_lendouble precision · not nullMean length of taker-Sell runs: total sell-print count / number of distinct sell runs.
run_imbalancedouble precision · not nullNormalized difference of the longest buy vs. sell run, in [-1,1]: (max_buy_run_length − max_sell_run_length) / (max_buy_run_length + max_sell_run_length).
logret_vardouble precision · not nullMean-centered variance of intrabar log returns (distinct from realized_vol, which is the un-centered sum of squared returns).
impact_per_notionaldouble precision · not null|bar log-return| / |signed (net) notional flow| — like amihud_illiquidity but normalized by directional pressure rather than gross dollar volume.
large_trade_reversaldouble precision · not nullMean 5-print-ahead return following prints in the running top decile by notional. Negative ⇒ big prints tend to reverse; 0 on bars with fewer than 6 prints.
directional_impact_asymmetrydouble precision · not nullMean per-print price change on buy-classified prints minus mean per-print price change on sell-classified prints. Positive ⇒ buys push price up more than sells push it down.
slippage_meandouble precision · not nullMean signed quote-relative slippage in price units ($): buy prints priced above the prevailing BBO mid, sell prints priced below it, averaged across prints with a valid attached quote.
slippage_bps_meandouble precision · not nullMean signed quote-relative slippage in bps across all sided prints with a valid quote. Positive ⇒ paid up / adverse execution.
slippage_bps_mediandouble precision · not nullMedian quote-relative slippage in bps. Streaming P² estimate.
slippage_bps_buy_meandouble precision · not nullMean quote-relative slippage in bps restricted to taker-Buy prints only.
slippage_bps_sell_meandouble precision · not nullMean quote-relative slippage in bps restricted to taker-Sell prints only.
slippage_bps_buy_sell_ratiodouble precision · not nullslippage_bps_buy_mean / slippage_bps_sell_mean.
slippage_bps_sell_buy_ratiodouble precision · not nullslippage_bps_sell_mean / slippage_bps_buy_mean.
ofidouble precision · not nullOrder-Flow Imbalance (Cont, Kukanov & Stoikov 2014): accumulated signed change in best-bid/ask queue depth across consecutive BBO snapshots attached to tbbo prints. Positive ⇒ net demand added / supply pulled at the touch.
ofi_normalizeddouble precision · not nullofi divided by the bucket's mean (bid_size+ask_size) depth — scale-free, suitable for cross-sectional ranking. 0 when no valid BBO snapshot was seen.
bid_count_at_touch_meandouble precisionBucket-mean number of distinct resting orders at the best BID across the BBO snapshots attached to trades (raw `levels[0].bid_ct`, averaged over valid-quote prints). A queue-fragmentation / order-count-at-touch signal orthogonal to the bid_sz share depth folded into ofi. NULL/0 when no valid BBO snapshot was seen.
ask_count_at_touch_meandouble precisionBucket-mean number of distinct resting orders at the best ASK across the BBO snapshots attached to trades (raw `levels[0].ask_ct`, averaged over valid-quote prints). Companion to bid_count_at_touch_mean. NULL/0 when no valid BBO snapshot was seen.
dollar_volumedouble precision · not nullTotal notional ($) traded across all prints in the bucket (sum of price×size, both sides) — the denominator for amihud_illiquidity.
n_printsbigint · not nullNumber of raw tbbo prints folded into this bucket after price/size validity filtering (price finite & >0, size >0). Same underlying count as trade_count.
flow_toxicity_scoredouble precision · not nullz(volume_delta_notional) × z(realized_vol), where each z-score is computed in a post-pass over the symbol's own trailing bucket series in the current upsert run. Highlights destabilizing, one-sided bars.
available_datedatePUBLIC-availability date: STORED generated column = date(event_time) — the session's own day, because a session's order flow is available on that session day. The point-in-time column to filter/join on. Previously date(event_time) + 1, which encoded a trading-lag adjustment and a file mtime rather than a publication date; see the entity-level availability note and migration m20260702_000204.

Access flow_metrics

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="flow_metrics",
    symbols=["NVDA", "AAPL"],
    start="2024-01-01",
)

Create a free account Browse all 95 datasets

Frequently asked questions

What is in the flow_metrics dataset?

Trade-flow metrics per symbol in fixed time windows: taker (aggressor) buy versus sell volume and trade counts, broken out by order size. One row is the finalized set of ~119 derived order-flow microstructure factors for one equity symbol over one aggregation bucket (currently only daily, bucket_seconds=86400): every top-of-book trade print during that bucket is aggressor-classified (quote-rule with tick-rule fallback) and folded into taker buy/sell flow, order-size composition, price/tick distributions, volatility, impact/slippage, run-structure, and order-flow-imbalance factors, plus a cross-bar flow_toxicity_score.

How do I avoid look-ahead bias with flow_metrics?

Filter on flow_metrics.available_date, the day the publisher made the row public. For this dataset that date is derived as follows — published: available_date = date(event_time) — the session's own day. WHY: event_time marks the START of the daily bucket, i.e. the trading session the bar aggregates, and the session's order flow is available on the session day itself. So the day the data was published is the session day, and that is what this column records. WHAT IT IS NOT: this was previously date(event_time) + 1, on two arguments that are both rejected. (a) 'the bar only settles after the close, so it is a T+1 fact' — an availability date is the day the publisher published, never an adjustment for when a consumer could act; the next tradeable session is always derivable forward from this date, and is never recoverable once a lag has been baked in. (b) 'the vendor file's last_modified_date lands on session+1' — an mtime is evidence about a filesystem, not about publication, and it moves for unrelated reasons (a site migration once touched 257 SEC FTD files to one 2020 date, which would have dated 11 years of history 11.5 years late). Corrected by migration m20260702_000204. A query of the form WHERE available_date <= '<as-of date>' never sees a row before it existed.

In what formats can I get flow_metrics?

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="flow_metrics". The column schema is public at https://api.obscura.trade/v1/catalog/flow_metrics.

Can I filter flow_metrics by company or symbol?

Yes. flow_metrics carries symbol, the column the API's symbols filter resolves against.

How often is flow_metrics updated?

Obscura refreshes flow_metrics on a every 6 hours 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. 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. Forex Positions AggregateA consensus long/short reading per currency pair, blending the individual broker sentiment feeds.