Ever timed how long your REST loop takes to grab quotes for all ~500 Hong Kong Stock Connect stocks? I did. It took 96 seconds, and the API throttled me halfway through. As an active intraday trader, I can’t afford my data arriving later than my edge.
So I ripped out the polling logic and piped everything through a single WebSocket connection. Now I get tick-by-tick updates in under 50ms, and I haven’t looked back. Let me show you how you can do the same, even if you’re a solo dev.
Why REST Polling is a Trap for Live Market Data
Polling 500+ stocks means 500+ HTTP round trips. Each trip costs connection overhead, and APIs will rate-limit you into oblivion. WebSocket lets you subscribe to hundreds of instruments in one go and passively receive updates. For my setup, I used the AllTick WebSocket API because it handles bulk HK Stock Connect subscriptions without hassle.
Architecture Overview
I like to keep things modular:
-
Symbol Service: Fetches Stock Connect components and appends
.HK. - Connection Manager: Handles WebSocket lifecycle, batches subscriptions, and sends pings.
- Tick Processor: Parses incoming JSON, maps fields to a standard schema, and queues them.
- Storage Agent: Dumps queued ticks into a database asynchronously, plus a reconnection watchdog.
| Module | Responsibility | Pro Tip |
|---|---|---|
| Symbol Service | Maintain a clean ticker list | Filter out suspended stocks |
| Connection Manager | Subscribe in batches, keep alive | Respect the max symbols per frame |
| Tick Processor | Deserialize and normalize | Use .get() to handle optional fields |
| Storage Agent | Async persistence + reconnect | Queue approach avoids back-pressure |
Show Me the Code
import websocket
import json
def on_message(ws, message):
# Parse pushed tick data
data = json.loads(message)
for tick in data.get("ticks", []):
# Swap print with your queue/db writer in production
print(f"{tick['symbol']} Price: {tick['price']} Volume: {tick['volume']}")
def on_open(ws):
# Batch subscribe to HK Stock Connect symbols
tickers = ["00700.HK", "09988.HK", "02628.HK"]
ws.send(json.dumps({"action": "subscribe", "symbols": tickers}))
ws = websocket.WebSocketApp("wss://api.alltick.co/stock/ws",
on_message=on_message,
on_open=on_open)
ws.run_forever()
Life After the Migration
These days, I fire up my trading terminal, glance at the green connection indicator, and immediately start watching real-time heatmaps and volume anomaly dashboards. Debugging data gaps has dropped to near zero. If you’re still polling your market data, do yourself a favor: swap to WebSocket and reclaim both your latency and your sanity.

Top comments (0)