Привет, Хабр! В этой статье я делюсь IT инструментами, которые позволили эффективно закодить автоматизированную систему торговли (АСТ) криптовалютой на централизованной (CEX) и децентрализованной (DEX) биржах. Система вышла в продакшн в начале 2022 года и работала только на централизованных биржах. После того как летом 2023 года правительство США начало блокировать работу криптобирж для граждан США, было принято решение о подключении децентрализованной биржи, так как децентрализация не требует проходить KYC.
Итак, начнём!
Архитектура бэкенда системы
Я исхожу из того что тысячи клиентов активно пользуются системой торговли, а значит, она должна быть надёжной, с понятной обывателю бизнес логикой, защищённой, масштабируемой. Система управляет чужими активами и взаимодействует с внешними независимыми сервисами, которые подвержены изменениям и простоям (downtime), поэтому необходимо иметь возможность быстрого добавления новой фичи или фикса бага.
Нарисуем архитектуру с тремя микросервисами. Каждый имеет свои задачи, т.е. не пересекающиеся по функционалу.
Слушатель соединяется с вебсокетом биржи и подписывается на определённые крипто пары, например, ETHUSDT, BTCUSD. Задачами Слушателя являются получение актуальных цен (2222 USDT за 1 ETH) и трейдов (с ID ордера).
Как только Слушатель определил, что ордер нашей торговой системы в статусе FILLED, он отправляет сообщение Контроллеру посредством брокера сообщений (Kafka или RabbitMQ). Это быстро (для Kafka миллион сообщений в секунду без проблем), надёжно, безопасно (SSL), масштабируемо (можно добавить много Контроллеров в качестве консьюмеров сообщений).
Дальше Контроллер задействует бизнес логику торговой стратегии. Микросервис отправляет запросы в биржу посредством REST API, используя эндпоинты create_order, get_order, cancel_order.
Если в вышеописанной цепочке произошёл сбой, то предусмотрен функционал, регулярно опрашивающий биржу о заполнении ордеров торговой системы. За это отвечает Дублёр. Во время сбоя такая дополнительная проверка позволит консистентно продолжить торговлю, хоть и с временной задержкой.
Универсальная библиотека взаимодействия с биржами
На крипторынке активно работают десятки бирж, каждая со своим API. При желании подключиться к новой бирже придётся изучать их API, заново писать в своём коде новый класс, добавлять новые тесты. Это может занять у разработчика до одного месяца. Чтобы минимизировать время разработки, рекомендую рассмотреть бесплатную универсальную библиотеку CCXT. Тогда архитектура будет реализовывать паттерн Proxy и выглядеть так:
Языки программирования
У моей системы пока нет серьезного требования к скорости обработки трейда, так как это не высокочастотная торговля. Поэтому не зазорно использовать те языки программирования, на которых уже написаны клиенты бирж или CCXT. Например, можете использовать не шустрый Python.
Обработка ошибок
В API бирж предусмотрены ошибки. Наиболее часто встречаемые из них:
у пользователя недостаточно денежных средств;
ордер не найден;
ошибка создания ордера;
истек срок действия API ключей;
не пройден KYC;
Система торговли должна уметь обрабатывать эти ошибки, иначе торговая логика клиента может быть нарушена и его бот перестанет создавать новые ордеры. Предусмотрите таймаут и ретрай. Добавьте функционал оповещения клиента о проблеме, которую может исправить только он.
Тестирование системы
Важно иметь интеграционные тесты. Для этого биржи предоставляют testnet API. То есть вы регистрируете пользователя в тестовой сети, и биржа бесплатно выдаёт ему тестовую криптовалюту, чтобы тестировать код вашей торговой системы. Я не реализовал CI, поэтому запускаю код торговой системы, Kafka и Redis в DockerDesktop. Имея опыт подключения ботов к централизованным биржам Binance, Kucoin, Bitso, дам лаконичный отзыв. Binance надёжна, с подробной документацией, с достаточно быстрой техподдержкой. У Kucoin бывают сбои или натыкаешься на неочевидную логику, главное научиться обрабатывать такие случаи.
Децентрализованная биржа
В сентябре 2023 года я искал децентрализованную биржу, по функционалу максимально приближенную к централизованной бирже. То есть такую, где можно создавать MARKET и LIMIT ордеры, слушать изменения статуса твоего ордера. Самая близкая что я нашёл - это была 1inch, но её функционал удовлетворял нашим потребностям менее чем на 70%. Поэтому пришлось написать DEX Component, напоминающий мини-биржу с функциями обработки и хранения ордеров. Схематично выглядит так:
UPDATE: В 2024г добавили свой смарт-контракт в Layer 2: вторая статья.