FINRA Short Volume
Daily short-sale volume per security from FINRA's Reg SHO files.
finra_short_volume — the dataset name to pass to the Obscura API.
What one row means
One symbol's consolidated Reg SHO short-sale volume for one trading day, aggregated across FINRA-reporting equity trade-reporting facilities (ADF/TRFs) into a single row per (occurred_on, symbol) from FINRA's daily CNMSshvol file (cdn.finra.org/equity/regsho/daily/CNMSshvolYYYYMMDD.txt).
One row per (occurred_on, symbol).
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 finra_short_volume: release_calendar: available_date = occurred_on + 0 calendar days, as a STORED generated column (m20260702_000196) — FINRA publishes the file for trade date D on D itself, so the publication lag is zero. Measured: CNMSshvol20260724.txt carries Last-Modified 2026-07-24 21:18:07 GMT, i.e. 17:18 ET on the trade date. That is 78 minutes after the 16:00 bell, which does not move the date: available_date is the day the PUBLISHER made the data available, and when a consumer can act on it is their inference from the calendar. The two columns are separate because they are two facts that happen to coincide — occurred_on is the trading day, available_date is the publication day.
Refresh cadence
Obscura refreshes finra_short_volume every weekday — 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 — 8 columns
The full public column list for finra_short_volume, with the meaning of every field. The same
schema is served unauthenticated at https://api.obscura.trade/v1/catalog/finra_short_volume.
| Column | Type | Description |
|---|---|---|
| occurred_on | date · not null | Trading day this short-volume snapshot covers, parsed from the 'Date' column / URL YYYYMMDD. The real-world EVENT date: the day the trading happened. Distinct from available_date (the day FINRA published the file) even though the two hold the same value today, because FINRA posts trade date D's file on D at ~17:18 ET. PK (with symbol). |
| symbol | text · not null | Equity ticker symbol from the 'Symbol' column, no separate CIK join in this table. PK (with occurred_on). |
| short_volume | double precision · not null | Total reported short-sale volume for the symbol/day, summed across FINRA trade-reporting facilities; double because FINRA reports fractional shares. |
| short_exempt_volume | double precision · not null | Portion of short_volume exempt from the Reg SHO price test / locate requirement (e.g. bona fide market making); subset of short_volume, not additional. |
| total_volume | double precision · not null | Total consolidated trading volume (short + non-short) for the symbol/day across the same facilities; short_volume/total_volume gives the short-volume ratio. Does not report open short interest (see finra_short_interest). |
| market | text | Comma-joined trade-reporting-facility codes rolled into the row (e.g. "B,Q,N"); NULL when the source file's optional 6th field is absent. |
| scraped_at | timestamp with time zone · not null | Ingestion timestamp set to Utc::now() at upsert; the synced_at equivalent for this pre-convention table. Excluded from exports, updated on re-upsert. |
| available_date | date | PUBLIC-availability date = occurred_on + 0 calendar days. FINRA posts the consolidated Reg SHO file for trade date D on D itself, at ~17:18 ET, so the day it became publicly available IS the trade date. DB-generated, read-only; the point-in-time column to filter/join on. Equal to occurred_on today, and still the column to use: if FINRA's cadence ever changes, this one moves and occurred_on does not. |
Access finra_short_volume
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="finra_short_volume",
symbols=["NVDA", "AAPL"],
start="2024-01-01",
)
Create a free account Browse all 95 datasets
Frequently asked questions
What is in the finra_short_volume dataset?
Daily short-sale volume per security from FINRA's Reg SHO files. One symbol's consolidated Reg SHO short-sale volume for one trading day, aggregated across FINRA-reporting equity trade-reporting facilities (ADF/TRFs) into a single row per (occurred_on, symbol) from FINRA's daily CNMSshvol file (cdn.finra.org/equity/regsho/daily/CNMSshvolYYYYMMDD.txt).
How do I avoid look-ahead bias with finra_short_volume?
Filter on finra_short_volume.available_date, the day the publisher made the row public. For this dataset that date is derived as follows — release_calendar: available_date = occurred_on + 0 calendar days, as a STORED generated column (m20260702_000196) — FINRA publishes the file for trade date D on D itself, so the publication lag is zero. Measured: CNMSshvol20260724.txt carries Last-Modified 2026-07-24 21:18:07 GMT, i.e. 17:18 ET on the trade date. That is 78 minutes after the 16:00 bell, which does not move the date: available_date is the day the PUBLISHER made the data available, and when a consumer can act on it is their inference from the calendar. The two columns are separate because they are two facts that happen to coincide — occurred_on is the trading day, available_date is the publication day. A query of the form WHERE available_date <= '<as-of date>' never sees a row before it existed.
In what formats can I get finra_short_volume?
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="finra_short_volume". The column schema is public at https://api.obscura.trade/v1/catalog/finra_short_volume.
Can I filter finra_short_volume by company or symbol?
Yes. finra_short_volume carries symbol, the column the API's symbols filter resolves against.
How often is finra_short_volume updated?
Obscura refreshes finra_short_volume on a every weekday 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.