US Commodity Futures Trading Commission
CFTC Commitments of Traders — Who is long and who is short every futures market, weekly, since 1986
When you want to know positioning rather than price — how long the funds are, whether commercials are hedging the other way, and how today compares with the history of that market. The Tuesday snapshot is released Friday.
Reach for it when…
When you want to know positioning rather than price — how long the funds are, whether commercials are hedging the other way, and how today compares with the history of that market. The Tuesday snapshot is released Friday.
Not for: Anything intraday or daily (the report is weekly and three days stale), options positioning by strike, equities that do not trade as futures.
Units, revisions, traps
Units. Contracts, by trader category. Legacy report: commercial, non-commercial, non-reportable. Disaggregated: producer, swap dealer, managed money, other. Net = long − short.
Revisions. Rare corrections are republished with a note; the history is stable.
- Contract sizes differ across markets — compare net positions to open interest or to their own history, not across markets in contracts.
- 'Non-commercial' is not 'hedge funds' exactly; the disaggregated report's 'managed money' is closer.
- Market names change over time (e.g. 'E-MINI S&P 500' vs 'S&P 500 Consolidated'); filter on the market code.
Classic mistake: Calling an extreme net-long 'bullish' — extremes are contrarian more often than not.
Three recipes
- Recipe 1 · Net speculative position in one market
- Recipe 2 · This week's full report, one text file
- Recipe 3 · Managed money in the disaggregated report
Each recipe: Python · Excel · Sheets, with how to read the result. Python recipes run under pandas; recipe 1 is re-run by the weekly check where the source allows it.
How to use it in your own work
Copy the snippet, change the series id, read the result the way the footer says. Replace YOUR_…_KEY with your own key where one is needed.
Recipe 1Net speculative position in one market
# legacy futures-only report via the Socrata API: 10-year Treasury note, net non-commercial
import requests, pandas as pd
u = ("https://publicreporting.cftc.gov/resource/6dca-aqww.json?$where=cftc_contract_market_code='043602'"
"&$order=report_date_as_yyyy_mm_dd%20DESC&$limit=104")
df = pd.DataFrame(requests.get(u, timeout=60).json())
df["date"] = pd.to_datetime(df.report_date_as_yyyy_mm_dd)
df["net_spec"] = df.noncomm_positions_long_all.astype(int) - df.noncomm_positions_short_all.astype(int)
print(df.set_index("date")[["market_and_exchange_names", "net_spec", "open_interest_all"]].head(8))- Data → From Web → https://publicreporting.cftc.gov/resource/6dca-aqww.csv?$where=cftc_contract_market_code='043602'&$limit=500 → Load.
=IMPORTDATA("https://publicreporting.cftc.gov/resource/6dca-aqww.csv?$where=cftc_contract_market_code='043602'&$limit=500")Recipe 2This week's full report, one text file
# every market, latest week, from the plain-text file the CFTC posts each Friday
import pandas as pd
cols = ["market", "date_yymmdd", "date", "code", "exchange", "x1", "x2", "oi", "nc_long", "nc_short", "nc_spread", "c_long", "c_short"]
df = pd.read_csv("https://www.cftc.gov/dea/newcot/deafut.txt", header=None, usecols=range(13), names=cols)
df["net_spec"] = df.nc_long - df.nc_short
print(df.sort_values("net_spec")[["market", "oi", "net_spec"]].head(10))- Data → From Text/CSV → https://www.cftc.gov/dea/newcot/deafut.txt (comma-delimited, no header).
=IMPORTDATA("https://www.cftc.gov/dea/newcot/deafut.txt")Recipe 3Managed money in the disaggregated report
# disaggregated futures-only (dataset 72hh-3qpy): managed-money net in gold (088691)
import requests, pandas as pd
u = ("https://publicreporting.cftc.gov/resource/72hh-3qpy.json?$where=cftc_contract_market_code='088691'"
"&$order=report_date_as_yyyy_mm_dd%20DESC&$limit=156")
df = pd.DataFrame(requests.get(u, timeout=60).json())
df["date"] = pd.to_datetime(df.report_date_as_yyyy_mm_dd)
df["mm_net"] = df.m_money_positions_long_all.astype(int) - df.m_money_positions_short_all.astype(int)
print(df.set_index("date")["mm_net"].head(8))- Same pattern with dataset 72hh-3qpy in the CSV URL.
- Same pattern with dataset 72hh-3qpy.
Series → question map
The ids we use from CFTC Commitments of Traders, each with the question it answers. The catalog's compare view reads the concept tags behind these rows.
| Series | Answers | Region | Concept |
|---|---|---|---|
| 6dca-aqww · 043602 | How are funds positioned in 10-year Treasuries? | United States | cot |
| 6dca-aqww · 088691 | Is gold crowded? | global | cot |
| 6dca-aqww · 097741 | How is the yen positioned? | Japan | cot |
| 6dca-aqww · 13874A | Positioning in S&P 500 futures | United States | cot |
Compare with
Same question, different source: Cboe index data, Stooq, FRED. The compare view lines up coverage, frequency, history and access side by side and lists what the combination makes possible.
Open compare: CFTC Commitments of Traders · Cboe index data · Stooq →
Questions readers ask
When is the COT report published?
Friday at 15:30 Eastern, showing positions as of the previous Tuesday.
Legacy or disaggregated?
Legacy has the longest history (1986) and the familiar commercial/non-commercial split; disaggregated (2006 →) separates managed money from swap dealers. Financial futures have their own 'TFF' version.
Where do market codes come from?
The cftc_contract_market_code column in any row; search once by name, then filter by code — names change, codes do not.
Educational only — we explain, we never advise · snippet licence: public domain · corrections to [email protected], fixed within a day and logged in the changelog.