WebSocket Streaming
Examples for real-time data streams using WebSocket subscriptions.
WebSocket subscriptions work without any credentials — only brokerId is needed.
Subscribe to Orderbook
Stream live orderbook updates for a market:
typescript
import { HundredX } from '100x-sdk';
// WebSocket works with read-only config
const sdk = new HundredX({ brokerId: 1 });
const subId = await sdk.ws.subscribeOrderbook(1, (data) => {
if (data.bids) {
console.log('Bids:');
for (const level of data.bids.slice(0, 5)) {
console.log(` ${level.price} x ${level.quantity}`);
}
}
if (data.asks) {
console.log('Asks:');
for (const level of data.asks.slice(0, 5)) {
console.log(` ${level.price} x ${level.quantity}`);
}
}
});Subscribe to Trades
Stream real-time trade data:
typescript
const tradeSubId = await sdk.ws.subscribeTrades(1, (trades) => {
for (const trade of trades) {
console.log(`[${trade.timestamp}] ${trade.side} ${trade.size} @ ${trade.price}`);
}
});Subscribe to Market Prices
Get orderbook data across all markets:
typescript
const priceSubId = await sdk.ws.subscribeMarketPrices((data) => {
if (data.marketId) {
const bestBid = data.bids?.[0]?.price || 'N/A';
const bestAsk = data.asks?.[0]?.price || 'N/A';
console.log(`Market ${data.marketId}: ${bestBid} / ${bestAsk}`);
}
});Unsubscribe
Each subscribe* call returns a subscription ID. Use it to unsubscribe:
typescript
// Unsubscribe from a specific stream
sdk.ws.unsubscribe(subId);
// Unsubscribe from everything
sdk.ws.unsubscribeAll();Build a Live Spread Monitor
typescript
async function spreadMonitor(marketId: number) {
let bestBid = '0';
let bestAsk = '0';
await sdk.ws.subscribeOrderbook(marketId, (data) => {
if (data.bids && data.bids.length > 0) bestBid = data.bids[0].price;
if (data.asks && data.asks.length > 0) bestAsk = data.asks[0].price;
const spread = parseFloat(bestAsk) - parseFloat(bestBid);
const mid = (parseFloat(bestBid) + parseFloat(bestAsk)) / 2;
const spreadBps = mid > 0 ? (spread / mid) * 10000 : 0;
console.log(`Spread: ${bestBid} / ${bestAsk} (${spreadBps.toFixed(1)} bps)`);
});
}
await spreadMonitor(1);Trade Volume Tracker
Track trade volume over a rolling window:
typescript
async function volumeTracker(marketId: number, windowMs: number = 60000) {
const recentTrades: { size: number; timestamp: number }[] = [];
await sdk.ws.subscribeTrades(marketId, (trades) => {
const now = Date.now();
for (const trade of trades) {
recentTrades.push({
size: parseFloat(trade.size),
timestamp: now,
});
}
// Remove expired trades
while (recentTrades.length > 0 && now - recentTrades[0].timestamp > windowMs) {
recentTrades.shift();
}
const volume = recentTrades.reduce((sum, t) => sum + t.size, 0);
console.log(`Volume (${windowMs / 1000}s window): ${volume.toFixed(4)}`);
});
}
await volumeTracker(1);Price Feed for Market Making
Use WebSocket prices to drive a market maker:
typescript
async function wsMarketMaker(marketId: number) {
// Need full credentials for trading
const sdk = await HundredX.create({
privateKey: process.env.PRIVATE_KEY!,
brokerId: Number(process.env.BROKER_ID!),
});
let currentMid = 0;
const SIZE = '0.5';
const SPREAD_BPS = 8;
// Stream prices
await sdk.ws.subscribeOrderbook(marketId, (data) => {
if (data.bids?.length && data.asks?.length) {
const bid = parseFloat(data.bids[0].price);
const ask = parseFloat(data.asks[0].price);
currentMid = (bid + ask) / 2;
}
});
// Refresh quotes every 2 seconds
setInterval(async () => {
if (currentMid === 0) return;
try {
await sdk.exchange.cancelAllOrders(marketId);
const halfSpread = currentMid * (SPREAD_BPS / 10000);
const bid = (currentMid - halfSpread).toFixed(2);
const ask = (currentMid + halfSpread).toFixed(2);
await sdk.exchange.placeOrder({
marketId,
isBuy: true,
amount: SIZE,
price: bid,
orderType: 'LIMIT',
});
await sdk.exchange.placeOrder({
marketId,
isBuy: false,
amount: SIZE,
price: ask,
orderType: 'LIMIT',
});
console.log(`Quoted: ${bid} / ${ask} (mid: ${currentMid.toFixed(2)})`);
} catch (error) {
console.error('Quote refresh error:', error);
}
}, 2000);
}
await wsMarketMaker(1);Multiple Market Subscriptions
typescript
const marketIds = [1, 2, 3];
const subscriptions: string[] = [];
for (const id of marketIds) {
const sub = await sdk.ws.subscribeOrderbook(id, (data) => {
const bid = data.bids?.[0]?.price || 'N/A';
const ask = data.asks?.[0]?.price || 'N/A';
console.log(`Market ${id}: ${bid} / ${ask}`);
});
subscriptions.push(sub);
}
// Cleanup
function cleanup() {
for (const sub of subscriptions) {
sdk.ws.unsubscribe(sub);
}
sdk.disconnect();
}
process.on('SIGINT', cleanup);Clean Shutdown
Always disconnect WebSocket connections when you're done:
typescript
// Option 1: Unsubscribe individually
sdk.ws.unsubscribe(subId);
// Option 2: Unsubscribe all and disconnect
sdk.ws.unsubscribeAll();
sdk.disconnect();