Detect leverage build-ups and squeezes with open interest + funding.
Optiom Research · runnable code, tested against the live API
Open interest tells you how much leverage exists; funding tells you which side pays for it. Combined, they give you the four regimes that matter: leverage building long, building short, flushing, or quiet. This tutorial resamples raw OI snapshots to hourly, aligns funding on the same clock and flags crowded-long build-ups and squeezes.
Fetch, resample, flag
OI arrives as tick-level snapshots (every few seconds), so resample to hourly last-values. Funding updates on a slower clock, so forward-fill it onto the OI index. A crowded-long hour is OI up more than 5% in 24h with positive funding; a squeeze hour is OI down more than 5% in 24h — leverage leaving the system fast, willingly or not.
import pandas as pd
import requests
BASE = "https://www.getoptiom.com/api/tradinghub"
SYMBOL = "BTCUSDT"
oi = pd.DataFrame(requests.get(
f"{BASE}/oi", params={"symbol": SYMBOL, "max_rows": 50_000}, timeout=60
).json()["oi"])
oi["dt"] = pd.to_datetime(oi["tMs"], unit="ms", utc=True)
oi_h = oi.set_index("dt")["oi"].resample("1h").last().dropna()
funding = pd.DataFrame(requests.get(
f"{BASE}/funding", params={"symbol": SYMBOL, "max_rows": 20_000}, timeout=30
).json())
funding["dt"] = pd.to_datetime(funding["time"], unit="s", utc=True)
f_h = funding.set_index("dt")["value"].resample("1h").ffill()
# align funding onto the OI clock (funding updates slower; forward-fill)
df = pd.DataFrame({"oi": oi_h})
df["funding"] = f_h.reindex(df.index, method="ffill")
df = df.dropna()
df["oi_chg_24h_pct"] = df["oi"].pct_change(24) * 100
# setup: leverage builds (OI +5% in 24h) while funding is positive -> crowded longs
df["crowded_long"] = (df["oi_chg_24h_pct"] > 5) & (df["funding"] > 0)
# squeeze: that leverage gets flushed (OI -5% in 24h)
df["squeeze"] = df["oi_chg_24h_pct"] < -5
print(df.tail(6).round(4))
print(f"\nHours flagged crowded-long: {int(df['crowded_long'].sum())}")
print(f"Hours flagged squeeze: {int(df['squeeze'].sum())}")
print("\nLatest squeeze windows:")
print(df[df["squeeze"]].tail(5)[["oi", "oi_chg_24h_pct", "funding"]].round(4))Reading the four regimes
OI up + funding positive: longs piling in — fragile, fuel for a downside cascade. OI up + funding negative: shorts piling in — fuel for a short squeeze up. OI down fast after either: the flush is happening; these hours overlap heavily with the cascade hours from the liquidations tutorial. OI flat: nobody is committing, expect chop.
Practical notes
At 50,000 snapshots the OI window covers roughly two days; schedule the script hourly and persist the output to build your own longer history. The squeeze flags become actionable when combined with the levels from the depth heatmap: a flush into a strong bid wall is the highest-quality long setup this data offers.
Run it on your own data.
Create a free account for CSV exports, then move to API access as your workflow grows.