DEV Community

kalos
kalos

Posted on

How to Fetch US Stock Real-Time Quotes & Order Book Depth via API

US Stock Real-Time Quotes & Order Book: WebSocket Dynamic Subscription Practice

If you’re building quantitative trading systems or market analysis tools in FinTech, you’ve likely struggled with traditional market data interfaces. REST polling is prone to rate limits and high latency. Standard WebSocket requires full reconnection every time you add or remove subscribed symbols, which often triggers reconnection storms and duplicate calculations. Minor network fluctuations also cause silent Socket disconnections and interrupted data streams, severely impacting quantitative strategies.

After multiple rounds of selection and production tests, I adopted a WebSocket dynamic subscription solution. By reusing a single persistent connection, we successfully integrated real-time quotes and full order book depth for US stocks. This article shares the complete integration workflow, parameter configurations, production code and common pitfalls based on real-world experience.

1. Core Concept

What is Dynamic Subscription

Dynamic subscription allows you to add or remove symbol lists by sending standard commands on one persistent WebSocket connection. There is no need to disconnect or rebuild the link at any point.

It is fundamentally different from two traditional solutions:

  • REST polling: Fetch data via cyclic HTTP requests.
  • Conventional WebSocket: Rebuild connection whenever you modify subscription symbols.

Dynamic subscription updates your symbol list entirely over the existing connection.

2. Comparison of Market Data Interfaces

We evaluated three mainstream interface types for US stock tick data and multi-level order book depth, focusing on development difficulty, operation maintenance and online stability.

REST Interface

Easy to implement. However, cyclic HTTP requests easily hit rate limits under high-frequency scenarios. Data refresh is restricted by request intervals, which cannot keep up with tick-level market changes and dynamic order book updates. It is not suitable for quantitative or high-frequency trading.

Basic WebSocket

As a long connection solution, it delivers data with lower latency than REST. Its critical downside: you must close and recreate the connection to adjust subscriptions. Frequent operations lead to reconnection storms, inconsistent subscription status and distorted order book data.

WebSocket with Dynamic Subscription

This solution follows standard WSS protocols and divides endpoints by asset categories. It natively supports dynamic subscription, as well as order book snapshot + incremental updates. A single connection handles all symbol changes perfectly, making it the final choice for our production environment.

WSS endpoint for stock data:

wss://quote.alltick.co/quote-stock-b-ws-api?token=YOUR_TOKEN
Enter fullscreen mode Exit fullscreen mode

Dedicated endpoints are provided for forex, cryptocurrencies and other assets. The layered design simplifies unified operation and maintenance.

3. Parameter Configuration for Common Scenarios

Below are frequently used operations, corresponding issues and verification rules. All configurations comply with official interface specifications.

Application Scenario Common Issues Parameter Settings (cmd_id/action/code) Verification Standard
Initialize connection + bulk subscribe US stocks No market data on startup, malformed request cmd_id=22004, action=subscribe, code=[NASDAQ:AAPL,NASDAQ:TSLA] Send commands inside the on_open callback; verify full request via logs
Add new symbols during runtime Forced reconnection, redundant connections cmd_id=22004, action=subscribe, code=[new symbol codes] Original connection remains alive; sync local subscription list
Unsubscribe symbols during runtime Ghost subscription (redundant data after unsubscription) cmd_id=22004, action=unsubscribe, code=[target codes] Data stops pushing for target symbols; remove codes from local list
Send duplicate subscription requests Duplicate computation on client side cmd_id=22004, action=subscribe, code=[existing codes] Server ignores duplicates silently; add client-side deduplication
Send empty code list Abnormal connection drop caused by invalid parameters cmd_id=22004, action=subscribe/unsubscribe, code=[] Reject empty requests with client-side pre-validation

4. Core Advantages of Dynamic Subscription WebSocket

4.1 Avoid reconnection issues via connection reuse

We use cmd_id=22004 for all subscription commands. Symbols can be updated without destroying Sockets. This eliminates reconnection storms and data gaps, and ensures continuous quotes and order book data.

4.2 Higher transmission efficiency with categorized data

The interface splits market data into two parts:

  • Real-time quotes: Latest price, trading volume and top bid/ask prices.
  • Order book: Full snapshot for initialization, plus incremental updates for subsequent changes.

This design reduces network traffic and prevents disorder or jumping order book levels. Developers can easily analyze order density at different price levels.

4.3 Adapt to complex networks with built-in heartbeat

Native heartbeat detection works with custom heartbeat logic in code to identify Socket disconnections and network anomalies quickly. Official examples for Python, Java, Go and other languages lower the integration cost for multi-stack teams.

4.4 Wide asset coverage reduces maintenance costs

Apart from US stocks, the interface supports Hong Kong stocks, forex, precious metals and cryptocurrencies. One set of integration logic can be reused across multiple business scenarios.

5. Full Python Implementation Code

The following code strictly follows the single-connection dynamic subscription rule. It includes subscription state management, null value validation, exception handling and heartbeat keepalive. You can deploy it directly for US stock quote and order book development.

# Endpoint & subscription rules: Official API Docs
# WSS endpoint for stock data
# wss://quote.alltick.co/quote-stock-b-ws-api?token=YOUR_TOKEN
import websocket
import json

# Local set for subscription management and deduplication
subscriptions = set()
# Replace with your valid token
TOKEN = "YOUR_TOKEN"
WSS_URL = f"wss://quote.alltick.co/quote-stock-b-ws-api?token={TOKEN}"

def send_subscribe(ws, action, code_list):
    """Unified method for subscribe / unsubscribe, fixed cmd_id = 22004"""
    if not code_list:
        return
    req_data = {
        "cmd_id": 22004,
        "action": action,
        "code": code_list
    }
    try:
        ws.send(json.dumps(req_data))
    except Exception:
        return

def on_open(ws):
    """Callback after connection established: initial bulk subscription"""
    init_codes = ["NASDAQ:AAPL", "NASDAQ:TSLA"]
    global subscriptions
    subscriptions.update(init_codes)
    send_subscribe(ws, "subscribe", init_codes)
    print("WebSocket connected, initial subscription completed")

def on_message(ws, message):
    """Data callback: null check and parsing"""
    if not message:
        return
    try:
        data = json.loads(message)
        code = data.get("code", "")
        price = data.get("price", 0)
        open_24h = data.get("open_24h", 0)
        # Filter empty and invalid data
        if not code or price <= 0 or open_24h <= 0:
            return
        print(f"Market Update | Symbol: {code}, Latest Price: {price}")
    except json.JSONDecodeError:
        return

def on_error(ws, error):
    """Catch connection exceptions"""
    print(f"Connection error: {str(error)}")

def on_close(ws, close_code, close_msg):
    """Clear local state after connection closed"""
    global subscriptions
    subscriptions.clear()
    print(f"Connection closed, code: {close_code}")

# Initialize WebSocket instance
ws_app = websocket.WebSocketApp(
    WSS_URL,
    on_open=on_open,
    on_message=on_message,
    on_error=on_error,
    on_close=on_close
)

if __name__ == "__main__":
    # Dynamic subscription test (uncomment to enable)
    # send_subscribe(ws_app, "subscribe", ["NASDAQ:MSFT"])  # Add symbol
    # send_subscribe(ws_app, "unsubscribe", ["NASDAQ:TSLA"]) # Remove symbol
    # Start persistent connection with 10s heartbeat
    ws_app.run_forever(ping_interval=10)
Enter fullscreen mode Exit fullscreen mode

6. Troubleshooting Guide

Based on production operation experience, here are 4 common issues, detection methods and solutions.

6.1 Message backlog caused by high-frequency tick data

Phenomenon: Massive tick data arrives during active trading hours; callbacks get stuck and the program lags.
Detection: Check log timestamps for continuous message accumulation.
Solution: Split data parsing and business logic. Use asynchronous queues to transfer raw data; only keep filtering and forwarding inside callbacks.

6.2 Silent disconnection due to network jitter

Phenomenon: No on_close callback is triggered after temporary network outage, while data delivery stops.
Detection: Add a data receiving timeout timer.
Solution: Combine native heartbeat with application-layer timeout logic. Disconnect and reconnect orderly when timeout occurs.

6.3 State mismatch from frequent subscription operations

Phenomenon: Rapid add/remove requests lead to inconsistent states between local list and server, causing ghost subscription.
Detection: Compare local subscription records with received data.
Solution: Add serial locks for subscription operations. Sync the local list after every operation.

6.4 Silent failure from incorrect symbol format

Phenomenon: Using short codes like AAPL results in no data received, without explicit errors.
Detection: Verify code field against official symbol rules.
Solution: Standardize symbols with Exchange:Code format and add format validation in advance.

7. Function Limitations

  • ✅ Supported: Dynamically add or remove symbol lists within a single WebSocket connection.
  • ❌ Not supported: Sync subscription status across multiple connections, retrieve historical tick data, or use private commands other than cmd_id=22004.

8. Production Outcome

This architecture stably supports real-time quotes and multi-level order book data in production. After deploying dynamic subscription:

  • Connection reconstruction is eliminated, and reconnection-related failures drop significantly.
  • Snapshot + incremental update reduces data volume and completely fixes order book disorder and jumping issues.

All data flows, command interactions and exceptions can be reproduced via logs and verified against official documents. This reliable solution fits quantitative strategies, market analysis tools and financial data services perfectly.

Top comments (0)