К списку статей
June 3, 2025
5 мин. чтения

CCXT: Как реально работают WebSocket-методы для ордербуков

CCXT
WebSocket
ордербук
биржи
API
трейдинг
криптовалюты

Привет! Сегодня разберём одну из самых важных тем для разработчиков торговых систем — как работают WebSocket-методы для получения ордербуков в CCXT. Если вы когда-нибудь сталкивались с вопросами типа "почему метод есть в документации, а на практике не работает?" или "какой метод выбрать для мониторинга 100+ торговых пар?", то эта статья для вас.

Введение: почему это важно

Работая с CCXT для сбора рыночных данных, многие сталкиваются с критическими вопросами:

  • Какие WebSocket-методы для ордербуков действительно поддерживаются на разных биржах?
  • Чем отличаются методы по объёму трафика и структуре данных?
  • Почему автотесты могут показывать "✓", а на практике метод не работает?

В этой статье — подробный разбор популярных методов, их особенностей и реального положения дел на примере 75+ бирж.

Обзор ключевых методов

Современные биржевые API предлагают несколько способов получения данных об ордербуках через WebSocket. Давайте разберём каждый из них:

1. watchOrderBook - классический подход

Это основной метод для подписки на обновления ордербука по одной торговой паре.

Ключевые характеристики:

  • Назначение: Подписка на обновления ордербука по одной паре
  • Тип соединения: Постоянное WebSocket-соединение
  • Данные: Полный ордербук (обычно 100–1000 уровней по каждой стороне)
  • Трафик: Средний или высокий, зависит от частоты обновлений и глубины

Пример использования:

const exchange = new ccxt.pro.binance();
const orderbook = await exchange.watchOrderBook('BTC/USDT');
console.log(orderbook);

2. watchOrderBookForSymbols - массовая подписка

Этот метод позволяет подписаться на несколько торговых пар одновременно, если биржа это поддерживает.

Ключевые характеристики:

  • Назначение: Подписка на несколько пар одновременно
  • Тип соединения: Постоянное WebSocket, часто одно соединение на множество пар
  • Данные: Для каждой пары — полный ордербук
  • Трафик: Очень высокий при большом числе пар (100–1000 уровней × 2 стороны × количество пар)

Пример ответа:

{
  "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"
  }
}

Важное предупреждение: В реальности поддерживается не на всех биржах. Иногда метод есть в API, но не реализован.

3. watchBidsAsks - оптимизированный мониторинг

Самый экономичный способ отслеживать лучшие цены по множеству торговых пар.

Ключевые характеристики:

  • Назначение: Подписка только на лучшие цены (top of book) по множеству пар
  • Тип соединения: Постоянное WebSocket, часто одно соединение на все пары
  • Данные: Только по одной цене на каждой стороне (bid/ask)
  • Трафик: Минимальный, подходит для мониторинга большого числа пар

Пример ответа:

{
  "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"
  }
}

Особенность: Обычно реализовано через ticker endpoint — экономит ресурсы и у клиента, и у биржи.

4. fetchOrderBookWs - разовые запросы

Альтернатива REST API для получения снэпшота ордербука.

Ключевые характеристики:

  • Назначение: Одноразовый запрос ордербука через WebSocket (REST-like)
  • Тип соединения: Временное WebSocket, соединение закрывается после получения данных
  • Данные: Снэпшот ордербука
  • Трафик: Минимальный

Важные различия и сравнение методов

Понимание различий между методами критически важно для выбора правильного подхода:

Постоянные vs временные соединения

  1. watch методы* — создают постоянное соединение, получают потоковые обновления в реальном времени
  2. fetch методы* — используют WebSocket только для разового запроса, аналогично REST API

Сравнение по трафику

watchBidsAsks vs watchOrderBookForSymbols:

  • watchBidsAsks — в 100–1000 раз меньше трафика, идеален для массового мониторинга
  • watchOrderBookForSymbols — мощно, но очень тяжело по трафику и поддерживается не всеми биржами

Пример расчёта трафика:

  • watchBidsAsks для 100 пар: ~100 записей (по 1 bid/ask на пару)
  • watchOrderBookForSymbols для 100 пар: ~100,000-1,000,000 записей (по 100-1000 уровней × 2 стороны × 100 пар)

Практический кейс: Gate.io и реальность vs документация

Давайте рассмотрим реальный пример того, как документация может не соответствовать практике.

Тест: watchOrderBookForSymbols на Gate.io

Попытка подписаться на 10 популярных торговых пар:

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('Успех!', orderbooks);
} catch (error) {
  console.error('Ошибка:', error.message);
}

Фактический результат:

NotSupported: gateio watchOrderBookForSymbols() is not supported yet

Важный урок: Даже если метод объявлен в API документации, это не гарантирует его работу для конкретной биржи. Всегда проверяйте на практике!

Автоматический аудит: что поддерживается на самом деле

Для получения реальной картины поддержки методов был написан скрипт проверки всех бирж CCXT:

const ccxt = require('ccxt');

async function checkAllExchangeMethods() {
    const results = [];
    
    // Получаем список всех поддерживаемых бирж
    const exchangeIds = ccxt.pro.exchanges;
    
    for (const exchangeId of exchangeIds) {
        try {
            const exchange = new ccxt.pro[exchangeId]();
            
            // Проверяем наличие методов
            const hasWatchOrderBook = typeof exchange.watchOrderBook === 'function';
            const hasWatchBidsAsks = typeof exchange.watchBidsAsks === 'function';
            const hasWatchOrderBookForSymbols = typeof exchange.watchOrderBookForSymbols === 'function';
            
            // Проверяем поддержку spot и futures
            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(`Ошибка при проверке ${exchangeId}:`, error.message);
        }
    }
    
    return results;
}

// Выполняем проверку
checkAllExchangeMethods().then(results => {
    console.table(results);
});

Результаты аудита (фрагмент топовых бирж)

Exchange        | Spot (OB/BA/OBS) | Futures (OB/BA/OBS)
----------------------------------------------------------
binance         | ✓/✓/✓            | ✓/✓/✓
bybit           | ✓/✓/✓            | ✓/✓/✓
okx             | ✓/✓/✓            | ✓/✓/✓
gateio          | ✓/✓/✓            | ✓/✓/✓
mexc            | ✓/✓/✓            | ✓/✓/✓
kucoin          | ✓/✓/✓            | ✓/✓/✓
huobi           | ✓/✓/✓            | ✓/✓/✓
bitget          | ✓/✓/✓            | ✓/✓/✓

Важное замечание:
Скрипт проверяет только наличие метода в объекте JavaScript, а не реальную поддержку на стороне биржи. Поэтому "✓" не всегда означает работоспособность — как мы видели на примере Gate.io.

Практические рекомендации по выбору методов

Для разных сценариев использования

1. Мониторинг большого количества пар (100+):

  • Используйте watchBidsAsks
  • Минимальный трафик
  • Получаете только лучшие цены
  • Идеально для арбитражных ботов

2. Построение полного ордербука для одной пары:

  • Используйте watchOrderBook
  • Полная глубина рынка
  • Подходит для market making стратегий

3. Мониторинг нескольких пар с полной глубиной:

  • Сначала попробуйте watchOrderBookForSymbols
  • Если не поддерживается — используйте множественные watchOrderBook
  • Учитывайте ограничения биржи на количество соединений

4. Разовое получение данных:

  • Используйте fetchOrderBookWs или обычный REST API
  • Для снэпшотов или инициализации

Оптимизация производительности

Управление соединениями:

// Плохо: создание множества соединений
const symbols = ['BTC/USDT', 'ETH/USDT', 'ADA/USDT'];
const orderbooks = await Promise.all(
    symbols.map(symbol => exchange.watchOrderBook(symbol))
);

// Хорошо: одно соединение для всех пар (если поддерживается)
try {
    const orderbooks = await exchange.watchOrderBookForSymbols(symbols);
} catch (error) {
    // Fallback к индивидуальным подпискам
    const orderbooks = await Promise.all(
        symbols.map(symbol => exchange.watchOrderBook(symbol))
    );
}

Управление глубиной:

// Ограничиваем глубину для экономии трафика
const orderbook = await exchange.watchOrderBook('BTC/USDT', 20); // только 20 уровней

Обработка ошибок и восстановление соединений

WebSocket-соединения могут обрываться, поэтому важно правильно обрабатывать ошибки:

async function robustWatchOrderBook(exchange, symbol, maxRetries = 3) {
    let retries = 0;
    
    while (retries < maxRetries) {
        try {
            const orderbook = await exchange.watchOrderBook(symbol);
            retries = 0; // сбрасываем счётчик при успехе
            return orderbook;
        } catch (error) {
            retries++;
            console.error(`Ошибка подписки (попытка ${retries}):`, error.message);
            
            if (retries >= maxRetries) {
                throw new Error(`Не удалось подписаться после ${maxRetries} попыток`);
            }
            
            // Экспоненциальная задержка
            await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, retries)));
        }
    }
}

Мониторинг качества данных

Важно отслеживать качество получаемых данных:

function validateOrderBook(orderbook) {
    // Проверяем базовую структуру
    if (!orderbook.bids || !orderbook.asks) {
        throw new Error('Неверная структура ордербука');
    }
    
    // Проверяем актуальность данных
    const now = Date.now();
    const dataAge = now - orderbook.timestamp;
    if (dataAge > 10000) { // старше 10 секунд
        console.warn('Устаревшие данные ордербука:', dataAge, 'мс');
    }
    
    // Проверяем логичность цен
    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('Пересекающийся спред:', { bestBid, bestAsk });
    }
}

Выводы и лучшие практики

Основываясь на практическом опыте работы с CCXT, вот главные рекомендации:

1. Не полагайтесь только на документацию

Всегда тестируйте методы на реальных данных перед внедрением в продакшн. Наличие метода в API не гарантирует его работоспособность.

2. Выбирайте метод под задачу

  • Массовый мониторинг: watchBidsAsks
  • Детальный анализ: watchOrderBook
  • Разовые запросы: fetchOrderBookWs

3. Оптимизируйте трафик

Для мониторинга большого количества пар watchBidsAsks может быть в 1000 раз эффективнее watchOrderBookForSymbols.

4. Готовьтесь к сбоям

Реализуйте robust retry логику и мониторинг качества данных.

5. Тестируйте на продакшн нагрузках

Поведение API может кардинально отличаться при нагрузке vs тестовых запросах.

Будущее WebSocket API для ордербуков

Индустрия движется в сторону более стандартизированных подходов:

  • Унификация методов между биржами
  • Улучшенная документация с реальными примерами
  • Более эффективные протоколы сжатия данных
  • Лучшие инструменты отладки и мониторинга

Заключение

WebSocket API для ордербуков — это мощный инструмент, но требующий глубокого понимания особенностей каждой биржи. CCXT значительно упрощает работу, унифицируя интерфейсы, но реальность всё ещё сложнее документации.

Ключ к успеху — тестирование, мониторинг и правильный выбор методов под конкретные задачи. Помните: то, что работает на одной бирже, может не работать на другой, даже если API выглядят идентично.

Успешная торговая система — это не только правильные алгоритмы, но и надёжная инфраструктура получения данных. И WebSocket-методы CCXT — важная часть этой инфраструктуры.

А какой у вас опыт работы с WebSocket API бирж? Сталкивались ли с неожиданными проблемами? Делитесь в комментариях!

Полезные ссылки

Цитирование

@software{soloviov2025ccxtprowebsocketorderbook,
  author = {Soloviov, Eugen},
  title = {CCXT: Как реально работают WebSocket-методы для ордербуков},
  year = {2025},
  url = {https://marketmaker.cc/ru/blog/post/ccxt-pro-websocket-orderbook-methods},
  version = {0.1.0},
  description = {Подробный разбор WebSocket-методов CCXT для работы с ордербуками: watchOrderBook, watchBidsAsks, watchOrderBookForSymbols. Реальные тесты на 75+ биржах.}
}

MarketMaker.cc Team

Количественные исследования и стратегии

Обсудить в Telegram