L1 / top of book
Best bid and best ask only. Derive this view after replaying the L2 snapshots and deltas; ticker statistics are not a substitute for quotes.
L2 Order Book Dataset
Normalized snapshots and deltas from major spot and derivatives venues, packaged as hourly Parquet/Zstd files for research and backtesting.
No credit card · The sample is one real hourly Parquet file and needs no API key
Is this the right dataset?
This landing page is for coverage, schema, sample files, and downloads. Use the SDK docs for method parameters and the reconstruction tutorial for replay logic.
Best bid and best ask only. Derive this view after replaying the L2 snapshots and deltas; ticker statistics are not a substitute for quotes.
This dataset. It records aggregate quantity at each visible price level so you can measure spread, depth, and imbalance.
Not provided. L2 cannot reveal queue position or how many individual orders make up a level unless the venue publishes an order count.
Sample
The first rows of one real hour: BTCUSDT on Binance Futures, 2026-09-02 at 12:00 UTC. One row per bid or ask price level in a snapshot or update.
binance_futures/2026-09-02/12/BTCUSDT_orderbook.parquetDownload full file| received_time | event_time | transaction_time | symbol | event_type | first_update_id | final_update_id | prev_final_update_id | last_update_id | side | price | quantity | order_count |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1788350400007361359 | 1788350399886 | 1788350399885 | BTCUSDT | update | 11454752530038 | 11454752532647 | 11454752529739 | null | bid | 26288.50 | 0.119 | null |
| 1788350400007361359 | 1788350399886 | 1788350399885 | BTCUSDT | update | 11454752530038 | 11454752532647 | 11454752529739 | null | ask | 76788.60 | 2.682 | null |
| 1788350400007361359 | 1788350399886 | 1788350399885 | BTCUSDT | update | 11454752530038 | 11454752532647 | 11454752529739 | null | bid | 26488.50 | 0.028 | null |
Wire format
Every row starts as a message on the exchange's WebSocket or REST API. Point at a line or a column to see where each value comes from and how we convert it. Our test suite replays these messages through the production pipeline, so the rows shown are the rows you download.
Exchange sends
WebSocket message · <symbol>@depth@0msreceived 2026-10-05 19:01:38.340225 UTC
{"stream": "btcusdt@depth@0ms","data": {"e": "depthUpdate","E": 1791226898196,"T": 1791226898194,"s": "BTCUSDT","ps": "BTCUSDT","U": 11742309239582,"u": 11742309241602,"pu": 11742309239523,"b": [["85547.70", "0.020"],["85580.30", "0.355"]],"a": [["85601.90", "2.784"],["85605.10", "0.001"],["85723.10", "0.000"]],"st": 1}}
Shortened: Binance sent 14 bid levels and 8 ask levels in this message. This example shows the two highest bids and the three lowest asks.
You download
Parquet row · orderbook · 1 of 5 rows from this message
Point at a line in the message or a column in the row to trace where each value comes from. Click a column to pin it.
Our tests replay this message through the production pipeline
All Binance Futures mapping rules →Conventions for every exchange are in the wire formats overview. Column types and units for order book data are in the schema below.
Use cases
Coverage
Every venue is stored under its own exchange ID, so spot and derivatives never mix. Bars show each venue's history from its first hourly file to today, or to its last file for a venue that is no longer collected. Symbol counts are live from the symbols API.
| Venue | Exchange ID | Market | History | Order book symbols |
|---|---|---|---|---|
| binance_futures | Futures | 2025-06-2817 mo | 919 | |
| binance_spot | Spot | 2025-06-2817 mo | 2,053 | |
| bybit | Futures | 2025-06-2817 mo | 1,543 | |
| bybit_spot | Spot | 2025-06-2817 mo | 829 | |
| okx_futures | Futures | 2025-06-2817 mo | 651 | |
| okx_spot | Spot | 2025-06-2817 mo | 1,661 | |
| bitget_futures | Futures | 2025-07-1516 mo | 1,211 | |
| bitget_spot | Spot | 2025-07-1516 mo | 1,127 | |
| kraken_derivatives | Futures | 2025-06-2817 mo | 653 | |
| kraken_spot | Spot | 2025-06-2817 mo | 1,671 | |
| hyperliquid_futures | Perpetuals | 2025-09-2914 mo | 458 | |
| hyperliquid_spot | Spot | 2025-09-2914 mo | 356 | |
| aster_futures | Futures | 2025-09-2914 mo | 664 | |
| bitmex | Futures | 2025-09-29 to 2026-09-2212 mo | 156 | |
| lighter | Perpetuals & Spot | 2025-12-3011 mo | 252 |
By exchange
Each exchange page covers its markets, verified history start, and a sample from that venue.
Schema · 13 columns
Every row represents one bid or ask price level inside a snapshot or incremental update. Rows carry exchange timing, sequence fields when available, price, quantity, and event type.
| Column | Type | Description |
|---|---|---|
| received_time | INT64 | Unix timestamp (nanoseconds) when our system received the event |
| event_time | INT64 | Unix timestamp when the exchange generated the event (the time unit changes with the exchange) |
| transaction_time | INT64nullable | Exchange-specific transaction timestamp (if available) |
| symbol | STRING | Trading pair symbol (for example, "BTCUSDT") |
| event_type | STRING | Type of order book event ("snapshot" or "update") |
| first_update_id | INT64nullable | First update ID in the update sequence |
| final_update_id | INT64nullable | Final update ID in the update sequence |
| prev_final_update_id | INT64nullable | Previous final update ID (to find gaps) |
| last_update_id | INT64nullable | Last update ID that the exchange processed |
| side | STRING | Order book side ("bid" or "ask") |
| price | STRING | Price level (stored as string for precision) |
| quantity | STRING | Quantity at the price level (stored as string for precision). The unit is the base asset on most venues. OKX derivatives use contracts, and BitMEX uses raw instrument units (refer to the venue notes) |
| order_count | INT64nullable | Number of orders at this price level (if the exchange gives it) |
Quickstart
The example loads BTCUSDT from Binance Futures for 2026-09-02. Change the symbol, exchange, or dates to pull any other slice of the archive.
pip install cryptohftdataSign up with email or Google, then generate a key from your dashboard. No credit card.
Create accountPaste the snippet, replace YOUR_API_KEY, and you get a pandas DataFrame with the columns listed above.
import cryptohftdata as chd
client = chd.CryptoHFTDataClient(api_key="YOUR_API_KEY")
df = client.get_orderbook(
symbol="BTCUSDT",
exchange=chd.exchanges.BINANCE_FUTURES,
start_date="2026-09-02",
end_date="2026-09-02",
)
print(df.head())
print(f"Order book rows: {len(df):,}")curl --fail --location \
"https://api.cryptohftdata.com/download?file=binance_futures/2026-09-02/12/BTCUSDT_orderbook.parquet" \
-o BTCUSDT_orderbook_12.parquetCaveats
Exchange feeds differ in subtle ways. These are the details that matter for accurate backtests, replay pipelines, and features. Missing hours and pending corrections for every venue are listed on Known Gaps & Corrections.
L2 order book data is aggregated by price level, not individual L3 orders.
Files contain snapshots plus incremental updates. Build state from a complete snapshot, apply later events in stored order, and reset whenever another snapshot appears.
Sequence fields vary by venue. If available continuity IDs show a gap, discard the local book and wait for a newer snapshot rather than replaying a state you cannot verify.
Quantities are in the venue's unit: base asset on most venues, contracts on OKX derivatives (multiply by the instrument's ctVal), and raw per-instrument units on BitMEX.
Hour-start checkpoint snapshots exist for Binance, Aster, OKX, Bybit, Bitget, Lighter, Kraken Futures and Hyperliquid, not for Kraken spot or BitMEX. A checkpoint is written only when the book is proven current, so some hours start without one; continue from the previous hour's book or wait for the next snapshot.
This page starts on 2025-06-28 based on the earliest stored hourly files for its covered exchange IDs and grows as new hourly files are published.
BitMEX (bitmex) is historical only: the exchange has closed and its files end on 2026-09-22.
FAQ
Yes. A free CryptoHFTData account with no credit card gives API access to this order book data and every other dataset. Individual hourly files can also be downloaded without an API key on the rate-limited free tier.
The earliest hourly files start on 2025-06-28, and new files are added every hour. Start dates differ by venue; the coverage table on this page lists each one.
Each file holds one symbol for one UTC hour, stored as Zstd-compressed Parquet under {exchange_id}/{YYYY-MM-DD}/{HH}/{SYMBOL}_orderbook.parquet. Parquet reads directly into pandas, Polars, DuckDB, and Arrow.
Install the SDK with pip install cryptohftdata, create a client with your API key, and call client.get_orderbook() with a symbol, exchange, and date range. It returns a pandas DataFrame.
L2. Each row is the aggregate quantity at one price level, recorded in snapshots and incremental updates. Individual orders (L3) and queue position are not included.
One free API key covers every exchange and every data type. $0.00.