# Open interest

> 5-minute open interest and long/short ratios of each crypto perpetual.

Source: https://getmarkethistory.com/docs/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.

## Query

curl:

```bash
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"
```

Python client:

```python
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 day
```

Plain `requests`:

```python
import json
import 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"]
```

Response (shape and headers as served; values illustrative):

```http
HTTP/2 200
content-type: application/x-ndjson
x-row-count: 1000
x-bars-charged: 1000
x-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}
```

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

| 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.

## Price

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.
