CFTC Commitments of Traders
The CFTC's weekly Commitments of Traders report: how commercial, non-commercial and small traders are positioned in each futures market. Legacy futures-only format.
cftc_cot — the dataset name to pass to the Obscura API.
What one row means
One market's legacy futures-only Commitments of Traders positioning breakdown for one weekly report — the split of total open interest across commercial (hedger), non-commercial (speculator), and non-reportable (small trader) accounts for a single CFTC-regulated futures market, as surveyed as of the Tuesday close of that report week and later disseminated by CFTC.
One row per (contract_market_code, report_date).
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 cftc_cot: release_calendar: available_date = report_date + 3 US FEDERAL BUSINESS days — the Tuesday survey is released the following Friday, and a federal holiday inside that window pushes the release out (Jun 16 2026 -> Jun 22, Jun 30 2026 -> Jul 6). Holiday-aware, so it is materialized by the collector, not a generated column.
Refresh cadence
Obscura refreshes cftc_cot weekly — 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 — 51 columns
The full public column list for cftc_cot, with the meaning of every field. The same
schema is served unauthenticated at https://api.obscura.trade/v1/catalog/cftc_cot.
| Column | Type | Description |
|---|---|---|
| contract_market_code | text · not null | CFTC contract market code for the futures market, e.g. "001602" = Wheat-SRW/CBOT, "13874A" = E-mini S&P 500/CME. Stable per-market key CFTC assigns; part of the composite primary key. |
| report_date | date · not null | Tuesday survey (as-of) date the weekly report covers — the period the positions are measured for, NOT the day CFTC published them. Part of the composite primary key. |
| available_date | date | PUBLIC-availability date = report_date advanced 3 US FEDERAL BUSINESS days — CFTC's Friday release of the Tuesday survey, pushed out by any federal holiday in the window (a plain "+3 calendar days" named Juneteenth and the observed 4th of July, days CFTC did not publish). Materialized by the collector via `calendar::add_business_days`, since a holiday-aware lag cannot be a generated column; NULL only on rows a collector run has not yet touched. The point-in-time column to filter/join on — NEVER report_date. |
| market_and_exchange | text | Human-readable market/exchange label, e.g. "WHEAT-SRW - CHICAGO BOARD OF TRADE". Nullable if the API omits it for a row. |
| open_interest | double precision | Total open interest across all trader categories for the market/week, in number of futures contracts. |
| noncomm_long | double precision | Non-commercial (large speculator) long open interest, contracts. |
| noncomm_short | double precision | Non-commercial (large speculator) short open interest, contracts. |
| noncomm_spread | double precision | Non-commercial spreading positions (long and short legs of intra-market spreads, counted once), contracts. |
| comm_long | double precision | Commercial (hedger) long open interest, contracts. |
| comm_short | double precision | Commercial (hedger) short open interest, contracts. |
| nonrept_long | double precision | Non-reportable (small trader, below CFTC reporting thresholds) long open interest, contracts. Typically CFTC's back-derived residual, passed through as-is. |
| nonrept_short | double precision | Non-reportable (small trader) short open interest, contracts. Same residual-derivation caveat as nonrept_long. |
| noncomm_net | double precision | Net speculative position (noncomm_long - noncomm_short), precomputed in-task; NULL only if either input is NULL. The standard "spec net length" signal traders watch for sentiment extremes/reversals. |
| cftc_market_code | text | CFTC market (exchange) code identifying the exchange the contract trades on, e.g. "CBT" = Chicago Board of Trade. Raw `cftc_market_code` (space-trimmed). Links markets across the same exchange. |
| cftc_commodity_code | text | CFTC commodity grouping code, e.g. "001" = wheat. Raw `cftc_commodity_code` (space-trimmed). Links the same underlying commodity across exchanges/contracts. |
| commodity_name | text | Commodity name, e.g. "WHEAT". Raw `commodity_name`. Leaf of the commodity classification hierarchy. |
| commodity_subgroup | text | Commodity subgroup, e.g. "GRAINS". Raw `commodity_subgroup_name`. Mid level of the classification hierarchy. |
| commodity_group | text | Commodity group, e.g. "AGRICULTURE". Raw `commodity_group_name`. Top level of the classification hierarchy for grouping/aggregating markets. |
| contract_units | text | Contract size/units label, e.g. "(CONTRACTS OF 5,000 BUSHELS)". Raw `contract_units`. Needed to convert contract counts to notional. |
| traders_tot | bigint | Total number of reporting traders in the market (all buckets). Raw `traders_tot_all`. Participation/crowdedness signal, not derivable from position sizes. |
| traders_noncomm_long | bigint | Number of reporting non-commercial long traders. Raw `traders_noncomm_long_all`. |
| traders_noncomm_short | bigint | Number of reporting non-commercial short traders. Raw `traders_noncomm_short_all`. |
| traders_noncomm_spread | bigint | Number of reporting non-commercial spreading traders. Raw `traders_noncomm_spread_all`. |
| traders_comm_long | bigint | Number of reporting commercial long traders. Raw `traders_comm_long_all`. |
| traders_comm_short | bigint | Number of reporting commercial short traders. Raw `traders_comm_short_all`. |
| traders_tot_rept_long | bigint | Number of total reportable long traders (commercial + non-commercial). Raw `traders_tot_rept_long_all`. |
| traders_tot_rept_short | bigint | Number of total reportable short traders (commercial + non-commercial). Raw `traders_tot_rept_short_all`. |
| conc_gross_le_4_long | double precision | Gross concentration: % of OI held by the largest 4 long traders. Raw `conc_gross_le_4_tdr_long`. Squeeze/concentration metric. |
| conc_gross_le_4_short | double precision | Gross concentration: % of OI held by the largest 4 short traders. Raw `conc_gross_le_4_tdr_short`. |
| conc_gross_le_8_long | double precision | Gross concentration: % of OI held by the largest 8 long traders. Raw `conc_gross_le_8_tdr_long`. |
| conc_gross_le_8_short | double precision | Gross concentration: % of OI held by the largest 8 short traders. Raw `conc_gross_le_8_tdr_short`. |
| conc_net_le_4_long | double precision | Net concentration: % of OI held by the largest 4 long traders (net basis). Raw `conc_net_le_4_tdr_long_all`. |
| conc_net_le_4_short | double precision | Net concentration: % of OI held by the largest 4 short traders (net basis). Raw `conc_net_le_4_tdr_short_all`. |
| conc_net_le_8_long | double precision | Net concentration: % of OI held by the largest 8 long traders (net basis). Raw `conc_net_le_8_tdr_long_all`. |
| conc_net_le_8_short | double precision | Net concentration: % of OI held by the largest 8 short traders (net basis). Raw `conc_net_le_8_tdr_short_all`. |
| open_interest_old | double precision | Old-crop-year total open interest, contracts. Raw `open_interest_old`. Old/other split not derivable from the _all total. |
| noncomm_long_old | double precision | Old-crop-year non-commercial long OI, contracts. Raw `noncomm_positions_long_old`. |
| noncomm_short_old | double precision | Old-crop-year non-commercial short OI, contracts. Raw `noncomm_positions_short_old`. |
| noncomm_spread_old | double precision | Old-crop-year non-commercial spreading positions, contracts. Raw `noncomm_positions_spread`. |
| comm_long_old | double precision | Old-crop-year commercial long OI, contracts. Raw `comm_positions_long_old`. |
| comm_short_old | double precision | Old-crop-year commercial short OI, contracts. Raw `comm_positions_short_old`. |
| nonrept_long_old | double precision | Old-crop-year non-reportable long OI, contracts. Raw `nonrept_positions_long_old`. |
| nonrept_short_old | double precision | Old-crop-year non-reportable short OI, contracts. Raw `nonrept_positions_short_old`. |
| open_interest_other | double precision | Other-crop-year total open interest, contracts. Raw `open_interest_other`. |
| noncomm_long_other | double precision | Other-crop-year non-commercial long OI, contracts. Raw `noncomm_positions_long_other`. |
| noncomm_short_other | double precision | Other-crop-year non-commercial short OI, contracts. Raw `noncomm_positions_short_other`. |
| noncomm_spread_other | double precision | Other-crop-year non-commercial spreading positions, contracts. Raw `noncomm_positions_spread_1`. |
| comm_long_other | double precision | Other-crop-year commercial long OI, contracts. Raw `comm_positions_long_other`. |
| comm_short_other | double precision | Other-crop-year commercial short OI, contracts. Raw `comm_positions_short_other`. |
| nonrept_long_other | double precision | Other-crop-year non-reportable long OI, contracts. Raw `nonrept_positions_long_other`. |
| nonrept_short_other | double precision | Other-crop-year non-reportable short OI, contracts. Raw `nonrept_positions_short_other`. |
Access cftc_cot
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="cftc_cot",
start="2024-01-01",
)
Create a free account Browse all 95 datasets
Frequently asked questions
What is in the cftc_cot dataset?
The CFTC's weekly Commitments of Traders report: how commercial, non-commercial and small traders are positioned in each futures market. Legacy futures-only format. One market's legacy futures-only Commitments of Traders positioning breakdown for one weekly report — the split of total open interest across commercial (hedger), non-commercial (speculator), and non-reportable (small trader) accounts for a single CFTC-regulated futures market, as surveyed as of the Tuesday close of that report week and later disseminated by CFTC.
How do I avoid look-ahead bias with cftc_cot?
Filter on cftc_cot.available_date, the day the publisher made the row public. For this dataset that date is derived as follows — release_calendar: available_date = report_date + 3 US FEDERAL BUSINESS days — the Tuesday survey is released the following Friday, and a federal holiday inside that window pushes the release out (Jun 16 2026 -> Jun 22, Jun 30 2026 -> Jul 6). Holiday-aware, so it is materialized by the collector, not a generated column. A query of the form WHERE available_date <= '<as-of date>' never sees a row before it existed.
In what formats can I get cftc_cot?
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="cftc_cot". The column schema is public at https://api.obscura.trade/v1/catalog/cftc_cot.
How often is cftc_cot updated?
Obscura refreshes cftc_cot on a weekly 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.