When we started building out our crypto trading infrastructure, we quickly ran into a challenge that sounds simple but is actually a deep engineering problem: turning a firehose of incremental order book updates from a cryptocurrency API into a continuously accurate local representation of the market. This post is the guide we wish we’d had back then, written from the perspective of a team of independent high-frequency traders. We’ll cover the requirements, the data pain points, the specific product-level solutions we built, and how it all fits into real industry applications.
What Problem Are We Solving?
We need a local order book that accurately reflects the exchange’s live state. Every strategy — from quoting to statistical arbitrage to liquidity analysis — depends on this ground truth. But the API doesn’t send us a full picture; it sends small incremental patches.
Data Pain Points: Understanding What You’re Actually Receiving
Incremental Updates Are Instructions, Not States
A full order book contains every active bid and ask level with their respective quantities. However, pushing the entire book on each change would be prohibitively bandwidth-heavy. Instead, cryptocurrency APIs use incremental feeds that deliver only the modified levels. You’ll see something like:
| Direction | Price | Quantity Change |
|---|---|---|
| Buy | 65000 | +0.5 |
| Sell | 65010 | -1 |
Think of this as a log entry: “Apply this delta.” You cannot interpret it in isolation; you must maintain your own state and apply each delta in sequence. If you treat each delta as an independent event, the order of application can get scrambled, and your local book will drift from reality.
Sequence Numbers Are Your Only Safeguard
Network transport means messages can arrive out of order. A later message might reach your server before an earlier one. If you apply them by arrival time, the state becomes logically corrupted. Our solution is strict sequence-number discipline. The API provides a sequence or updateId with every message. Our rule:
- Get a full snapshot and record its sequence number.
- Buffer all subsequent deltas.
- Only apply deltas whose sequence number is exactly one greater than our current state.
- If a sequence gap appears, discard the local state and re-fetch a fresh snapshot.
This ensures we never build on a broken foundation.
Product Functionality: Designing the Local Book and Connection
Use a Dictionary, Not a List
Early on, we used arrays for price levels. As the number of levels grew, update performance tanked. Now we use dictionaries (maps) keyed by price:
order_book = {
"bids": {
65000: 1.5,
64999: 2.0
},
"asks": {
65001: 1.8,
65002: 3.1
}
}
On each delta: if new quantity > 0, set the price key; if quantity == 0, delete the key. This structure makes getting best bid/ask and calculating depth extremely fast.
WebSocket for Low-Latency Feeds
HTTP polling introduces unacceptable latency for order book updates. We always use WebSocket connections. While integrating one feed, we based our initial handler on the AllTick API WebSocket market data pattern. The core processing loop is:
import websocket
import json
order_book = {
"bids": {},
"asks": {}
}
def update_order_book(data):
for item in data.get("bids", []):
price = float(item["price"])
volume = float(item["volume"])
if volume == 0:
order_book["bids"].pop(price, None)
else:
order_book["bids"][price] = volume
for item in data.get("asks", []):
price = float(item["price"])
volume = float(item["volume"])
if volume == 0:
order_book["asks"].pop(price, None)
else:
order_book["asks"][price] = volume
def on_message(ws, message):
data = json.loads(message)
if data.get("symbol") == "BTCUSDT":
update_order_book(data)
print(order_book)
ws = websocket.WebSocketApp(
"wss://apis.alltick.co/websocket-api",
on_message=on_message
)
ws.run_forever()
This is the foundation. Wrap it with sequence validation, heartbeat checks, and automatic snapshot recovery on disconnect for a production-grade system.
Industry Applications: Where Accurate Depth Matters
We use this book for market making, arbitrage signals, and real-time liquidity monitoring. A small consistent error in depth data can gradually erode profitability. Two additional notes from our production experience:
- After a WebSocket disconnect, the local book is outdated. Reconnect logic must fetch a fresh snapshot first, then resume deltas.
- Price precision: avoid floating-point keys. Convert all prices to integers based on the tick size to prevent matching errors.
Accurate order book reconstruction is not just about receiving data; it’s about synchronizing a distributed state. Get this right, and your trading strategies have a solid foundation.

Top comments (0)