Нормализация данных криптобирж: где рвётся поток
Одна и та же сделка на двух площадках приходит разными полями. Где-то торговая пара — одно поле, где-то два независимых тикера; объём — то в базовой валюте, то в котируемой, а сторона сделки иногда уже сведена к «покупка/продажа», иногда отдаётся флагом инициатора.
Разные форматы котировок расходятся сильнее всего на метках времени: одни площадки отдают миллисекунды, другие — секунды, часть — в локальном поясе вместо UTC, а публикация сделки и её попадание в поток разнесены во времени. Если агрегировать как есть, свечи за один интервал не совпадут между площадками, а событие окажется в чужом окне.
Дальше начинается ручная сверка сделок: аналитик сводит выгрузки в таблице, сопоставляет идентификаторы, пересчитывает объёмы и вручную разбирает расхождения в выгрузках площадок. На день истории по нескольким площадкам уходят часы, и итог всё равно зависит от того, заметил ли человек пропуск.
Дороже всего обходится потеря истории при сбое. Если сборщик не фиксирует запись до того, как отдать данные дальше, падение процесса оставляет дыру, а площадка задним числом сделки не отдаёт — пробел в ряду остаётся навсегда и портит любые расчёты на его границе. Поэтому нормализация данных криптобирж строится на входе, а не на этапе отчёта — разбираем, как это закрывается.
Что даёт единый слой нормализации
Единый слой нормализации приводит все площадки к одной схеме: инструмент, сторона сделки, цена и объём в базовой единице, метка времени в общем часовом поясе, признак типа исполнения и разбивка частичных закрытий. Приведение идёт на входе, поэтому аналитика, торговые модули и отчётность читают один и тот же формат котировок — без отдельных переходников под каждую биржу. Транспортом служит Kafka: партиционирование по инструменту сохраняет порядок событий, а повторный разбор не разрушает уже записанную историю.
Подключение новой площадки сводится к коннектору и карте полей, а не к пересборке хранилища и правкам в коде потребителей. На практике это дни работы вместо недель: новый источник поднимается в тестовом контуре, сверяется с эталоном на историческом отрезке и включается в общий поток.
Автоматическое сведение источников закрывает основную часть записей — от 97 до 99% в зависимости от площадки. Спот и деривативы одной пары сопоставляются по инструменту и времени, расхождения ловятся по контрольным суммам объёмов за минуту. Остаток уходит в очередь на разбор: это выборочная проверка аномалий, а не поток ручных сверок, которые раньше съедали время дежурной смены.
Целостность истории сделок держится на идемпотентной записи по ключу «площадка + идентификатор сделки» и неизменяемом логе сырых ответов. Нормализацию можно переиграть заново и получить тот же результат — это спасает при уточнении правил или доразборе пропущенного участка. Заодно уходит целый класс ошибок: рассинхрон часовых поясов, разные обозначения одной пары, потерянные частичные исполнения и задвоенные сделки при перезапуске сбора.
Способы сбора котировок: сравнение подходов
Биржа не отдаёт котировки одним способом: свежесть и глубина истории приходят из разных каналов. Потоковая подписка на котировки держит постоянное соединение и отдаёт изменения по мере появления — задержка поступления котировок измеряется долями секунды, но буфер канала ограничен, и при обрыве связи пропущенный интервал приходится добирать отдельно. Пакетные выгрузки истории дают глубину истории сделок и полный срез книги за прошлые периоды, зато формируются порциями и заметно отстают от текущего момента.
Опрос по расписанию занимает середину: он предсказуем и не требует постоянного соединения, но на волатильном рынке между двумя запросами успевает пройти движение, которое в потоке мы увидели бы сразу.
| Подход | Когда подходит | Ограничения |
|---|---|---|
| Потоковая подписка на котировки | Онлайн-торговля, риск-контроль, витрины реального времени | Нужен контроль разрывов и догрузка пропусков, число одновременных подписок ограничено |
| Опрос по расписанию | Портфельная аналитика, отчёты, оповещения, редкие сигналы | Задержка поступления котировок растёт вместе с интервалом, а частые запросы упираются в лимиты биржи |
| Пакетные выгрузки истории | Проверка стратегий на прошлых данных, аудит, разбор инцидентов | Глубина истории сделок ограничена окном выгрузки, данные приходят с отставанием |
Что берём в связку
Совместимость достигается не выбором одного подхода, а их связкой: поток держит горячий слой и оперативные витрины, выгрузки дозаливают историю, опрос страхует на случай разрыва. Ключевое условие — единая модель инструмента и времени, иначе одна и та же сделка приходит из разных каналов с разными идентификаторами и не склеивается.
Этапы внедрения: от аудита источников до передачи
Порядок работ строим так, чтобы каждое решение подтверждалось поведением источника, а не предположением. Сначала фиксируем, что площадки реально отдают, затем собираем целевую схему и только после этого пишем код — иначе переделка обойдётся дороже, чем сам разбор.
- Аудит биржевых источников. Разбираем потоки сделок, стакана и выгрузки истории: форматы ответов, частоту обновления, пагинацию, лимиты запросов, поведение при обрыве соединения. Отдельно помечаем источники, которые отдают данные с задержкой или пересчитывают задним числом.
- Карта расхождений. Сводим в одну таблицу различия площадок: идентификаторы инструментов, точность цены и объёма, часовые пояса и метки времени, обозначение стороны сделки. Она же становится рабочим документом при добавлении новой биржи.
- Правила сведения записей. Описываем единую схему события: ключ, приведение символов, округление, разметку дублей и переоткрытий. Правила версионируем — правка не ломает уже собранные наборы данных.
- Сборка. Реализуем приём, нормализацию и запись в хранилище с идемпотентной обработкой: повторный запуск не создаёт дублей, пропуск закрывается добором истории.
- Проверка на исторических данных. Прогоняем правила на накопленном архиве: сверяем число событий и объёмы, стыки при перезапуске, восстановление после пропусков. Каждое расхождение разбираем до причины, а не сглаживаем фильтром.
- Передача системы заказчику. Отдаём конфигурации, схему хранения, регламент контроля качества данных и порядок действий при сбое источника, обучаем команду. После передачи система работает и развивается силами заказчика — наша поддержка остаётся опцией, а не условием.
Что передаём на руки: конфигурации и регламенты
Передаём не только работающий контур, но и комплект, по которому его можно развивать без нас. Каждый артефакт привязан к конкретной операции: подключить новую биржу, разобрать расхождение в свече, сменить ответственного или понять, почему источник отвалился ночью.
- Конфигурации подключений — по каждой бирже: перечень торговых пар и потоков, лимиты обращений, схема переподключения, поведение при рассинхроне и пропуске сообщений.
- Схема нормализации — единая модель инструмента и события сделки, правила приведения тикеров и отметок времени к одной шкале, обработка переименований и дроблений.
- Справочники соответствий — таблицы между биржевыми и внутренними идентификаторами и порядок добавления нового источника без правки кода.
- Правила доступа — роли на чтение данных, изменение маппинга и конфигураций; журнал изменений, чтобы каждое вмешательство было объяснимо.
- Регламент сопровождения — реакция на новый листинг, смену формата и отключение источника, периодичность сверок, точки эскалации.
- Документация системы — архитектурная схема, описание потоков данных, чек-лист подключения биржи и список известных ограничений.
- Приёмочный набор — тестовые события с ожидаемым результатом нормализации, чтобы расхождения ловились проверкой, а не через недели после запуска.
Отдельно фиксируем, что остаётся на вашей стороне: ключи доступа, контакты с биржами, политика хранения истории.
Кейс: консолидация котировок с четырёх площадок
Клиент — фонд алгоритмической торговли на четырёх площадках, включая Bybit. Каждая отдавала сделки и стакан в своём виде: время в секундах и миллисекундах, у части площадок — локальное, без смещения, а один и тот же инструмент писался как BTC/USDT, BTCUSDT и XBTUSD.
Сверка шла вручную: аналитик собирал выгрузки в таблицы и находил расхождения уже в готовом отчёте — по объёмам, времени и пропущенным интервалам. Один торговый день занимал около шести часов, и на этом объёме терялись редкие, но значимые аномалии.
| Метрика | До | После |
|---|---|---|
| Доля автоматически сведённых записей | 63% | 99,4% |
| Время подготовки отчёта за день | 5-6 часов ручной сверки | 9 минут |
| Расхождения на 10 000 сделок | около 430 | единичные, каждое объяснимо |
Основой стала единая модель данных: время приводится к UTC, инструменты — к общему справочнику с пересчётом обозначений, сделки дедуплицируются по идентификатору площадки, снапшот стакана склеивается с последующими изменениями. Каждая запись хранит источник, поэтому расхождение разбирается до исходного сообщения.
Проверки на разрывы и рассинхрон выполняются на входе, а не в отчёте: запись с неполной цепочкой событий помечается и уходит в отдельную очередь на разбор. Отчёт формируется по расписанию, и ручная сверка превратилась из обязательного этапа в исключение.
Что делать, если у биржи уже есть свой канал поставки?
Ломать работающий канал не нужно. Если у биржи уже есть свой канал поставки котировок, он становится ещё одним приёмником в общей схеме: нормализующий слой ставится поверх него и приводит поток к единому виду, а не подменяет источник.
Технически это выглядит так: приёмник читает то, что уже отдаёт существующий контур — потоковое соединение, файлы выгрузок или FIX, — и публикует события во внутреннюю модель. В ней у каждого события фиксированы инструмент, тип, метка времени с точностью до источника и признак происхождения, поэтому расчётный модуль, архив и витрина не знают и не должны знать, из какого канала пришли данные.
Дальше начинается сосуществование двух контуров и постепенная миграция источников. Новый контур и самописное решение идут параллельно: расхождения по объёму и по ценам считаются автоматически, и источник переключается на нормализованную ветку только после подтверждённой сходимости. Порядок — по одному источнику за раз, с возможностью вернуть прежний маршрут без остановки сбора.
Отказ от самописного решения происходит не «в один день», а по мере перекрытия источников: сначала с него снимается запись и он остаётся в режиме чтения для сверок, затем выключается. Так встраивание в существующую схему не превращается в разовый рискованный переезд — цену ошибки платит один источник, а не весь сбор котировок.
Технические сомнения: разбор частых вопросов
Площадки меняют схемы ответов без анонсов: поле переименовали, вложенность сдвинули, число превратили в строку. Ломается не приём, а разбор — и дальше расходится всё: ордера, сделки, свечи, свечные агрегаты.
Поэтому контракт на вход описываем декларативно: схема, типы полей, обязательность, правила приведения. Расхождения уходят в карантин, а не в основную витрину. Ниже — вопросы, которые чаще всего задают инженеры заказчика.
Площадка сменила формат ответа — витрина поедет?
Маппинг полей живёт отдельным слоем конфигурации, а не в коде обработки. Новая схема подключается как новая версия, старая остаётся доступной для сверки. Пока поток не пройдёт проверку на эталонной выборке реальных ответов, он идёт в карантин — расхождения видно, но данные потребителей не портятся.
Как выравниваете метки времени разных площадок?
Храним два значения: время события по часам площадки и время приёма у нас. Метки приводим к единому часовому поясу, разбираем целые секунды, милли- и микросекунды, отдельно считаем и компенсируем сетевую задержку. Свечи, собранные из разных источников, после этого не расходятся между собой.
Что произойдёт при отказе источника или разрыве связи?
Переподключение с нарастающей паузой, параллельно резервный транспорт опроса и буфер на диске, чтобы не потерять пропущенный интервал. Повторы гасятся по ключу записи, поэтому дубликаты не накапливаются. Пропуск фиксируется в отчёте о полноте, а не остаётся незамеченным.
Подключаете новый источник и переобрабатываете историю?
Адаптер источника собирается по общему контракту, отдельно описывается справочник инструментов и правила сопоставления тикеров. История догружается порциями с проверкой контрольных сумм, запись идемпотентна — повторный прогон за тот же период не создаёт дублей и сходится с исходными данными.
Обсудим вашу задачу и вернёмся с планом
Чтобы обсудить задачу нормализации предметно, на входе нужен перечень источников котировок и текущая схема доставки данных. Чем конкретнее список площадок, инструментов и требуемых типов сообщений, тем точнее оценка состава работ — без допущений, которые потом превращаются в переделки. Пришлите то, что есть: черновик, таблицу сопоставления полей, фрагмент конфигурации.
Дальше разбираем по пунктам:
- Перечень источников котировок — площадки, число инструментов, нужны ли сделки, стаканы, индексы и метки времени.
- Текущая схема получения — прямое подключение, сторонний агрегатор, выгрузки, наличие исторических архивов.
- Целевой формат и потребители — куда отдаём данные и какие поля обязательны для торговой системы, аналитики или хранилища.
- Требования к задержке и полноте — допустимое отставание котировок, глубина истории, поведение при разрыве соединения.
- Особенности инструментов — нестандартные тикеры, разные шаги цены и размеры лота, правила округления на каждой площадке.
- Что уже работает — схемы таблиц, очереди, собственные скрипты нормализации: сохраним то, что не мешает, и не будем ломать работающий поток.
- Ограничения и сроки — доступы, проверки на вашей стороне, дата ввода в эксплуатацию, кто принимает результат.
После разбора вернёмся с оценкой состава работ, планом внедрения и сроками по этапам, с точками приёмки на каждом.







