Hey devs! 👋 We want to share a practical recipe that has become a staple in our quantitative data pipeline: streaming a cryptocurrency order book in real time and maintaining an exact local copy using Python. If you’ve ever needed reliable market depth for your app, bot, or analysis notebook, this setup will give you full ownership of the data.
The Problem with Polling
REST endpoints give you a static snapshot of the order book. That’s okay for low-frequency dashboards, but if you need up-to-the-millisecond accuracy—for example, when computing slippage or order flow signals—polling introduces gaps that ruin the picture. You need a persistent WebSocket stream that pushes every change as it happens.
Ingredients
- WebSocket client to receive live data.
- Snapshot for initializing the book.
- Diffs for keeping it current.
- SortedDict to store bids and asks efficiently.
We used sortedcontainers because it keeps items in order and supports fast insertions/deletions. Bids are sorted descending, asks ascending.
from sortedcontainers import SortedDict
# Bids: highest price first
bids = SortedDict(lambda x: -x)
# Asks: lowest price first
asks = SortedDict()
Step-by-Step Code
Connect to a WebSocket endpoint that provides snapshot and diff messages. We’ve had good experiences with AllTick’s feed, as the data format is clean and well-documented. Here’s the full minimal example:
import websocket
import json
from sortedcontainers import SortedDict
bids = SortedDict(lambda x: -x)
asks = SortedDict()
def on_message(ws, message):
data = json.loads(message)
# Update both sides of the book
process_orderbook(data)
def process_orderbook(data):
global bids, asks
for update in data.get("bids", []):
price, size = update
if size == 0:
bids.pop(price, None)
else:
bids[price] = size
for update in data.get("asks", []):
price, size = update
if size == 0:
asks.pop(price, None)
else:
asks[price] = size
ws = websocket.WebSocketApp("wss://api.alltick.co/crypto/orderbook",
on_message=on_message)
ws.run_forever()
Making It Production-Ready
The snippet above works for experimentation, but for anything serious you’ll want:
- Sequence verification on diffs to detect gaps.
- Automatic snapshot reload if a gap is found.
- Heartbeat and auto-reconnect for the WebSocket connection.
Implementing these guards turns a fragile script into a self-healing service.
Visual Feedback
During development, we often plot the order book using matplotlib to sanity-check the data:
import matplotlib.pyplot as plt
def plot_orderbook():
plt.plot(list(bids.keys()), list(bids.values()), color='green', label='Bids')
plt.plot(list(asks.keys()), list(asks.values()), color='red', label='Asks')
plt.legend()
plt.show()
Green shows the bid side, red the ask side. Any sudden gap or spike immediately reveals a synchronization issue.
Wrapping Up
With a few dozen lines of Python, you can maintain a real-time, exchange-accurate order book locally. This opens the door to custom indicators, low-latency alerts, and strategy backtesting on consistent data. Give it a try—it’s one of those building blocks that pays dividends across many projects.

Top comments (0)