WebSocket Crypto: Real-Time Price Feeds for Traders
Learn how WebSocket crypto APIs deliver live price data with zero lag. Compare CryptoCompare, Alpaca, Binance, and other top options with working code examples.
Learn how WebSocket crypto APIs deliver live price data with zero lag. Compare CryptoCompare, Alpaca, Binance, and other top options with working code examples.
If you've ever watched a crypto chart refresh every few seconds while a trade slips away, you already understand the problem REST APIs can't solve. WebSocket crypto connections keep a persistent channel open between your app and the exchange — prices stream in the moment they change, not when you decide to ask. For scalpers, algo traders, and anyone running real-time signal systems, this isn't a nice-to-have. It's the baseline infrastructure that separates reactive traders from the ones always a step behind.
REST polling introduces artificial latency at every step. A call to GET /api/v3/ticker/price opens a connection, waits for a response, then closes it. Even at 10 requests per second, you're missing hundreds of price ticks between calls. WebSocket flips this model entirely: one connection stays open, and data arrives the moment the exchange publishes it — no asking required.
The difference hits hardest during volatility. When BTC drops 3% in 90 seconds, REST-based systems are still catching up while WebSocket-connected traders have already seen every tick. On platforms like Binance and OKX, where order books can shift dozens of times per second during major moves, polling simply cannot keep pace.
| Feature | REST API | WebSocket |
|---|---|---|
| Connection model | New per request | Persistent, long-lived |
| Data delivery | Pull (you request) | Push (server sends) |
| Typical latency | 50–500ms | 1–10ms |
| Server load | High (repeated requests) | Low (one connection) |
| Best use case | Historical data, one-off queries | Live prices, order books, trades |
The good news: you have solid options at every budget level, from completely free websocket crypto APIs to institutional-grade feeds. Here's what actually matters in practice.
Binance's websocket crypto api is the most commonly used in the industry — partly because of volume, partly because the documentation is genuinely good. The example below subscribes to live ticker data for BTC, ETH, and SOL. No API key needed for public market data streams.
Install the dependency first: pip install websocket-client
import websocket
import json
def on_message(ws, message):
data = json.loads(message)
# Handle combined stream wrapper
if 'stream' in data:
ticker = data['data']
else:
ticker = data
symbol = ticker.get('s', '')
price = ticker.get('c', '') # current close price
volume = ticker.get('v', '') # 24h volume
change = ticker.get('P', '') # 24h price change %
print(f'{symbol}: ${price} | Change: {change}% | Vol: {volume}')
def on_error(ws, error):
print(f'WebSocket error: {error}')
# Implement reconnect logic here in production
def on_close(ws, close_status_code, close_msg):
print(f'Connection closed: {close_status_code}')
def on_open(ws):
subscribe_msg = {
'method': 'SUBSCRIBE',
'params': [
'btcusdt@ticker',
'ethusdt@ticker',
'solusdt@ticker'
],
'id': 1
}
ws.send(json.dumps(subscribe_msg))
print('Subscribed to Binance ticker streams')
socket_url = 'wss://stream.binance.com:9443/ws'
ws = websocket.WebSocketApp(
socket_url,
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close
)
ws.run_forever(reconnect=5) # auto-reconnect on disconnect
Pro tip: Always implement reconnect logic in production. Exchanges occasionally drop WebSocket connections during maintenance windows or network events. The reconnect=5 parameter in websocket-client handles this automatically — without it, your stream silently dies and you won't know until your data stops updating.
The cryptocompare websocket delivers aggregated price data across dozens of exchanges in a single connection — useful when you need a consolidated mid-market price rather than exchange-specific data. Type 5 messages are aggregate price updates. You'll need a free API key from CryptoCompare's developer portal.
Install with: npm install ws
const WebSocket = require('ws');
const API_KEY = 'YOUR_CRYPTOCOMPARE_API_KEY';
const WS_URL = `wss://streamer.cryptocompare.com/v2?api_key=${API_KEY}`;
function connectWebSocket() {
const ws = new WebSocket(WS_URL);
ws.on('open', () => {
const subscribeMsg = {
action: 'SubAdd',
subs: [
'5~CCCAGG~BTC~USD', // BTC/USD aggregate
'5~CCCAGG~ETH~USD', // ETH/USD aggregate
'5~CCCAGG~SOL~USD' // SOL/USD aggregate
]
};
ws.send(JSON.stringify(subscribeMsg));
console.log('Connected to CryptoCompare WebSocket API');
});
ws.on('message', (data) => {
const msg = JSON.parse(data);
// TYPE 5 = aggregate price update, only process if PRICE field exists
if (msg.TYPE === '5' && msg.PRICE) {
const output = {
pair: `${msg.FROMSYMBOL}/${msg.TOSYMBOL}`,
price: msg.PRICE,
volume24h: msg.VOLUME24HOUR || 0,
lastMarket: msg.LASTMARKET || 'N/A'
};
console.log(output);
}
});
ws.on('error', (err) => {
console.error('WebSocket error:', err.message);
});
ws.on('close', () => {
console.log('Disconnected — reconnecting in 5s...');
setTimeout(connectWebSocket, 5000); // auto-reconnect
});
}
connectWebSocket();
Alpaca's crypto websocket api free tier gives you real-time trades and quotes for major pairs without a monthly subscription. It's particularly clean for Python developers — the official SDK handles connection management, reconnects, and message parsing out of the box. Authentication uses your Alpaca API key and secret, which you generate from their dashboard.
Install with: pip install alpaca-py
from alpaca.data.live import CryptoDataStream
from alpaca.data.models import Trade, Quote
API_KEY = 'YOUR_ALPACA_API_KEY'
SECRET_KEY = 'YOUR_ALPACA_SECRET_KEY'
stream = CryptoDataStream(
api_key=API_KEY,
secret_key=SECRET_KEY
)
async def handle_trade(trade: Trade):
print(
f'TRADE | {trade.symbol}: '
f'${float(trade.price):.2f} x {trade.size} '
f'@ {trade.timestamp}'
)
async def handle_quote(quote: Quote):
spread = float(quote.ask_price) - float(quote.bid_price)
print(
f'QUOTE | {quote.symbol} '
f'Bid: ${quote.bid_price} '
f'Ask: ${quote.ask_price} '
f'Spread: ${spread:.4f}'
)
# Subscribe to trades and quotes
stream.subscribe_trades(handle_trade, 'BTC/USD', 'ETH/USD')
stream.subscribe_quotes(handle_quote, 'BTC/USD')
print('Starting Alpaca crypto websocket stream...')
stream.run()
Raw price feeds are only useful if you do something with them. The typical pattern for a WebSocket-powered signal system looks like this: connect to one or more streams, maintain a rolling price buffer in memory, apply your indicator logic on each incoming tick, and emit alerts when conditions are met.
For example, you might maintain a 20-tick moving average buffer in a deque, recalculate on every message, and fire an alert when price crosses the moving average from below. Because WebSocket messages arrive in real time, your signals fire within milliseconds of the actual market move — not seconds later when your next REST poll completes.
The practical architecture: one WebSocket connection per exchange or data source, a shared in-memory price store (a simple dict works for small systems), and a signal evaluation loop that runs on each price update. For multi-exchange systems like those tracking Binance, Bybit, and Coinbase simultaneously, use asyncio to manage multiple connections without thread overhead.
VoiceOfChain takes this architecture further — aggregating WebSocket feeds from multiple exchanges and applying signal logic in real time. Rather than building and maintaining your own WebSocket infrastructure, you can consume the processed signals directly as a trader and focus on execution rather than data plumbing.
For production systems, a few rules of thumb: always buffer 1-5 seconds of messages in case your processing lags during spikes; log raw message counts so you can detect silent disconnects; and set exchange-specific heartbeat/ping intervals (Binance requires a pong response to server pings every 3 minutes or the connection drops).
WebSocket crypto APIs are the foundation every serious trading system is built on. The pattern is straightforward once you've implemented it once: connect, subscribe, process each message, emit signals. The real work is in what you do with the data — your indicator logic, your risk filters, your execution rules.
Start with Binance's public streams if you want zero friction — no account needed, copy the Python example above, and you'll have live BTC prices streaming to your terminal in under five minutes. From there, experiment with order book streams (btcusdt@depth20) to see bid/ask pressure in real time, or trade streams (btcusdt@trade) to track individual executions. Once you're comfortable with the data model, layering in signal logic becomes a natural next step.