Overview

Real-time market data via WebSocket.

Real-time market data via WebSocket. Subscribe to order books, trades, tickers, prices, candlesticks, and open interest across supported exchanges.

WebSocket URL: wss://md.liquiditytech.com/marketdata/v2/public

Supported exchanges: BINANCE / OKX / EDX


Connection

Responses are GZIP-compressed by default. To receive plain text, append ?binary=false to the URL:

wss://md.liquiditytech.com/marketdata/v2/public?binary=false

To decompress in Python:

import zlib

# binary_data is the raw bytes received from ws.recv()

decompressed = zlib.decompress(binary_data, zlib.MAX_WBITS | 16).decode('utf-8')

Authentication

Authentication is optional. Unauthenticated connections work immediately but have lower rate limits.

To authenticate, send a login message after connecting and before subscribing

{
    "action": "login",
    "args": {
        "apiKey": "your_api_key",
        "timestamp": "1597026383085",
        "sign": "your_signature"
    }
}

Note: the login message uses "action" and "args" (an object), while subscribe/unsubscribe messages use "event" and "arg" (an array). These are different field names.

Signature: HMAC-SHA256(secret, timestamp + "GET" + "/users/self/verify"), hex-encoded.

import hmac, hashlib, time

api_key = "your_api_key"
secret  = "your_secret_key"

timestamp = str(int(time.time()))
message = timestamp + "GET" + "/users/self/verify"
sign = hmac.new(secret.encode(), message.encode(), hashlib.sha256).hexdigest()

Response:

{ "event": "login", "code": "200000", "msg": "success" }

Rate Limits

UnauthenticatedAuthenticated
Max connections per IP540
Max trading pairs per connection550

Subscription rate: max 50 subscribe/unsubscribe requests per second per IP. Exceeding this returns error 11260.

Limits are counted by trading pair, not by channel. Subscribing to TICKER, ORDER_BOOK, and TRADE for the same symbol counts as 1 trading pair.


Heartbeat

The server sends a WebSocket protocol-level ping shortly after the connection is established. Most WebSocket client libraries handle this automatically.

The connection is closed if the client is inactive for 60 seconds. To keep the connection alive, the client must send a JSON ping at regular intervals (recommended: every 20 seconds):

The client can also send a ping at any time:

{ "ping": 1769050973831 }

Server response:

{ "pong": 1769050974552 }

For subscribed connections receiving frequent pushes (e.g. TICKER, BBO), the data flow itself keeps the connection alive. Explicit pings are only required when subscribed to low-frequency or no channels.


Symbol Format

Symbols follow the pattern {EXCHANGE}_{TYPE}_{BASE}_{QUOTE}:

PartValuesExample
EXCHANGEBINANCE / OKX / EDXBINANCE
TYPESPOT / PERP (perpetual futures)PERP
BASEBase currencyBTC
QUOTEQuote currencyUSDT

Examples: BINANCE_PERP_BTC_USDT, OKX_SPOT_ETH_USDT

Futures-only channels (MARK_PRICE, INDEX_PRICE, OPEN_INTEREST, etc.) require a PERP symbol. Using a SPOT symbol with these channels returns error 11100.


Subscribe & Unsubscribe

Multiple channels can be included in a single request.

Subscribe:

{
    "event": "subscribe",
    "arg": [
        { "channel": "TICKER", "sym": "BINANCE_PERP_BTC_USDT" },
        { "channel": "ORDER_BOOK", "sym": "OKX_SPOT_ETH_USDT", "level": 50 }
    ]
}

Unsubscribe:

{
    "event": "unsubscribe",
    "arg": [
        { "channel": "TICKER", "sym": "BINANCE_PERP_BTC_USDT" }
    ]
}

Success response:

{
    "event": "subscribe",
    "arg": [{ "channel": "TICKER", "sym": "BINANCE_PERP_BTC_USDT" }],
    "code": 0,
    "message": "Success"
}

Failure response:

{
    "event": "subscribe",
    "arg": [{ "channel": "TICKER", "sym": "INVALID_SYM" }],
    "code": 11100,
    "message": "invalid symbols"
}

All channel names must be uppercase. Using lowercase returns error 11103.


Available Channels

ChannelDescriptionPush FrequencyScope
TICKER24-hour rolling ticker2000msAll
ORDER_BOOKOrder book depth250msAll
BBOBest bid & offerOn changeAll
TRADELatest tradesReal-timeAll
MARK_PRICEMark priceReal-timeFutures only
INDEX_PRICEIndex priceReal-timeFutures only
KLINECandlestick (trade price)Real-timeAll
INDEX_KLINECandlestick (index price)Real-timeFutures only
MARK_PRICE_KLINECandlestick (mark price)Real-timeFutures only
OPEN_INTERESTContract open interestReal-timeFutures only

Error Codes

CodeDescription
200000Login successful
11100Invalid symbol
11101Invalid candlestick interval
11102Invalid event type
11103Invalid channel name (must be uppercase)
11106Unknown protocol version
11107Depth data not found
11108Response too long
11109Too many symbols subscribed
11112Invalid depth level
11200Invalid request parameter
11210Exceeded 5-symbol limit (unauthenticated)
11220Exceeded 50-symbol limit (authenticated)
11230Exceeded 5-connection limit (unauthenticated)
11240Exceeded 40-connection limit (authenticated)
11250Symbol not currently supported
11260Exceeded 50 requests/second limit