Every week, the US Commodity Futures Trading Commission publishes a snapshot of how the world's largest market participants are positioned in currency futures markets. Released every Friday at 3:30 pm Eastern Time and covering data through the prior Tuesday, the Commitments of Traders (COT) report is one of the few windows into who is holding what and in which direction — before the next big move arrives.
For FX traders, COT data is not a crystal ball. It is a positioning map. And positioning maps, read correctly, reveal the conditions that often precede sharp reversals, sustained trends, and the moments when consensus becomes its own risk.
What You Will Learn
- What the CFTC COT report is, how it is structured, and which numbers matter
- How to interpret net non-commercial positioning as a sentiment indicator
- Why extreme positioning signals potential turning points in FX pairs
- How to access and analyse COT data via the FXMacroData API
- Practical frameworks for combining COT signals with macro fundamentals
The Anatomy of a COT Report
The CFTC collects position data from futures exchanges, aggregates it, and publishes three main versions of the COT report. For FX traders, the most relevant is the Legacy COT report (Futures-Only), which breaks positions into three groups:
- Commercial traders — corporations, importers, exporters, and multinationals who use currency futures primarily for hedging. Their positions reflect business-level currency risk management rather than speculative views on direction. Commercials are often contrarian in nature, increasing short exposure as prices rise (hedging upcoming receivables) and decreasing it as prices fall.
- Non-commercial traders (large speculators) — hedge funds, asset managers, and CTAs who trade currency futures for speculative profit. This is the group FX traders watch most closely. Non-commercials position with conviction based on macro views, trend signals, and rate differentials. When they are aggressively long or short a currency, it is because they have a thesis — and when that thesis becomes crowded, the reversal risk grows.
- Non-reportable positions (small speculators) — retail traders and small participants whose positions fall below the CFTC reporting threshold. This group is generally less significant for macro FX analysis.
Key Concept: Non-Commercial Net Position
Non-commercial net position = Non-commercial long contracts − Non-commercial short contracts. This single figure is what most FX traders track week over week. A rising net long in EUR futures means large speculators are increasing their bullish exposure to the euro. A sustained net short in JPY futures means the hedge fund community has a structural bearish view on the yen.
Why COT Data Matters for FX Traders
Currency markets are the largest and most liquid markets in the world, but they are not transparent. You cannot see who is buying EUR/USD at 1.1050 or shorting JPY futures in overnight Asia. The COT report is one of the few sources that gives you a weekly read on aggregate directional conviction — and that makes it uniquely valuable for three specific types of analysis.
1. Identifying Crowded Trades
When non-commercial positioning in a currency reaches extreme levels relative to its historical range, the trade is crowded. Crowded trades are not inherently wrong — they are often the result of a well-reasoned macro thesis. But they carry an asymmetric risk: the more crowded a trade, the more violent the move when participants need to exit simultaneously.
The canonical example is the JPY short trade. Through much of 2022 and 2023, non-commercial short positioning in JPY futures reached multi-decade extremes, reflecting the wide and persistent rate differential between the Bank of Japan and every other major central bank. The yen weakened broadly. But each Bank of Japan policy surprise — and there were several — triggered sharp, rapid short-covering rallies in JPY that caught holders of crowded short positions in a squeeze. The fundamental thesis was correct for much of the period, yet the position was periodically dangerous to hold because of how crowded it had become.
FXMacroData surfaces COT positioning for eight major currency futures — AUD, CAD, CHF, EUR, GBP, JPY, NZD, and USD — making it straightforward to track which trades are building toward historical extremes.
curl "https://fxmacrodata.com/api/v1/cot/jpy?api_key=YOUR_API_KEY&start=2022-01-01"
{
"data": [
{
"date": "2024-04-02",
"noncommercial_long": 28341,
"noncommercial_short": 198076,
"noncommercial_net": -169735,
"commercial_long": 213540,
"commercial_short": 47832,
"open_interest": 287450
}
]
}
A net non-commercial position of −169,735 contracts in JPY is large by any historical measure. Plotting this series over time immediately reveals how far current positioning sits relative to past extremes — and whether the crowd has room to extend further or is approaching a structural reversal risk zone.
2. Tracking Trend Confirmation and Deterioration
COT data is not a timing tool — a crowded trade can remain crowded for months before reversing. But it is an excellent regime identifier. When non-commercial positioning is consistently trending in one direction, it confirms that macro money is aligned behind a trend. When that trend starts to plateau or reverse even while price continues in the same direction, it is often an early warning of waning conviction.
The divergence between price and positioning is one of the most reliable COT-based signals in FX. If EUR/USD is grinding higher but non-commercial net longs in EUR futures are shrinking week over week, large speculators are reducing exposure into strength — and that distribution pattern often precedes a top.
Signal Framework: Price vs Positioning Divergence
- Bullish divergence: Price falls, but non-commercial net longs hold steady or increase — selling pressure is met by fresh long conviction. Supports continuation of the longer-term trend.
- Bearish divergence: Price rises, but non-commercial net longs shrink — speculators are distributing into strength. Often precedes a reversal or consolidation.
- Trend confirmation: Both price and net positioning moving in the same direction — the path of least resistance is clear.
3. Anchoring Macro Views with Market Positioning
COT data becomes most powerful when combined with macro fundamentals. A rate differential may strongly favour one currency — but if that thesis is already priced into an extreme net long position, the incremental upside may be limited. Conversely, a currency trading against macro fundamentals with a heavily crowded short position is a setup worth watching closely: any fundamental surprise that challenges the bear thesis will force short covering at scale.
Imagine watching the CHF. Swiss National Bank policy decisions come through on the CHF policy rate endpoint. If macro data shows a widening CHF-positive rate differential but non-commercial CHF positioning in futures is still deeply short, the positioning backdrop is constructive for a catch-up rally when the fundamental case eventually becomes undeniable. That combination — macro tailwind plus a wrong-footed speculator community — is where the largest and fastest FX moves often originate.
Reading the COT Report: Key Metrics to Track
Raw contract counts are informative, but the following derived metrics sharpen the signal considerably.
Net Position as a Percentage of Open Interest
Normalising net non-commercial positions against total open interest gives a standardised measure of directional skew. A net long of 50,000 contracts means something very different in a currency with 100,000 contracts of open interest versus one with 500,000. Dividing net position by open interest produces a ratio between −1 and +1 that is directly comparable across currencies and across time.
import requests
BASE = "https://fxmacrodata.com/api/v1"
KEY = "YOUR_API_KEY"
def cot_series(currency: str, start: str = "2020-01-01") -> list[dict]:
r = requests.get(
f"{BASE}/cot/{currency}",
params={"api_key": KEY, "start": start}
)
r.raise_for_status()
return r.json()["data"]
def net_oi_ratio(record: dict) -> float:
"""Net non-commercial position as fraction of open interest."""
if record.get("open_interest", 0) == 0:
return 0.0
return record["noncommercial_net"] / record["open_interest"]
eur_cot = cot_series("eur")
ratios = [(r["date"], net_oi_ratio(r)) for r in eur_cot]
print(ratios[-5:]) # most recent five weeks
Z-Score of Net Positioning
The z-score measures how many standard deviations current positioning sits from its historical mean. A z-score above +2 or below −2 flags statistically extreme conditions. For FX, it is common practice to use a rolling 52-week window so that the benchmark reflects current market structure rather than a decade-old positioning regime.
import statistics
def rolling_zscore(series: list[dict], window: int = 52) -> list[dict]:
"""Compute z-score of net non-commercial positioning on a rolling window."""
results = []
values = [r["noncommercial_net"] for r in series]
for i, record in enumerate(series):
start_i = max(0, i - window + 1)
window_vals = values[start_i : i + 1]
if len(window_vals) < 4:
results.append({**record, "zscore": None})
continue
mu = statistics.mean(window_vals)
sig = statistics.stdev(window_vals)
z = (record["noncommercial_net"] - mu) / sig if sig > 0 else 0.0
results.append({**record, "zscore": round(z, 2)})
return results
gbp_cot = cot_series("gbp", start="2018-01-01")
gbp_scored = rolling_zscore(gbp_cot)
extremes = [r for r in gbp_scored if r["zscore"] is not None and abs(r["zscore"]) > 2.0]
print(f"Extreme positioning weeks in GBP: {len(extremes)}")
Weekly Change in Net Position
The velocity of positioning change is often as important as the absolute level. A currency moving from +20,000 net longs to +80,000 net longs over four weeks signals accelerating conviction. A currency reversing from +120,000 to +60,000 over the same period signals active distribution — even if net positioning remains comfortably positive.
Accessing COT Data via FXMacroData
FXMacroData delivers weekly CFTC COT data for all eight major currency futures contracts through a clean REST endpoint. Each record includes the full breakdown: non-commercial longs, shorts, and net, plus commercial longs and shorts, and total open interest.
Supported currencies: AUD, CAD, CHF, EUR, GBP, JPY, NZD, USD.
# EUR net positioning since 2023
curl "https://fxmacrodata.com/api/v1/cot/eur?api_key=YOUR_API_KEY&start=2023-01-01"
# GBP full history
curl "https://fxmacrodata.com/api/v1/cot/gbp?api_key=YOUR_API_KEY"
# AUD recent 12 months
curl "https://fxmacrodata.com/api/v1/cot/aud?api_key=YOUR_API_KEY&start=2024-01-01"
The response is date-sorted with the most recent data first and uses consistent field names across all currencies, so a single analysis script works across all eight pairs without modification.
Non-Commercial Long
Speculative bullish contracts held by hedge funds and CTAs. Rising week over week: bulls are adding.
Non-Commercial Short
Speculative bearish contracts. Rising week over week: bears are adding. Extreme levels: short squeeze risk.
Non-Commercial Net
Longs minus shorts. The headline number. Above zero: speculative community is net bullish. Track trend and z-score.
Open Interest
Total contracts outstanding. Rising open interest alongside a rising net long confirms strong participation in the trend.
Practical Multi-Currency COT Scan
One of the most useful applications of COT data is a weekly cross-currency scan that ranks all major currencies by their z-scored positioning. This immediately surfaces which currencies are most extended long, which are most extended short, and which sit near neutral — and it provides a basis for identifying pairs where one side's positioning is at an extreme relative to the other.
import requests, statistics
from datetime import datetime, timedelta
BASE = "https://fxmacrodata.com/api/v1"
KEY = "YOUR_API_KEY"
CURRENCIES = ["aud", "cad", "chf", "eur", "gbp", "jpy", "nzd"]
def cot_series(ccy: str) -> list[dict]:
r = requests.get(f"{BASE}/cot/{ccy}", params={"api_key": KEY, "start": "2019-01-01"})
r.raise_for_status()
return r.json()["data"]
def zscore_latest(records: list[dict], window: int = 52) -> dict:
vals = [r["noncommercial_net"] for r in records]
latest = vals[0]
sample = vals[:window]
mu = statistics.mean(sample)
sig = statistics.stdev(sample) if len(sample) > 1 else 1.0
z = (latest - mu) / sig if sig > 0 else 0.0
return {
"net" : latest,
"zscore" : round(z, 2),
"oi_ratio" : round(latest / records[0]["open_interest"], 3) if records[0].get("open_interest") else None,
"date" : records[0]["date"],
}
results = {}
for ccy in CURRENCIES:
data = cot_series(ccy)
results[ccy.upper()] = zscore_latest(data)
# Rank by z-score
ranked = sorted(results.items(), key=lambda x: x[1]["zscore"], reverse=True)
print(f"{'CCY':<6} {'Net':>12} {'Z-Score':>9} {'OI Ratio':>10} {'Date'}")
print("-" * 56)
for ccy, r in ranked:
flag = " ← EXTREME" if abs(r["zscore"]) > 2.0 else ""
print(f"{ccy:<6} {r['net']:>12,} {r['zscore']:>9.2f} {str(r['oi_ratio']):>10} {r['date']}{flag}")
The output gives a snapshot like the following (illustrative values):
CCY Net Z-Score OI Ratio Date
--------------------------------------------------------
EUR +94,320 +2.31 +0.31 2024-04-02 ← EXTREME
GBP +38,150 +1.45 +0.22 2024-04-02
AUD -4,200 -0.18 -0.03 2024-04-02
NZD -8,900 -0.62 -0.15 2024-04-02
CAD -21,300 -1.08 -0.18 2024-04-02
CHF -44,100 -1.95 -0.38 2024-04-02
JPY -172,400 -2.64 -0.60 2024-04-02 ← EXTREME
When EUR is at a 2-standard-deviation extreme long and JPY is at a 2-standard-deviation extreme short, the EUR/JPY pair is positioned with the crowd firmly on one side. Any macro shock that disrupts either the EUR bullish thesis or the JPY bearish thesis will force rapid, large-scale unwinding — and EUR/JPY can move 3–4% in a single session under those conditions.
Combining COT with Macro Fundamentals
COT data answers the question: who is positioned, and how aggressively? Macro fundamental data answers the question: what should the currency be worth based on rates, inflation, and growth? The most powerful FX frameworks use both.
A simple four-quadrant model structures the interaction clearly:
| Scenario | Macro Signal | COT Positioning | Implication |
|---|---|---|---|
| Strong Conviction Long | Bullish (rising rates, strong data) | Not yet crowded; z-score < +1 | Trend likely has room to extend. Dip-buy opportunities. |
| Late-Stage Long | Bullish but slowing | Crowded; z-score > +2 | Trend intact but fragile. Reduce position size; tighten stops. |
| Reversal Setup | Turning bearish (surprise cut, weak data) | Extreme long; z-score > +2.5 | High-probability flush. Force-selling amplifies the move. Best asymmetric short entry. |
| Stealth Accumulation | Bearish consensus | Extreme short; z-score < −2 | Any positive surprise triggers outsized short-squeeze rally. Watch for fundamental inflection. |
To operationalise the macro column, pull policy rate history from the relevant central bank endpoint alongside the COT data. For example, tracking the RBA policy rate and Australian inflation alongside AUD COT positioning gives a complete picture of whether the speculator community is aligned with or ahead of the macro story.
Limitations to Keep in Mind
COT data is powerful but not infallible. Five limitations deserve explicit acknowledgement before building a COT-based trading framework.
- Publication lag. The CFTC measures positions as of Tuesday close and publishes on Friday. By the time the data is public, three to four days of trading have occurred. Significant position changes can occur between measurement and publication.
- Futures ≠ spot FX. Institutional FX flow occurs primarily in the OTC spot and forward markets, which are far larger and entirely unregulated. COT captures only the exchange-traded futures layer — a significant but incomplete proxy for total speculative positioning.
- Crowded trades can stay crowded. A z-score above +2 identifies statistical extremity, not an imminent reversal. The JPY short trade remained extreme for multiple quarters as the Bank of Japan held its ultra-loose policy framework. Extreme positioning narrows the risk-reward; it does not guarantee a date for the turn.
- Commercials are not infallible contrarians. Hedgers increase short positions when they have receivables to protect — not necessarily because they think the currency will fall. Using commercial positioning as a contrarian signal requires careful context about the underlying business flows driving the hedging activity.
- Open interest can distort contract counts. A large increase in open interest alongside a rising net position may indicate new money entering, while stable or declining open interest alongside a rising net may simply reflect the short side covering. Always view net positions alongside the open interest trend.
Building a Weekly COT Dashboard
With the FXMacroData API, building a personal COT monitoring dashboard is a weekend project. The key components are:
- Fetch the last 52 weeks of COT data for all seven G10 currency futures
- Compute net positioning z-scores on a rolling 52-week window
- Rank currencies from most extreme long to most extreme short
- Identify pairs where opposite extremes exist (e.g., EUR extreme long + JPY extreme short → EUR/JPY in focus)
- Pull the macro context — policy rate differentials from the relevant rate endpoints — to determine whether the positioning is aligned with or diverging from the fundamental backdrop
- Flag any weeks where positioning moved by more than one standard deviation — rapid repositioning is a signal in its own right
The FXMacroData COT dashboard page delivers this view visually across all supported currencies, updated weekly after each CFTC release. For quantitative or programmatic use, the API endpoint returns the underlying data in a form that feeds directly into Python, R, or any analytical environment.
Quick Reference: COT API Endpoints
- EUR:
https://fxmacrodata.com/api/v1/cot/eur?api_key=YOUR_API_KEY - GBP:
https://fxmacrodata.com/api/v1/cot/gbp?api_key=YOUR_API_KEY - JPY:
https://fxmacrodata.com/api/v1/cot/jpy?api_key=YOUR_API_KEY - AUD:
https://fxmacrodata.com/api/v1/cot/aud?api_key=YOUR_API_KEY - CAD:
https://fxmacrodata.com/api/v1/cot/cad?api_key=YOUR_API_KEY - CHF:
https://fxmacrodata.com/api/v1/cot/chf?api_key=YOUR_API_KEY - NZD:
https://fxmacrodata.com/api/v1/cot/nzd?api_key=YOUR_API_KEY
The Bottom Line
COT reports give FX traders a window that almost nothing else provides: a weekly, audited measure of how the world's largest speculative accounts are positioned in currency futures. Used in isolation, that information is suggestive but incomplete. Combined with macro fundamentals — central bank policy rates, inflation readings, and economic surprises surfaced through the FXMacroData API — it becomes a genuine analytical edge.
The most dangerous FX trades are not the ones where the fundamental case is wrong. They are the ones where the fundamental case is right but the trade is so crowded that a single data surprise triggers a cascade of forced exits. COT data is the early warning system for those conditions.
Track positioning alongside the macro calendar. Know when the crowd is stretched. And when fundamentals shift, know which direction the exits are pointed.