Слогер Создать блог
Разработка

Как перестать дёргать API и начать получать данные в реальном времени

WebSocket вместо бесконечных запросов — переходим с опроса на подписку и перестаём терять ценные миллисекунды на бирже

Зачем всё это нужно

Честно говоря, я застрял в петле, напоминающей бесконечный «День сурка» — только вместо повторения одного и того же дня я каждую секунду дёргал торговый API, чтобы узнать цену. Запускал простой while True:, долбил эндпоинт, парсил JSON, а потом… снова ждал секунду. Ноутбук гудел как взлетающий самолёт, процессор был загружен на 80 %, а данные всё равно устаревали к моменту обработки.

Проблема была не только в потраченных циклах — дело в задержке. На быстрых рынках секунда может стоить пропущенного тика, который превращает прибыльную сделку в убыток. Я всё спрашивал себя: «Неужели нет способа заставить рынок присылать данные мне, как Нео уклоняется от пуль в замедленной съёмке?»

Момент озарения настал, когда я пролистал документацию одной популярной криптобиржи и увидел WebSocket-эндпоинт с пометкой «stream ticker». Внезапно весь этот кошмар опросов показался попыткой собрать кубик Рубика с завязанными глазами, хотя решение лежало прямо перед носом.

Прозрение: перестань тянуть — начни подписываться

Открытие было до глупости простым: прекрати дёргать, начни получать. Вместо того чтобы каждую секунду спрашивать сервер «Эй, дай актуальную цену?», вы открываете постоянное двустороннее соединение и позволяете серверу отправлять обновления каждый раз, когда что-то меняется.

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

  • Почти нулевую задержку (часто менее 100 мс).
  • Гораздо меньший трафик (без лишних опросов).
  • Чистый код (никакой ручной регулировки частоты запросов или логики повторных попыток).

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

Как это выглядит в коде

Ад опроса

Вот как выглядела моя первая попытка (Python, библиотека requests). Я опрашивал тикер BTC/USDT на какой-то бирже каждую секунду.

import time import requests API_URL = "https://api.example.com/v1/ticker?symbol=BTCUSDT" def fetch_price(): resp = requests.get(API_URL, timeout=5) resp.raise_for_status() data = resp.json() return float(data["price"]) while True: price = fetch_price() print(f"[{time.strftime('%X')}] Price: {price:.2f}") time.sleep(1) # <-- мучительная пауза

Что пошло не так?

  1. Страх перед лимитами — если уменьшить sleep до 0,2 с, быстро упрёшься в лимит API и получишь бан.
  2. Устаревшие данные — даже при 1 с можно пропустить движение внутри секунды.
  3. Пустая трата CPU — цикл держит поток живым, потребляя ресурсы, даже когда цена не меняется.

WebSocket: блаженство

А теперь тот же функционал, но через WebSocket. Большинство бирж предоставляют стрим вроде wss://stream.example.com/ws/btcusdt@ticker. Сообщение приходит только тогда, когда тикер обновляется.

import json import time import websocket # pip install websocket-client WS_URL = "wss://stream.example.com/ws/btcusdt@ticker" def on_message(ws, message): data = json.loads(message) # Формат зависит от биржи; подправьте при необходимости. price = float(data["c"]) # 'c' = цена закрытия во многих стримах print(f"[{time.strftime('%X')}] Price: {price:.2f}") def on_error(ws, error): print("WebSocket error:", error) def on_close(ws, close_status_code, close_reason): print("### Connection closed ###") # Простая стратегия переподключения – подождать и повторить. time.sleep(5) start_ws() def on_open(ws): print("### WebSocket connection opened ###") def start_ws(): ws = websocket.WebSocketApp( WS_URL, on_open=on_open, on_message=on_message, on_error=on_error, on_close=on_close, ) ws.run_forever(ping_interval=30, ping_timeout=10) # keep-alive if __name__ == "__main__": start_ws()

Почему это похоже на прокачку:

  • run_forever держит соединение живым; библиотека сама обрабатывает пинг/понг.
  • Данные поступают только когда меняются, так что не тратим трафик и ресурсы CPU.
  • Логика переподключения живёт в on_close — больше никаких спагетти из sleep и retry.
Ловушки, которых стоит избегать
ЛовушкаКак выглядитКак обойти
Игнорирование ping/pongСоединение молча обрывается через несколько минут.Используйте встроенный keep-alive (ping_interval) или вручную отвечайте на ping-фреймы.
Предположение о порядке сообщенийОбработка устаревшего тикера после более свежего из-за джиттера сети.Включайте в каждое сообщение порядковый номер или метку времени и отбрасывайте устаревшие обновления.
Жёстко заданная задержка переподключенияМгновенное переподключение заваливает сервер шквалом handshake.Реализуйте экспоненциальную задержку (например, 1 с, 2 с, 4 с с ограничением 30 с).

Почему эта суперсила важна

С живым WebSocket-потоком вы больше не гоняетесь за рынком — вы осёдлываете его. Представьте, что можно построить:

  • Бота для скальпинга, который отправляет ордер в тот момент, когда цена пересекает скользящую среднюю, с задержкой, опережающей других розничных трейдеров.
  • Дашборд, обновляющий свечные графики в реальном времени без единого AJAX-запроса.
  • Систему оповещений, которая пишет вам в Telegram, когда спред превышает порог, а ваш ноутбук при этом простаивает с загрузкой CPU 2 %.

Переход от опроса к стримингу превращает вашу архитектуру из «спроси и жди» в «слушай и реагируй». Это разница между проверкой почтового ящика каждый час и почтовой щелью, которая звякает при каждом письме.

Попробуйте сами

Теперь, когда вы увидели заклинание, идите и попробуйте! Выберите любую биржу с WebSocket-тикером (Binance, Coinbase Pro, Alpaca и т.д.), скопируйте скелет выше и подпишитесь на нужный символ. А затем расширьте его:

  • Вычислите простую скользящую среднюю на лету.
  • Запустите тестовый ордер, когда цена отклонится от средней более чем на 0,5 %.
  • Записывайте каждое событие в файл и посмотрите, насколько чище выглядит лог по сравнению с версией на опросах.

Делитесь ссылкой на репозиторий или скриншотами живого тикера — посмотрим, кто сможет собрать самого быстрого бота!

Счастливого кодинга, и пусть ваши соединения остаются открытыми, а профит — высоким. 🚀

По материалам: finance. Текст переработан редакцией Слогера.

← На главную

Рекламное место — Конец поста
Реклама · Слогер

Комментарии (0)

Войдите, чтобы комментировать.

Пока нет комментариев. Будьте первым.