Market holidayJapan will be closed on 2026-11-03 (Culture Day), 5 days from now.All announcements
Article

Crypto WebSocket Data, Normalized: One Stream for Every Market (Python)

Every exchange speaks a different dialect. TIQEX normalizes crypto, futures, and FX WebSocket data into one JSON shape — one subscribe, one consumer, every market. Full Python example inside.

The normalization problem in crypto market data

Ask five exchanges for "the latest trade" and you get five different answers: different field names, different timestamp units, different ideas of what a symbol is called. Every quant desk, terminal, and dashboard ends up maintaining the same unglamorous translation layer — exchange dialect in, clean schema out — before any real work begins.

A normalized crypto WebSocket feed removes that layer. One subscribe message, one JSON response shape, whether the tick is BTC spot, a continuous future, or an FX pair. You write the consumer once and point it at any market.

What TIQEX's normalized stream looks like

From the official docs (https://tiqex.io/developers), the entire streaming contract is two lines:

wss://api.tiqex.io/api/v1/market/stream
{ "action": "subscribe", "market": "crypto", "symbols": ["BTCUSDT"] }

That's it. Send a subscribe JSON with market and symbols; the stream pushes ticks back in a consistent JSON shape. The docs explicitly call out:

  • Millisecond delivery for terminals, dashboards, and strategy runtimes
  • Batch multi-symbol subscriptions — one socket, many symbols
  • REST + WebSocket pairing — "Use REST for snapshots and historical candles; WebSocket for live ticks. Same API key. Stream handshake counts once; pushed ticks are not re-billed."

Authentication is the same X-API-Key header pattern as REST:

Bash
curl https://api.tiqex.io/api/v1/market/crypto/quote?symbols=BTCUSDT \
  -H "X-API-Key: YOUR_API_KEY"

Keep keys server-side; never ship them in public frontend bundles.

Putting it to work: a normalized multi-market consumer

Because the response shape is consistent, one handler serves every subscription:

Python
import json, websocket

WS_URL = "wss://api.tiqex.io/api/v1/market/stream"

def on_message(ws, raw):
    msg = json.loads(raw)
    # same fields whether this is crypto, futures, FX, or equities —
    # field names here are illustrative; confirm against the endpoint
    # reference in the docs before production use
    handle_tick(market=msg.get("market"), symbol=msg.get("symbol"),
                price=float(msg.get("price", 0)), ts=msg.get("ts"))

def handle_tick(market, symbol, price, ts):
    # your normalization layer is now ~5 lines instead of 5 files
    store(market, symbol, price, ts)

def on_open(ws):
    # subscribe only after the socket is connected —
    # sending before run_forever() raises WebSocketConnectionClosedException
    ws.send(json.dumps({"action": "subscribe", "market": "crypto",
                        "symbols": ["BTCUSDT", "ETHUSDT"]}))

ws = websocket.WebSocketApp(WS_URL,
                            header={"X-API-Key": "YOUR_API_KEY"},
                            on_open=on_open,
                            on_message=on_message)
ws.run_forever()

The docs also provide heartbeat and reconnect guidance — for a strategy runtime, wire on_close to exponential-backoff resubscribe rather than crashing the loop.

Honest limits (from the docs FAQ)

  • Plan-gated: "Upgrade for WebSocket, lower latency, higher quotas, or more markets in production." Check console entitlements before assuming stream access on a free key.
  • Varies by market: "Latency, field granularity, and history depth vary by market and plan."
  • Consolidated, not raw: "Output may not match any single exchange tick-for-tick." If your strategy depends on exchange-specific sequencing, this is a feature summary feed, not a replacement for the exchange's native socket.
  • Symbol codes: crypto uses BTCUSDT-style codes; other markets accept product short codes or TV symbols — see each endpoint's parameter table and the console symbol lists rather than guessing.

When normalization pays for itself

  • Cross-venue dashboards: one charting component, N markets, zero per-exchange parsers.
  • Strategy portability: develop against crypto ticks, deploy the same consumer on futures or FX by changing the market field.
  • Backtest/live parity: REST candles for history plus WebSocket ticks for live, in one schema — your offline features and online features finally agree.

One key, one subscribe shape, one JSON schema. Grab a key at tiqex.io and replace your exchange-dialect translation layer with five lines of code.