Open interest
crypto-futures carries a snapshot of each perpetual’s positioning every 5 minutes, from
the contract’s first day in the archive on (September 2020 for the oldest, December 2021 for
most), delisted contracts included. Being backfilled: until it is done, a contract’s
history may be empty or start later than that.
- open interest: the contracts open, and their value in the quote currency.
- long/short ratios: of the top traders’ accounts, of the top traders’ positions, of all accounts, and of the taker buy volume to the taker sell volume.
A day is added the day after it ends, so the newest row is under two days old.
curl -sD - "https://getmarkethistory.com/query/v1/open-interest?symbol=BTCUSDT&start=2024-01-01&end=2024-01-31" \ -H "Authorization: Bearer $MARKET_HISTORY_KEY"from markethistory import Client
mh = Client() # reads MARKET_HISTORY_KEY
rows = list(mh.each(mh.open_interest, "BTCUSDT", start="2024-01-01", end="2024-01-31"))len(rows) # 288 snapshots a dayimport jsonimport os
import requests
url = "https://getmarkethistory.com/query/v1/open-interest"params = {"symbol": "BTCUSDT", "start": "2024-01-01", "end": "2024-01-31"}headers = {"Authorization": f"Bearer {os.environ['MARKET_HISTORY_KEY']}"}
rows = []while True: r = requests.get(url, params=params, headers=headers, timeout=60) r.raise_for_status() # see /docs/errors for what each status means rows += [json.loads(line) for line in r.text.splitlines() if line] print(r.headers["X-Row-Count"], "rows,", r.headers["X-Bars-Charged"], "bars") if "X-Next-Cursor" not in r.headers: break params["cursor"] = r.headers["X-Next-Cursor"]HTTP/2 200content-type: application/x-ndjsonx-row-count: 1000x-bars-charged: 1000x-next-cursor: eyJ…x-query-ms: 15
{"account_ratio":1.0412,"open_interest":71234.567,"open_interest_value":3015678901.23,"taker_buy_sell_ratio":0.9876,"timestamp":"2024-01-01T00:00:00Z","top_trader_account_ratio":1.1203,"top_trader_position_ratio":1.0538}Shape and headers as served; the values are illustrative, not copied from a response.
One symbol per request, spelled as /api/v1/symbols?source=crypto-futures&timeframe=1m lists
it.
| Parameter | Meaning |
|---|---|
symbol |
The perpetual (BTCUSDT). Required. |
source |
Optional: crypto-futures, the only source with open interest. |
start, end |
Time range, inclusive (RFC 3339 or a bare date). Default: all of it. |
limit |
Rows per page: default 1,000, maximum 100,000. |
cursor |
X-Next-Cursor from the previous page. |
format |
jsonl (default), csv, json, parquet or arrow. mbt1 is bars only. |
Pages run oldest first. Follow X-Next-Cursor (or the Link header) until it is absent: the
cursor holds no server state. A symbol without open interest is a 404.
Columns
Section titled “Columns”| Column | Type | Meaning |
|---|---|---|
timestamp |
timestamp | the snapshot’s time, UTC, on the 5-minute grid |
open_interest |
float | contracts open |
open_interest_value |
float | their value in the quote currency (USDT for BTCUSDT) |
top_trader_account_ratio |
float | top traders: accounts long ÷ accounts short |
top_trader_position_ratio |
float | top traders: long position size ÷ short position size |
account_ratio |
float | all accounts: long ÷ short |
taker_buy_sell_ratio |
float | taker buy volume ÷ taker sell volume over the 5 minutes |
Any value column can be null: some days lack the top-trader ratios. A missing snapshot is a
missing row, not a row of nulls. Values are stored exactly as published (every digit) and are
served as the nearest float.
Billed like bars: one row is one bar, a page rounds up to a block of 100 rows, and an empty page is free. Open interest needs bought bars: the free plan’s monthly bars do not pay for it. A year of one perpetual is 105,120 rows.