Currencyinfo 4.2.0: автономный сервис справочных курсов для криптовалют и фиата

Любой кошелек, обозреватель блоков, платежный сервис, бухгалтерский инструмент или приложение для управления портфелем рано или поздно задается вопросом: какова стоимость этого актива прямо сейчас? Сложность заключается не в выполнении одного API-запроса. Трудности возникают при выборе надежного источника, нормализации данных с разных рынков, преодолении квот и сбоев, отсеивании некорректной информации, сохранении истории и объяснении причин изменения котировок. Currencyinfo создан для решения этих задач, и начиная с версии 4.2.0, он больше не является внутренним компонентом ADAMANT. Это универсальный сервис справочных курсов с открытым исходным кодом, который можно развернуть на собственных мощностях для любых проектов, работающих с данными о криптовалютах и фиатных валютах.
Справочный курс не должен быть загадочным числом, взятым у единственного поставщика. Это должен быть наблюдаемый результат, полученный на основе правил, которые вы контролируете.
Агрегация данных из нескольких источников
Ценообразование на основе одного источника удобно до тех пор, пока этот источник не начинает ограничивать запросы, удалять рынки, менять формат данных, становиться недоступным в вашем регионе или выдавать аномальные значения. Currencyinfo 4.2.0 позволяет перепроверять данные до десяти независимых поставщиков и преобразовывать их котировки в единый настраиваемый справочный курс.
В этом релизе добавлены четыре коннектора, не требующих ключей API: CoinPaprika, CoinLore, Binance и ExchangeRate-API. Вместе с Currency API стандартная конфигурация теперь включает пять источников, работающих без учетных данных. CoinGecko по-прежнему доступен с демо-ключом; CoinMarketCap и ExchangeRate.host поддерживают аутентифицированные настройки; MOEX предоставляет еще один специализированный вариант. CryptoCompare сохранен для совместимости, но теперь считается устаревшим и отключен по умолчанию, так как для нового доступа требуется подписка.
Поставщики различаются по охвату активов, частоте обновлений, региональной доступности, квотам и рыночным допущениям. Currencyinfo делает эти различия явными, предоставляя операторам инструменты для управления тем, как эти факторы влияют на итоговый курс.
От котировок к обоснованному курсу
Конвейер обработки данных проходит пять этапов. Источники опрашиваются по собственному расписанию. Валидация нормализует пары и отбрасывает нулевые или нечисловые кросс-курсы. Агрегация обнаруживает расхождения, применяет группы и весовые коэффициенты, а также использует параметр minSources для принятия решения о том, достаточно ли данных для публикации курса. История сохраняется в виде снимков в собственной базе данных MongoDB оператора. Наконец, REST API предоставляет доступ к текущим и историческим курсам через специализированные конечные точки.

Это краткое описание скрывает несколько полезных функций управления. Группы авторитетных источников можно отделить от резервных групп. Весовые коэффициенты и стратегии объединения позволяют задать правила комбинирования данных от разных поставщиков. Детерминированная триангуляция базовой монеты позволяет вычислить пару, если прямая котировка недоступна. Управление актуальностью через rateLifetime предотвращает использование устаревших данных.
Что наиболее важно, параметр minSources теперь учитывает актуальность данных. Настроенный поставщик, который перестал предоставлять корректные данные, больше не учитывается только на основании своего присутствия в конфигурации. Сервис публикует курс только при наличии достаточного количества актуальных данных и предсказуемо деградирует, если их недостаточно. Устойчивость заключается не в том, чтобы делать вид, что каждый поставщик всегда работает исправно, а в том, чтобы знать, какие данные актуальны, каких не хватает и как ваша система должна реагировать на это.
Улучшения для операторов
Currencyinfo 4.2.0 также усиливает внутренние компоненты системы. Три индекса тикеров, отсортированных по дате, делают запросы к истории более эффективными при масштабировании. В тестовом наборе данных, содержащем около 238 миллионов документов, один репрезентативный запрос по паре и диапазону ускорился с 22,8 секунды до 8 миллисекунд. Реальные результаты зависят от оборудования, распределения данных, состояния кэша и типа запроса, но направление очевидно: накопленная история теперь гораздо проще в эксплуатации.
Сервис переведен на Node.js 22.12 или новее, а платформа обновлена до NestJS 12, Mongoose 9, Zod 4, TypeScript 6 и Jest 30. Полный набор тестов теперь включает 28 комплектов и 266 проверок.
Распространение через контейнеры стало приоритетным методом выпуска. Образы публикуются для linux/amd64 и linux/arm64 с OCI-метаданными, SBOM и данными о происхождении сборки. Среда выполнения работает без прав root, менеджеры пакетов удалены из производственного образа, логи используют строгие права доступа, секретные значения скрыты, а CI-конвейер включает сканирование уязвимостей.
Для нового развертывания самый быстрый путь — использование публичного образа:
docker pull ghcr.io/adamant-im/currencyinfo:4.2.0

Четкие границы
Currencyinfo создает справочные курсы. Это не лента исполнения сделок для биржи, не терминал высокочастотных рыночных данных и не хостируемый API с гарантированным SLA. Самостоятельное развертывание дает вам контроль над конфигурацией, историей, конфиденциальностью и доступностью; оно также возлагает на вас ответственность за мониторинг развертывания и соблюдение условий, лимитов и правил перераспределения данных каждого вышестоящего поставщика.
Обновление с версии 4.1.2 требует планирования. Старые конфигурации могут включать поставщиков, для которых теперь требуются учетные данные, поэтому перед запуском 4.2.0 операторам следует отключить такие источники, добавить ключи или принять новые настройки по умолчанию без ключей. Для больших существующих баз данных истории следует создать три новых индекса отдельно: в ходе измерений при выпуске это заняло около 17 минут на NVMe-накопителях и 50 минут на SATA. Форматы хранимых документов остались совместимыми, что упрощает откат версии.
Следует отметить одно изменение в поведении: фильтры истории теперь используют задокументированный порядок пар БАЗА/КОТИРОВКА. Клиенты, которые ранее компенсировали это переворотом пар, должны удалить это обходное решение. Неизвестные параметры запроса теперь также отклоняются с ошибкой HTTP 400 вместо того, чтобы игнорироваться.
ADAMANT остается в проекте, так как использует Currencyinfo в своей работе и продолжает курировать его развитие. Однако проект не ограничивается только ADAMANT. Он в равной степени актуален для независимых кошельков, обозревателей блоков, платежных бэкендов, бухгалтерских систем или операторов инфраструктуры, которым нужен сервис курсов с возможностью проверки, настройки и локального запуска.