Skip to content

WebSocket Integration

This guide explains how to integrate with the TradeX Market Data WebSocket API for real-time market data streaming.

The Market Data Service provides a WebSocket API for real-time market data including trades, order books, tickers, candles, mark prices, index prices, and funding rates.

ws://localhost:8080/ws

For production with TLS:

wss://marketdata.dokploy.samarpit.dev/ws
  1. Connect: Establish WebSocket connection
  2. Subscribe: Send subscription messages
  3. Receive Updates: Process real-time updates
  4. Keep-Alive: Respond to ping messages
  5. Disconnect: Close connection when done
{
"op": "operation_name",
"channels": [...],
"data": {...},
"price_rounding": 0.5
}
{
"op": "update",
"channel": "channel_name",
"symbol": "SYMBOL",
"data": {...}
}

Subscribe to one or more channels:

{
"op": "subscribe",
"channels": [
{
"name": "book",
"symbols": ["BTCUSDT-PERP", "ETHUSDT-PERP"],
"price_rounding": 0.5
},
{
"name": "ticker",
"symbols": ["BTCUSDT-PERP"]
}
]
}
{
"op": "unsubscribe",
"channels": [
{
"name": "book",
"symbols": ["BTCUSDT-PERP"]
}
]
}
{
"op": "ping"
}

Server responds with pong.

Configure client settings:

{
"op": "config",
"price_rounding": 1.0
}

Real-time trade execution updates (batched every 100ms):

{
"op": "update",
"channel": "trades",
"symbol": "BTCUSDT-PERP",
"data": [
{
"price": "67850.50",
"quantity": "0.025",
"side": "BUY",
"trade_id": "uuid",
"timestamp": 1732105234123
}
]
}

Order book updates with delta messages:

{
"op": "update",
"channel": "book",
"symbol": "BTCUSDT-PERP",
"data": {
"bids": [
{"price": "67850.00", "quantity": "1.5"}
],
"asks": [
{"price": "67851.00", "quantity": "1.2"}
],
"delta": true
}
}

24h ticker statistics and LTP updates:

{
"op": "update",
"channel": "ticker",
"symbol": "BTCUSDT-PERP",
"data": {
"type": "ltp",
"price": "67850.50",
"quantity": "0.025",
"side": "BUY",
"trade_id": "uuid",
"timestamp": 1732105234123
}
}

Candlestick updates:

{
"op": "update",
"channel": "candle:1m",
"symbol": "BTCUSDT-PERP",
"data": {
"interval": "1m",
"open": "67800.00",
"high": "67850.50",
"low": "67750.00",
"close": "67830.00",
"volume": "125.5",
"openTime": 1732105200000,
"closeTime": 1732105259999
}
}

Available intervals: 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w

Mark price updates:

{
"op": "update",
"channel": "mark",
"symbol": "BTCUSDT-PERP",
"data": {
"symbol": "BTCUSDT-PERP",
"mark_price": "67850.25",
"index_price": "67800.00",
"timestamp": 1732105234123
}
}

Index price updates:

{
"op": "update",
"channel": "index",
"symbol": "BTCUSDT-INDEX",
"data": {
"price": "67800.00",
"components": [...],
"timestamp": 1732105234123
}
}

Funding rate updates:

{
"op": "update",
"channel": "funding",
"symbol": "BTCUSDT-PERP",
"data": {
"funding_rate": "0.0001",
"mark_price": "67850.25",
"index_price": "67800.00",
"next_funding_time": 1732105300000,
"countdown_seconds": 3600,
"timestamp": 1732105234123
}
}
const ws = new WebSocket('wss://marketdata.dokploy.samarpit.dev/ws');
ws.onopen = () => {
// Subscribe to channels
ws.send(JSON.stringify({
op: 'subscribe',
channels: [
{
name: 'book',
symbols: ['BTCUSDT-PERP'],
price_rounding: 0.5
},
{
name: 'ticker',
symbols: ['BTCUSDT-PERP']
}
]
}));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
switch (message.op) {
case 'subscribed':
console.log('Subscribed:', message.data.channels);
break;
case 'update':
handleUpdate(message);
break;
case 'pong':
console.log('Received pong');
break;
case 'error':
console.error('Error:', message.data.message);
break;
}
};
function handleUpdate(message) {
switch (message.channel) {
case 'book':
if (message.data.delta) {
// Apply delta to local order book
} else {
// Initialize with snapshot
}
break;
case 'ticker':
if (message.data.type === 'ltp') {
console.log('LTP:', message.data.price);
}
break;
}
}
// Send ping every 30 seconds
setInterval(() => {
ws.send(JSON.stringify({ op: 'ping' }));
}, 30000);
import asyncio
import websockets
import json
async def subscribe():
uri = "wss://marketdata.dokploy.samarpit.dev/ws"
async with websockets.connect(uri) as websocket:
# Subscribe
subscribe_msg = {
"op": "subscribe",
"channels": [
{
"name": "book",
"symbols": ["BTCUSDT-PERP"],
"price_rounding": 0.5
}
]
}
await websocket.send(json.dumps(subscribe_msg))
# Listen for messages
async for message in websocket:
data = json.loads(message)
if data["op"] == "update":
channel = data["channel"]
symbol = data["symbol"]
payload = data["data"]
if channel == "book":
print(f"Book update for {symbol}: {payload}")
asyncio.run(subscribe())
{
"op": "error",
"data": {
"message": "Error description"
}
}
let ws;
let subscriptions = [];
function connect() {
ws = new WebSocket('wss://marketdata.dokploy.samarpit.dev/ws');
ws.onopen = () => {
// Re-subscribe to all channels
subscriptions.forEach(sub => {
ws.send(JSON.stringify({
op: 'subscribe',
channels: sub
}));
});
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = () => {
console.log('Connection closed, reconnecting...');
setTimeout(connect, 1000);
};
}
connect();
  • Default: 100 messages per second per client
  • Configurable: Via WS_RATE_MAX_MSGS_PER_SEC
  • Messages exceeding limit are silently dropped
  1. Reconnection: Implement automatic reconnection with exponential backoff
  2. Re-subscription: Re-subscribe to channels on reconnect
  3. Error Handling: Handle errors gracefully
  4. Message Buffering: Buffer messages during reconnection
  5. Price Rounding: Use price rounding to reduce bandwidth
  6. Selective Subscription: Only subscribe to needed channels and symbols