REST API для исторических рыночных данных: разработка под ключ

История сделок нужна аналитике, отчётности и проверкам, но из открытых источников она приходит с пробелами и задержками. Мы разрабатываем REST API для выгрузки исторических рыночных данных под ключ: от аудита источников до передачи готовой спецификации. Отдача ускоряется в разы, а пропуски в глубине истории закрывает регламент регулярных проверок.
Часто задаваемые вопросы

REST API разработка исторических данных: где теряется история

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

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

Цена для продукта — не косметика. Бэктест на рваной истории показывает доходность, которой не было, индикаторы считаются по неполному окну, отчёт расходится с графиком. Дальше рушится доверие к аналитике, и восстановить его дороже, чем починить отдачу.

Разбираем, как это закрывается в REST API разработке под исторические рыночные данные: контракт на диапазон и точность метки, проверка целостности истории на входе, идемпотентная догрузка пропущенного, кэш под повторные запросы и режим отдачи, который не зависит от лимитов запросов внешнего источника.

Что даёт выгрузка истории: полнота, скорость, устойчивость

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

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

Устойчивость сервиса дают кэш, ограничение частоты обращений к источникам и повторные попытки с нарастающей паузой. Если внешний источник недоступен, отдаётся последняя согласованная версия ряда, а не ошибка — терминал и аналитика продолжают работать. Независимой проверкой служит сверка с публичными агрегаторами, например CoinMarketCap.

Ручные правки пропусков ушли из процесса аналитиков: расхождения между источниками попадают в отчёт, а не в график. Заказчики в отзывах отмечают именно это — «архив перестал быть отдельной задачей: данные за нужный период готовы к началу торгового дня, а не к его середине».

REST API разработка: варианты отдачи истории и ограничения

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

Мы разводим эти сценарии по отдельным контурам: потоковая подписка не конкурирует за соединения с пакетной выгрузкой, а тяжёлые срезы уходят на реплику хранилища и не тормозят запись новых данных. Разница между режимами не в удобстве, а в том, какие ограничения вы принимаете вместе с ними.

Четыре режима и их пределы

Режим Когда подходит Ограничения
Постраничная выборка Интеграции, отчёты, добор пропущенных интервалов Число запросов растёт с глубиной истории; при рестарте нужен курсор, иначе получите повторы или дыры
Пакетная выгрузка Первичная загрузка, проверка стратегий, восстановление архива Данные отстают от текущего момента; разложить файл по своей схеме придётся на стороне потребителя
Потоковая подписка Онлайн-котирование, риск-мониторинг, расчёт индикаторов на лету Отдаёт только «с этого момента»; после разрыва соединения нужен догон через исторический запрос
Прямая выборка из хранилища Аналитика, произвольные срезы, сверка данных Только чтение и отдельная копия; схема фиксирована, любые изменения — через согласование

Ограничения — свойство режима, а не дефект: поток не отдаёт глубину, файл не догоняет реальное время, реплика не пишет. Поэтому в описании API мы фиксируем границы каждого режима и правила перехода между ними — догон после разрыва, курсор при рестарте, сверку данных между копиями.

От аудита источников до передачи: этапы инженерной работы

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

  1. Аудит источников данных. Смотрим форматы выгрузок, глубину истории, ограничения на частоту запросов и поведение площадки при сбоях. На выходе — перечень источников с пометками, где ожидаются разрывы и дубликаты.
  2. Проектирование схемы данных. Фиксируем сущности (сделки, свечи, стакан), таймзоны, точность округления и правила сращивания рядов. Схема становится контрактом: по ней строится и хранилище, и структура ответов API.
  3. Реализация. Собираем слой загрузки с повторными попытками и идемпотентной записью, чтобы повторный импорт не плодил дубликаты, и слой отдачи — с курсорной пагинацией и предсказуемыми кодами ошибок.
  4. Проверка на эталонном наборе. Небольшой отрезок истории размечаем вручную и сверяем с источником до последней записи. Расхождения ловим до того, как они уедут в аналитику.
  5. Приёмочная проверка. Прогоняем сценарии заказчика: редкие инструменты, границы периодов, пиковые нагрузки. Фиксируем, что отдача укладывается в оговорённые сроки и не теряет записи.
  6. Передача и наблюдение. Отдаём описание схемы, конфигурацию и порядок развёртывания, а после запуска следим за свежестью данных и задержкой ответа.

Порядок не случаен: каждый шаг опирается на артефакт предыдущего — перечень источников, схему, эталон. Поэтому приёмка закрывается до передачи, а не после.

Что остаётся у вас: спецификация, схемы, регламенты

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

  • Спецификация интерфейса — методы, параметры, форматы ответов, коды ошибок и лимиты обращений в машиночитаемом виде: из неё генерируются клиенты и тесты.
  • Схема данных — таблицы, ключи, типы, индексы и правила хранения истории; по ней видно, почему выборка по диапазону дат остаётся быстрой на растущем объёме.
  • Регламент обновления — расписание загрузки, окно догрузки пропущенных периодов, проверка целостности и сверка с источником.
  • Политика доступа — роли и области видимости, сроки жизни ключей, квоты на потребителя, журнал обращений и порядок отзыва доступа.
  • Документация для команды — локальный запуск, переменные окружения, миграции, метрики, чек-лист релиза и порядок отката.
  • Автотесты и эталонные примеры запросов — фиксируют ожидаемое поведение, чтобы правки в разборе исторических данных ловились до выката.
  • Инструкция на случай сбоя — что делать при пропусках или медленных ответах источника, как переключиться на резервный поток и чем подтвердить восстановление.

Практика: как закрыли дыры в истории и ускорили отдачу

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

Восстановление истории

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

Пиковая нагрузка и отдача

Под пиком сервис раньше рос в задержке: очередь запросов копилась, часть клиентов не дожидалась ответа на длинных диапазонах. Горячие диапазоны мы вынесли в колоночное хранилище ClickHouse, предрассчитали недельные и месячные агрегаты и ограничили размер страницы. На пике в двадцать раз выше обычного отдача держится ровно, сборка годового набора сократилась до минуты.

Результат проекта: история без пропусков, отдача под пиком без обрывов, документированные правила сведения источников и повторяемый прогон восстановления по расписанию.

Чем выгрузка истории отличается от потока реального времени

Архивная выгрузка в REST-интерфейсе отвечает на запрос по диапазону: клиент передаёт интервал времени и идентификатор инструмента, сервис отдаёт страницу записей с курсором на следующую. Результат детерминирован — повтор с тем же курсором возвращает те же строки, поэтому обрыв связи лечится перезапросом, а не восстановлением подписки.

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

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

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

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

Технические сомнения перед стартом работ

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

Что делать с пропусками в исторических данных источника?

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

Что произойдёт, если источник перестанет отвечать?

Отдаём последний подтверждённый срез вместе с временем его актуальности и признаком устаревания. Потребитель сам решает, работать с этими данными или ждать — вместо пустого ответа и разбора ошибки на своей стороне.

Можно ли расширить глубину истории позже?

Да, бэкфилл идёт диапазонами и порциями, контракт ответа не меняется — расширение не ломает уже написанных клиентов. Новые и ранее загруженные участки сверяются на стыках, чтобы на границе не появилось двойных или разъехавшихся значений.

Как проверяется, что данные совпадают с источником?

Сверка идёт по контрольным суммам срезов за выборочные периоды; расхождения попадают в отчёт, а не растворяются в логах. Это даёт воспроизводимость: одно и то же окно, запрошенное повторно, возвращает тот же результат.

Мы можем забрать свою выгрузку?

Выгрузка отдаётся потоком в файл по той же схеме полей, что и в REST-ответах, — данные переносимы и не заперты внутри сервиса. Формат выбираем под ваш конвейер обработки.

Дальше — обсуждение: опишите задачу, вернёмся с оценкой и планом.

Обсудим задачу и вернёмся с оценкой и планом

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

  • Глубина истории и источники: биржевые ленты, вендорские архивы, собственные выгрузки — за какой период нужны данные и где возможны пропуски.
  • Состав данных: тики или агрегированные свечи, интервалы, перечень инструментов и площадок, нужна ли корректировка котировок на сплиты и дивиденды.
  • Требования к качеству: полнота рядов, точность до знака, единая временная зона, правила разрешения расхождений между источниками и отсев дублей.
  • Формат ответа и навигация по объёму: JSON, CSV или Parquet; постраничная выдача, курсоры, фильтры по диапазону дат и инструменту.
  • Нагрузка и доступы: сколько одновременных запросов держит потребитель, нужны ли ключи, разделение прав и ограничение частоты обращений.
  • Актуализация и устойчивость: как часто догружаем новые данные, за какое время закрываем пропуск в архиве, что видит клиент при отказе источника.
  • Приёмка: на каких наборах сверяем выдачу с эталоном и какую долю запросов считаем уложившейся в целевое время ответа.

Опишите задачу в свободной форме и отметьте, что из перечисленного уже решено, — вернёмся с оценкой работ, схемой данных и планом внедрения по этапам.

Направления блокчейн-разработки

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1369
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    816
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1142