# Perpetual prices

> 1m mark, index and premium prices of each crypto perpetual, since its first month.

Source: https://getmarkethistory.com/docs/perp-prices

`crypto-futures` carries three prices of each perpetual beside its trades, **one row a minute**
from the contract's first month on (January 2020 for the oldest), delisted contracts included:

- **mark**: the price positions are valued and liquidated at.
- **index**: the spot reference the contract tracks, averaged over several spot markets.
- **premium**: the premium index, the contract's gap to its index as a fraction; the
  [funding rate](https://getmarkethistory.com/docs/funding) is computed from it.

Nothing trades at these prices, so a row has no volume. Months are added a day or two after
they end, so the newest row is up to a month old.

## Query

curl:

```bash
curl -sD - "https://getmarkethistory.com/query/v1/prices?symbol=BTCUSDT&kind=mark&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

page = mh.prices("BTCUSDT", "mark", start="2024-01-01", end="2024-01-31", limit=100_000)
page.to_pandas().set_index("timestamp")["close"]
```

Plain `requests`:

```python
import json
import os

import requests

url = "https://getmarkethistory.com/query/v1/prices"
params = {"symbol": "BTCUSDT", "kind": "mark", "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: 21

{"close":42314.0,"high":42330.1,"low":42288.5,"open":42292.4,"timestamp":"2024-01-01T00:00:00Z"}
{"close":42301.7,"high":42322.9,"low":42296.3,"open":42314.0,"timestamp":"2024-01-01T00:01:00Z"}
```

One symbol and one kind per request, the symbol spelled as
`/api/v1/symbols?source=crypto-futures&timeframe=1m` lists it.

| Parameter      | Meaning                                                                      |
| -------------- | ---------------------------------------------------------------------------- |
| `symbol`       | The perpetual (`BTCUSDT`). Required.                                         |
| `kind`         | `mark`, `index` or `premium`. Required.                                      |
| `source`       | Optional: `crypto-futures`, the only source with these prices.               |
| `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 and only works with the `kind` it came from. A symbol without that
price is a 404.

## Columns

| Column      | Type      | Meaning                       |
| ----------- | --------- | ----------------------------- |
| `timestamp` | timestamp | the minute's open, UTC        |
| `open`      | float     | the first price of the minute |
| `high`      | float     | the highest                   |
| `low`       | float     | the lowest                    |
| `close`     | float     | the last                      |

Prices are stored exactly as published (to 10⁻⁸, finer when a price has more digits) 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. These prices need bought bars: the free plan's monthly bars do not pay for them.
A year of one kind is 525,600 rows.
