CCXT : comment fonctionnent réellement les méthodes WebSocket de carnet d'ordres
Bonjour ! Aujourd'hui, nous allons nous pencher sur l'un des sujets les plus importants pour les développeurs de systèmes de trading : le fonctionnement des méthodes WebSocket permettant d'obtenir des carnets d'ordres dans CCXT. Si vous vous êtes déjà demandé « pourquoi cette méthode est dans la documentation mais ne fonctionne pas en pratique ? » ou « quelle méthode choisir pour surveiller plus de 100 paires de trading ? », cet article est fait pour vous.
Introduction : pourquoi c'est important
Lorsqu'on travaille avec CCXT pour la collecte de données de marché, beaucoup se posent des questions cruciales :
- Quelles méthodes WebSocket pour les carnets d'ordres sont réellement prises en charge sur les différents exchanges ?
- En quoi les méthodes diffèrent-elles en termes de volume de trafic et de structure des données ?
- Pourquoi des tests automatisés peuvent-ils afficher « ✓ » alors que la méthode ne fonctionne pas en pratique ?
Dans cet article, une analyse détaillée des méthodes les plus courantes, de leurs caractéristiques et de la situation réelle sur plus de 75 exchanges.
Aperçu des méthodes clés
Quatre méthodes WebSocket principales pour les données de carnet d'ordres : abonnement unique, abonnement groupé, surveillance du top of book et snapshot ponctuel
Les API modernes des exchanges offrent plusieurs moyens d'obtenir des données de carnet d'ordres via WebSocket. Examinons chacune d'elles :
1. watchOrderBook - L'approche classique
Il s'agit de la méthode principale pour s'abonner aux mises à jour du carnet d'ordres d'une seule paire de trading.
Caractéristiques principales :
- Objectif : s'abonner aux mises à jour du carnet d'ordres d'une paire
- Type de connexion : connexion WebSocket persistante
- Données : carnet d'ordres complet (généralement 100 à 1000 niveaux par côté)
- Trafic : moyen à élevé, selon la fréquence des mises à jour et la profondeur
Exemple d'utilisation :
const exchange = new ccxt.pro.binance();
const orderbook = await exchange.watchOrderBook('BTC/USDT');
console.log(orderbook);
2. watchOrderBookForSymbols - Abonnement groupé
Cette méthode permet de s'abonner simultanément à plusieurs paires de trading, si l'exchange le prend en charge.
Caractéristiques principales :
- Objectif : s'abonner à plusieurs paires en même temps
- Type de connexion : WebSocket persistant, souvent une seule connexion pour plusieurs paires
- Données : pour chaque paire, carnet d'ordres complet
- Trafic : très élevé avec un grand nombre de paires (100–1000 niveaux × 2 côtés × nombre de paires)
Exemple de réponse :
{
"BTC/USDT": {
"bids": [[50000.1, 1.5], [50000.0, 2.1]],
"asks": [[50001.0, 1.2], [50001.1, 0.8]],
"timestamp": 1717398000000,
"datetime": "2025-06-03T12:00:00Z"
},
"ETH/USDT": {
"bids": [[3000.5, 10.2], [3000.4, 5.7]],
"asks": [[3001.0, 8.3], [3001.1, 12.1]],
"timestamp": 1717398000000,
"datetime": "2025-06-03T12:00:00Z"
}
}
Avertissement important : en réalité, cette méthode n'est pas prise en charge sur tous les exchanges. Parfois la méthode existe dans l'API mais n'est pas implémentée.
3. watchBidsAsks - Surveillance optimisée
Le moyen le plus économique de suivre les meilleurs prix sur plusieurs paires de trading.
Caractéristiques principales :
- Objectif : s'abonner uniquement aux meilleurs prix (top of book) pour plusieurs paires
- Type de connexion : WebSocket persistant, souvent une seule connexion pour toutes les paires
- Données : un seul prix par côté (bid/ask)
- Trafic : minimal, adapté à la surveillance d'un grand nombre de paires
Exemple de réponse :
{
"BTC/USDT": {
"bids": [[50000.1, 1.5]],
"asks": [[50001.0, 1.2]],
"timestamp": 1717398000000,
"datetime": "2025-06-03T12:00:00Z"
},
"ETH/USDT": {
"bids": [[3000.5, 10.2]],
"asks": [[3001.0, 8.3]],
"timestamp": 1717398000000,
"datetime": "2025-06-03T12:00:00Z"
}
}
Particularité : généralement implémentée via le endpoint de ticker — cela économise des ressources à la fois pour le client et pour l'exchange.
4. fetchOrderBookWs - Requêtes ponctuelles
Alternative à l'API REST pour obtenir des snapshots de carnet d'ordres.
Caractéristiques principales :
- Objectif : requête ponctuelle de carnet d'ordres via WebSocket (façon REST)
- Type de connexion : WebSocket temporaire, la connexion se ferme après réception des données
- Données : snapshot du carnet d'ordres
- Trafic : minimal
Différences importantes et comparaison des méthodes
Comprendre les différences entre les méthodes est essentiel pour choisir la bonne approche :
Connexions persistantes vs. temporaires
- Méthodes watch* — créent une connexion persistante, reçoivent des mises à jour en streaming en temps réel
- Méthodes fetch* — utilisent WebSocket uniquement pour une requête ponctuelle, à la manière de l'API REST
Comparaison du trafic
watchBidsAsks vs. watchOrderBookForSymbols :
watchBidsAsks— 100 à 1000 fois moins de trafic, idéal pour la surveillance groupéewatchOrderBookForSymbols— puissant, mais très lourd en trafic et non pris en charge par tous les exchanges
Exemple de calcul de trafic :
- watchBidsAsks pour 100 paires : ~100 enregistrements (1 bid/ask par paire)
- watchOrderBookForSymbols pour 100 paires : ~100 000-1 000 000 enregistrements (100-1000 niveaux × 2 côtés × 100 paires)
Comparaison visuelle de l'intensité des données entre le carnet d'ordres complet et les méthodes top of book (bids/asks)
Cas pratique : Gate.io, réalité contre documentation
L'écart entre une documentation API propre et le comportement réel des exchanges
Examinons un exemple concret montrant que la documentation peut ne pas correspondre à la pratique.
Test : watchOrderBookForSymbols sur Gate.io
Tentative de s'abonner à 10 paires de trading populaires :
const symbols = [
'1CAT/USDT:USDT',
'1INCH/USDT:USDT',
'A8/USDT:USDT',
'AAVE/USDT:USDT',
'ACE/USDT:USDT',
'ACH/USDT:USDT',
'ACT/USDT:USDT',
'ACX/USDT:USDT',
'ADA/USDT:USDT',
'ADX/USDT:USDT'
];
const exchange = new ccxt.pro.gateio();
try {
const orderbooks = await exchange.watchOrderBookForSymbols(symbols);
console.log('Success!', orderbooks);
} catch (error) {
console.error('Error:', error.message);
}
Résultat réel :
NotSupported: gateio watchOrderBookForSymbols() is not supported yet
Leçon importante : même si une méthode est déclarée dans la documentation de l'API, cela ne garantit pas qu'elle fonctionne pour un exchange donné. Testez toujours en pratique !
Audit automatisé : ce qui est réellement pris en charge
Matrice de compatibilité montrant le support réel des méthodes sur plus de 75 exchanges de cryptomonnaies
Pour obtenir une image réelle du support des méthodes, un script a été écrit pour vérifier tous les exchanges CCXT :
const ccxt = require('ccxt');
async function checkAllExchangeMethods() {
const results = [];
// Get list of all supported exchanges
const exchangeIds = ccxt.pro.exchanges;
for (const exchangeId of exchangeIds) {
try {
const exchange = new ccxt.pro[exchangeId]();
// Check for method presence
const hasWatchOrderBook = typeof exchange.watchOrderBook === 'function';
const hasWatchBidsAsks = typeof exchange.watchBidsAsks === 'function';
const hasWatchOrderBookForSymbols = typeof exchange.watchOrderBookForSymbols === 'function';
// Check spot and futures support
const hasSpot = exchange.has['spot'];
const hasFutures = exchange.has['future'] || exchange.has['swap'];
results.push({
exchange: exchangeId,
spot: hasSpot,
futures: hasFutures,
watchOrderBook: hasWatchOrderBook,
watchBidsAsks: hasWatchBidsAsks,
watchOrderBookForSymbols: hasWatchOrderBookForSymbols
});
} catch (error) {
console.error(`Error checking ${exchangeId}:`, error.message);
}
}
return results;
}
// Run the check
checkAllExchangeMethods().then(results => {
console.table(results);
});
Résultats de l'audit (extrait des principaux exchanges)
Exchange | Spot (OB/BA/OBS) | Futures (OB/BA/OBS)
----------------------------------------------------------
binance | ✓/✓/✓ | ✓/✓/✓
bybit | ✓/✓/✓ | ✓/✓/✓
okx | ✓/✓/✓ | ✓/✓/✓
gateio | ✓/✓/✓ | ✓/✓/✓
mexc | ✓/✓/✓ | ✓/✓/✓
kucoin | ✓/✓/✓ | ✓/✓/✓
huobi | ✓/✓/✓ | ✓/✓/✓
bitget | ✓/✓/✓ | ✓/✓/✓
Remarque importante :
Le script vérifie uniquement la présence de la méthode dans l'objet JavaScript, pas le support réel côté exchange. Ainsi, un « ✓ » ne signifie pas toujours une fonctionnalité opérationnelle — comme on l'a vu avec l'exemple de Gate.io.
Recommandations pratiques pour le choix de la méthode
Organigramme de décision pour choisir la bonne méthode WebSocket selon votre cas d'usage
Pour différents cas d'usage
1. Surveillance d'un grand nombre de paires (100+) :
- Utilisez
watchBidsAsks - Trafic minimal
- Récupérez uniquement les meilleurs prix
- Idéal pour les bots d'arbitrage
2. Construction d'un carnet d'ordres complet pour une paire :
- Utilisez
watchOrderBook - Profondeur de marché complète
- Adapté aux stratégies de market making
3. Surveillance de plusieurs paires avec profondeur complète :
- Essayez d'abord
watchOrderBookForSymbols - Si non pris en charge, utilisez plusieurs
watchOrderBook - Tenez compte des limites de l'exchange sur le nombre de connexions
4. Récupération ponctuelle de données :
- Utilisez
fetchOrderBookWsou l'API REST classique - Pour les snapshots ou l'initialisation
Optimisation des performances
Connexions individuelles chaotiques (à gauche) vs connexion WebSocket multiplexée optimisée (à droite)
Gestion des connexions :
// Bad: creating multiple connections
const symbols = ['BTC/USDT', 'ETH/USDT', 'ADA/USDT'];
const orderbooks = await Promise.all(
symbols.map(symbol => exchange.watchOrderBook(symbol))
);
// Good: one connection for all pairs (if supported)
try {
const orderbooks = await exchange.watchOrderBookForSymbols(symbols);
} catch (error) {
// Fallback to individual subscriptions
const orderbooks = await Promise.all(
symbols.map(symbol => exchange.watchOrderBook(symbol))
);
}
Gestion de la profondeur :
// Limit depth to save traffic
const orderbook = await exchange.watchOrderBook('BTC/USDT', 20); // only 20 levels
Gestion des erreurs et récupération de connexion
Récupération résiliente de la connexion avec un mécanisme de retry à backoff exponentiel
Les connexions WebSocket peuvent se rompre, il est donc important de disposer d'une gestion des erreurs adéquate :
async function robustWatchOrderBook(exchange, symbol, maxRetries = 3) {
let retries = 0;
while (retries < maxRetries) {
try {
const orderbook = await exchange.watchOrderBook(symbol);
retries = 0; // reset counter on success
return orderbook;
} catch (error) {
retries++;
console.error(`Subscription error (attempt ${retries}):`, error.message);
if (retries >= maxRetries) {
throw new Error(`Failed to subscribe after ${maxRetries} attempts`);
}
// Exponential backoff
await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, retries)));
}
}
}
Surveillance de la qualité des données
Les données du carnet d'ordres traversant des points de contrôle de validation : structure, fraîcheur et logique du spread
Il est important de suivre la qualité des données reçues :
function validateOrderBook(orderbook) {
// Check basic structure
if (!orderbook.bids || !orderbook.asks) {
throw new Error('Invalid orderbook structure');
}
// Check data freshness
const now = Date.now();
const dataAge = now - orderbook.timestamp;
if (dataAge > 10000) { // older than 10 seconds
console.warn('Stale orderbook data:', dataAge, 'ms');
}
// Check price logic
const bestBid = orderbook.bids[0] ? orderbook.bids[0][0] : 0;
const bestAsk = orderbook.asks[0] ? orderbook.asks[0][0] : 0;
if (bestBid >= bestAsk && bestBid > 0 && bestAsk > 0) {
console.warn('Crossed spread:', { bestBid, bestAsk });
}
}
Conclusions et bonnes pratiques
Sur la base de l'expérience pratique avec CCXT, voici les principales recommandations :
1. Ne vous fiez pas uniquement à la documentation
Testez toujours les méthodes avec des données réelles avant de les déployer en production. La présence d'une méthode dans l'API ne garantit pas son bon fonctionnement.
2. Choisissez la méthode adaptée à la tâche
- Surveillance groupée :
watchBidsAsks - Analyse détaillée :
watchOrderBook - Requêtes ponctuelles :
fetchOrderBookWs
3. Optimisez le trafic
Pour la surveillance d'un grand nombre de paires, watchBidsAsks peut être jusqu'à 1000 fois plus efficace que watchOrderBookForSymbols.
4. Préparez-vous aux échecs
Mettez en place une logique de retry robuste et une surveillance de la qualité des données.
5. Testez sous charge de production
Le comportement de l'API peut différer radicalement sous charge par rapport aux requêtes de test.
L'avenir des API WebSocket pour les carnets d'ordres
Des connexions fragmentées entre exchanges vers des protocoles d'API unifiés et standardisés
L'industrie évolue vers des approches plus standardisées :
- Unification des méthodes entre les exchanges
- Documentation améliorée avec des exemples réels
- Protocoles de compression de données plus efficaces
- Meilleurs outils de débogage et de surveillance
Conclusion
Les API WebSocket pour les carnets d'ordres sont des outils puissants, mais elles nécessitent une compréhension approfondie des spécificités de chaque exchange. CCXT simplifie considérablement le travail en unifiant les interfaces, mais la réalité reste plus complexe que la documentation.
La clé du succès réside dans les tests, la surveillance et le choix des bonnes méthodes pour des tâches spécifiques. Rappelez-vous : ce qui fonctionne sur un exchange peut ne pas fonctionner sur un autre, même si les API semblent identiques.
Un système de trading réussi ne repose pas uniquement sur des algorithmes corrects, mais aussi sur une infrastructure de données fiable. Et les méthodes WebSocket de CCXT sont un élément important de cette infrastructure.
Quelle est votre expérience avec les API WebSocket des exchanges ? Avez-vous rencontré des problèmes inattendus ? Partagez-les dans les commentaires !
Liens utiles
Citation
@software{soloviov2025ccxtprowebsocketorderbook,
author = {Soloviov, Eugen},
title = {CCXT: How WebSocket Orderbook Methods Really Work},
year = {2025},
url = {https://marketmaker.cc/en/blog/post/ccxt-pro-websocket-orderbook-methods},
version = {0.1.0},
description = {Detailed breakdown of CCXT WebSocket methods for orderbooks: watchOrderBook, watchBidsAsks, watchOrderBookForSymbols. Real tests on 75+ exchanges.}
}
Authors
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.