In quantitative trading, cross-border investment research, market surveillance, and high-frequency strategies, millisecond-level real-time feeds combined with granular tick-level execution data represent core infrastructure assets. Compared to conventional OHLC bars or Level 1 snapshots, tick-by-tick (trade-by-trade) data reconstructs the true microstructure of every executed transaction, while real-time streaming ensures minimal latency for time-sensitive decisions.
Global equity markets are fragmented across exchanges with differing protocols, latency profiles, and data licensing rules. This article provides a practical, code-first guide to efficiently integrate comprehensive global stock market data — covering real-time Level 1 quotes, trade ticks, order book depth, and historical bars — using both REST and WebSocket interfaces provided by iTick (https://itick.org/en).
1. REST API — Fast Retrieval of Snapshots and Batch Data
REST endpoints are ideal for on-demand queries, batch initialization, backtesting data collection, or scenarios where update frequency is moderate.
Base URL: https://api.itick.org
Authentication: Bearer Token passed via HTTP header
1.1 Real-Time Quote (Level 1)
import requests
API_TOKEN = "your_token_here"
region = "US" # US | HK | SH | SZ | ...
symbol = "AAPL"
url = f"https://api.itick.org/stock/quote?region={region}&code={symbol}"
headers = {"accept": "application/json", "token": API_TOKEN}
resp = requests.get(url, headers=headers)
if resp.status_code == 200:
payload = resp.json()
if payload.get("code") == 0:
q = payload["data"]
print(f"{q['s']:>12} Last: {q['ld']:>10.3f} Chg%: {q['chp']:>6.2f}% Vol: {q['v']:>12,d}")
else:
print("API Error:", payload.get("msg"))
else:
print("HTTP", resp.status_code)
Key fields:
-
ld— Last traded price -
chp— Percentage change -
v— Cumulative trading volume -
o/h/l/c— Session open/high/low/previous close
1.2 Recent Trade Ticks (Tick History)
The /tick endpoint returns the most recent executed trades (useful for warm-up, snapshot analysis, or micro-structure studies).
url = f"https://api.itick.org/stock/tick?region=HK&code=00700" # Tencent
# ... same headers & error handling ...
ticks = payload["data"]
for t in ticks[:8]:
ts = t["t"] # timestamp (usually ms or ISO)
price = t["p"]
size = t["v"]
print(f"{ts} | {price:>8.3f} × {size:>10,d}")
Note: REST /tick normally delivers a limited lookback window. For continuous, streaming tick updates → use WebSocket (section 2).
1.3 Order Book Depth (Level 2 Snapshot)
url = f"https://api.itick.org/stock/depth?region=SH&code=600519" # Kweichow Moutai
# ...
depth = payload["data"]
print("Bids:")
for bid in depth["b"][:5]: # top 5 bid levels
print(f" {bid['p']:>10.3f} {bid['v']:>12,d}")
print("Asks:")
for ask in depth["a"][:5]:
print(f" {ask['p']:>10.3f} {ask['v']:>12,d}")
1.4 Historical Bars
Supports multiple timeframes: 1-min, 5-min, ..., daily, weekly, monthly.
ktype = "2" # 1=1m, 2=5m, 3=15m, 4=30m, 5=1h, 6=2h, 7=4h, 8=1d, 9=1w, 10=1M
limit = 250
url = f"https://api.itick.org/stock/kline?region=US&code=MSFT&kType={ktype}&limit={limit}"
# ...
for bar in payload["data"]:
print(f"{bar['t']} O:{bar['o']:>8.2f} H:{bar['h']:>8.2f} L:{bar['l']:>8.2f} C:{bar['c']:>8.2f} V:{bar['v']:>12,d}")
2. WebSocket — Ultra-Low-Latency Streaming (Quotes • Ticks • Depth)
For latency-critical applications (HFT prototypes, live risk monitors, execution algos), WebSocket streaming is strongly preferred over polling.
Endpoint: wss://api.itick.org/stock
Authentication: Token in connection header
Supported subscriptions: quote, tick, depth
Below is a robust, production-ready Python client with auto-reconnect, heartbeat, and structured logging.
import websocket
import json
import threading
import time
from loguru import logger
class iTickWSClient:
def __init__(self, token: str, symbols: list[str], types: str = "quote,tick,depth"):
self.token = token
self.symbols = symbols # ["AAPL$US", "00700$HK", "600519$SH"]
self.types = types
self.url = "wss://api.itick.org/stock"
self.ws = None
self.connected = False
self.thread = None
def on_message(self, ws, message):
try:
msg = json.loads(message)
if "data" in msg:
d = msg["data"]
typ = d.get("type")
sym = d.get("s")
if typ == "tick":
logger.info(f"TICK {sym:>12} {d.get('t')} {d.get('p'):>9.3f} × {d.get('v'):>10,d}")
elif typ == "quote":
logger.info(f"QUOTE {sym:>12} Last {d.get('ld'):>9.3f} {d.get('chp'):>6.2f}%")
elif typ == "depth":
b1 = d["b"][0] if d.get("b") else None
logger.debug(f"DEPTH {sym:>12} Bid1 {b1['p'] if b1 else '—':>9} × {b1['v'] if b1 else '—':>10,d}")
except Exception as e:
logger.exception("Parse error")
def on_error(self, ws, err): logger.error(f"WS error: {err}")
def on_close(self, ws, code, msg):
logger.warning(f"Closed {code} — {msg}")
self.connected = False
time.sleep(3)
self.start()
def on_open(self, ws):
logger.success("WebSocket connected")
self.connected = True
self.subscribe()
def subscribe(self):
payload = {
"ac": "subscribe",
"params": ",".join(self.symbols),
"types": self.types
}
self.ws.send(json.dumps(payload))
logger.info(f"Subscribed → {self.symbols} types={self.types}")
def heartbeat(self):
while self.connected:
time.sleep(30)
try:
self.ws.send(json.dumps({"ac": "ping", "params": str(int(time.time()*1000))}))
except:
pass
def start(self):
self.ws = websocket.WebSocketApp(
self.url,
header={"token": self.token},
on_open=self.on_open,
on_message=self.on_message,
on_error=self.on_error,
on_close=self.on_close
)
threading.Thread(target=self.ws.run_forever, daemon=True).start()
threading.Thread(target=self.heartbeat, daemon=True).start()
# ────────────────────────────────────────────────
if __name__ == "__main__":
logger.add("itick.log", rotation="500 MB", level="INFO")
client = iTickWSClient(
token="your_token_here",
symbols=["AAPL$US", "00700$HK", "600519$SH"],
types="quote,tick"
)
client.start()
try:
while True: time.sleep(1)
except KeyboardInterrupt:
client.ws.close()
3. Key Production Considerations & Best Practices
| Market | Region | Example Ticker | Format Notes |
|---|---|---|---|
| US | US | AAPL, TSLA | Plain English ticker |
| Hong Kong | HK | 00700, 09988 | Numeric, no prefix |
| Shanghai | SH | 600519 | 6-digit |
| Shenzhen | SZ | 000001, 300750 | 6-digit |
-
Batch requests — Change
code→codesand use comma-separated list (e.g./stock/quotes?region=US&codes=AAPL,MSFT,NVDA) - Rate limits & pricing → Free tier exists; production usage typically requires a paid plan (see https://itick.org/en/pricing)
- Reconnection logic — Essential in production. Exponential back-off + jitter recommended.
- Caching — Cache static/reference data (bars, symbol master) locally; rely on WebSocket for mutable real-time fields.
- Latency optimization — Co-locate near data centers if pursuing sub-10 ms execution; otherwise regional cloud instances usually suffice.
Summary
Combining REST for initialization/backfills with WebSocket for live streaming delivers a robust, low-latency global equity data pipeline suitable for quant research, algo development, risk dashboards, and fintech products.
Start by obtaining an API key at https://itick.org/en, experiment with the code samples above, and progressively integrate the feed into your strategy engine or time-series database.
Market data is mission-critical infrastructure — treat latency, completeness, and uptime accordingly.
GitHub examples & community: https://github.com/itick-org/
Top comments (0)