DEV Community

EmilyL
EmilyL

Posted on

Stop Polling! Stream Real-Time Hong Kong Stock Connect Prices with Python and WebSockets

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()
Enter fullscreen mode Exit fullscreen mode

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)