---
name: cftc-commitments-of-traders-ingestion
description: "How to get CFTC Commitments of Traders (COT) data into a pandas DataFrame and Parquet: access, the request, the format, limits, quirks and terms."
---

# Load CFTC Commitments of Traders into pandas and Parquet

Source entry: https://signal-lab-jet.vercel.app/datasets/cftc-commitments-of-traders
Provider: https://www.cftc.gov/MarketReports/CommitmentsofTraders/index.htm
Checked against the provider's documentation: 2026-10-29

## Access
- No account, key or app token. The CFTC asks you not to overuse the API.

## Request
```bash
curl 'https://publicreporting.cftc.gov/resource/6dca-aqww.json?$limit=5&$order=report_date_as_yyyy_mm_dd%20DESC'
```

## Format
JSON array of rows (Socrata). Dataset 6dca-aqww is the Legacy futures-only report; other report types use other dataset ids. Numbers arrive as strings.

## Load into pandas and Parquet
Needs Python 3 with requests, pandas and pyarrow.
```python
"""CFTC Commitments of Traders, Legacy futures-only (Socrata API) -> pandas -> Parquet. No key or token."""
import requests
import pandas as pd

URL = "https://publicreporting.cftc.gov/resource/6dca-aqww.json"  # Legacy - Futures Only
PAGE = 5000
rows, offset = [], 0
while True:
    r = requests.get(URL, params={
        "$where": "report_date_as_yyyy_mm_dd >= '2024-01-01'",
        "$order": "report_date_as_yyyy_mm_dd, id",   # a stable order makes $offset paging safe
        "$limit": PAGE, "$offset": offset,
    }, timeout=60)
    r.raise_for_status()
    batch = r.json()
    rows += batch
    if len(batch) < PAGE:
        break
    offset += PAGE

df = pd.DataFrame(rows)
df["report_date_as_yyyy_mm_dd"] = pd.to_datetime(df["report_date_as_yyyy_mm_dd"])  # the Tuesday "as of" date
num = [c for c in df.columns if c.endswith("_all") or c.endswith("_old") or c.endswith("_other")]
df[num] = df[num].apply(pd.to_numeric, errors="coerce")  # Socrata returns numbers as strings
df.to_parquet("cftc_cot_legacy_futures.parquet", index=False)
print(len(df), "rows;", df["market_and_exchange_names"].nunique(), "markets; latest", df["report_date_as_yyyy_mm_dd"].max().date())
```
Run by us on 2026-10-29 (python 3.13.5 | pandas 3.1.0 | pyarrow 26.0.0 | requests 2.34.2). Result: 49,251 rows for 512 markets from 2024-01-02, latest report date 2026-10-20.

## Limits
- Rate limit: Not stated; the CFTC says you can use the API without a token as long as you are not overusing it.

## Quirks
- report_date_as_yyyy_mm_dd is the Tuesday the positions are as of. The report is normally released the following Friday at 3:30 p.m. ET, and federal holidays can delay it, so date each row to its release day in backtests.
- Page with $limit and $offset over a stable $order (the snippet orders by report date and id).
- Only markets where 20 or more traders hold reportable positions are covered.

## Terms and attribution
- Public domain US government information; the CFTC requests appropriate acknowledgement in any use (no set wording).
- Terms page: https://www.cftc.gov/WebPolicy/index.htm

## Sources
- https://www.cftc.gov/MarketReports/CommitmentsofTraders/index.htm: "As long as you are not overusing the API, you should be able to use the API without a token."
- https://www.cftc.gov/MarketReports/CommitmentsofTraders/ReleaseSchedule/index.htm: "The Commitments of Traders reports are released at 3:30 p.m. Eastern time."
- https://www.cftc.gov/WebPolicy/index.htm: "Public domain information may be freely distributed and copied, but it is requested that in any subsequent use the CFTC be given appropriate acknowledgement."

Information for educational purposes only. Free tiers, limits and licenses belong to the providers and may change; check the provider's own terms before using the data.
