Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Биржевая ИТ-инфраструктура исторически включает в себя несколько торговых платформ. Три года назад мы создали еще одну. Зачем было инициировать новую разработку при многообразии существующих систем? Рассказывают Александр Стриковский и Александра Кузнецова из Блока развития торгово-клиринговых систем.
Предыстория
Мы с коллегами постоянно ищем возможности для модернизации торгово-клиринговых систем (ТКС). Команды находят новые идеи, но проверить их в основных ТКС обычно невозможно: слишком высока цена доработок и вычислительных ресурсов. Легкая система с модульной архитектурой на базе основной платформы — это новая степень свободы: в ней можно реализовывать сложные алгоритмы, обслуживать больше клиентов, и всё это без снижения запаса производительности.
Для подобных экспериментов нужна подходящая задача, и в 2018 году мы её нашли: на валютном рынке необходимо было реализовать новую для Мосбиржи технологию Request For Stream (RFS). Жёстких требований к её производительности не предъявлялось, но было понятно, что изменения коснутся критически важных частей торговой системы. Для минимизации рисков решили разработать лёгкое ядро, которое взяло бы на себя все вычисления, связанные с технологией RFS. Так появилась платформа Cricket.
Архитектура новой торговой платформы
Cricket представляет из себя платформу с модульной архитектурой. Функциональность системы определяется набором плагинов. Плагины с бизнес-составляющей специфичны для каждой задачи, а вот технологические могут использоваться без изменений в самых разных проектах. При проектировании системы решили максимально сосредоточиться на удобстве разработки перспективных систем на базе Cricket, поэтому отказались от хранения данных в общей памяти SystemV Shared Memory ради поддержки стандартных алгоритмов и контейнеров из stl и boost.
Архитектурно Cricket выглядит следующим образом:
Dispatcher — источник и хранилище транзакций. Передача сообщений по Multicast UDP, получение истории по TCP.
Store — хранилище сообщений.
Gateway содержит модули обработки информационных запросов, поступающих от клиентов, и модули обработки транзакций.
Engine — основной компонент, содержащий модуль обработки транзакций и запросов, а также модули взаимодействия с внешними системами. Именно здесь хранится бизнес-логика проектов, которые могут быть весьма разнообразными.
При проектировании системы мы старались предельно расширить область её будущего применения. В контексте Мосбиржи это означает взаимодействие с как можно большим числом приложений и сервисов в нашей торговой инфраструктуре. В частности, в Cricket реализовали механизм отложенных транзакций. В основной системе входящее сообщение всегда порождает транзакцию (внутреннее сообщение), которая обязана ответить в конце обработки. А входящий клиентский запрос в Сricket способен породить несколько транзакций, при этом только последняя из них ответит на запрос, а остальные выполнятся в отложенном (безответном) режиме.
Обращение к БД и клиринговые проверки (то есть проверка на наличие обеспечения для проведения транзакции) — операции, выполнение которых требует времени — теперь можно выполнять в фоне, без блокировки основного конвейера обработки транзакций. Cricket использует стандартные внутренние протоколы, а значит, может взаимодействовать с большинством наших подсистем, будь то индекс-сервер или клиринговая система.
Request for Stream
Мы уже упоминали, что отправной точкой для создания платформы Cricket стала технология RFS. Расскажем о ней чуть подробнее. Её бизнес-задача состоит в том, чтобы предоставить клиентам Мосбиржи доступ к котировкам валют мировых провайдеров ликвидности — крупных глобальных банков. Для этого необходимо подключиться к одной из торговых платформ, выступающей посредником между провайдерами и потребителями ликвидности, а затем организовать доступ для наших клиентов.
Порядок действий такой:
Потребитель объявляет аукцион по заданному инструменту торгов на заданный объём валюты.
Информация об аукционе становится доступна провайдерам ликвидности.
Провайдеры предлагают инициатору аукциона свои котировки на объём, из которых инициатор выбирает лучшие по цене.
При получении устраивающей его цены потребитель принимает котировку.
Информация о котировках отправляется в основную систему, где проходит необходимые проверки.
При успешном прохождении проверок в основной системе регистрируется сделка.
Каждый пользователь одновременно может участвовать в нескольких аукционах. Понятно, что связанные с ними вычисления легли бы ненужной нагрузкой на основную торговую систему. Вместо этого обмен транзакциями между потребителями и провайдерами ликвидности берёт на себя система RFS, построенная на платформе Cricket.
TWAP
Но внедрением RFS мы не ограничились. Ещё один проект валютного рынка Мосбиржи, реализованный на основе Cricket, — Time weighted average price (TWAP). Его основная идея — помочь участникам торгов продавать крупные объёмы валюты по лучшей цене, чем при использовании стандартных механизмов валютного рынка, например, заявок по средневзвешенной цене (VWAP, volume weighted average price).
Проблема продажи крупных объёмов валюты заключается в том, что котировка быстро съедает в биржевом стакане встречный объём с лучшими ценами и продолжает исполняться по менее выгодным. Суть алгоритма TWAP состоит в том, что крупная заявка будет разделена на более мелкие, которые будут проданы за заданное время по близкой к заданной цене.
К примеру, нам необходимо за 8 часов купить доллары за рубли в объеме $8 млн с подачей лимитированных заявок по цене 75 RUB/USD. Со времени старта исполнения заявки TWAP алгоритмический модуль начинает подавать в торговую систему сгенерированные заявки, равномерно распределённые по времени (по одной в час) и объёмам. Средний объём одной заявки Vср = общий объем валюты / число итераций. В нашем примере Vср = $1 млн. При условии, что каждая заявка исполняется полностью, операция может выглядеть так:
Если задать случайные отклонения для объёмов заявок и времени их выставления, то в течение дня алгоритм TWAP будет исполняться непредсказуемо:
Основные принципы алгоритма TWAP:
Объёмы заявок рассчитываются автоматически и учитывают неисполненные остатки от предыдущих заявок. Оставшийся общий нереализованный объём равномерно распределяется на оставшееся количество будущих заявок.
Алгоритмические заявки, направляемые в торговую систему, проходят все стандартные проверки, в том числе на достаточность единого лимита. При этом обеспечение блокируется только под заявки, непосредственно выставляемые в торговую систему, и под сделки, заключённые по этим заявкам.
Эта технология требует от торговой системы достаточно большого объема вычислений при реализации заявок. Система TWAP на базе Cricket позволила освободить основную торговую систему от лишней нагрузки.
ТКС Агро
На базе Cricket мы реализовали торгово-клиринговую платформу Агро, которая обеспечивает торги агропродукцией на НТБ. Она интересна тем, что функционирует полностью независимо от других наших торговых систем. Старые наработки для этой задачи не подходили — предыдущая система была написана 12 лет назад, потребовался бы слишком серьёзный объем доработок. Поэтому решили развернуть новый проект на базе лёгкого ядра. Разработка заняла всего 4 месяца, причем в неё была вовлечена совсем небольшая команда — и это с учётом того, что для обеспечения клиринга в Агро реализовали собственный бэк-офис. За счёт этого затраты на проект существенно сократились.
Другие разработки на базе Cricket
В этом году мы запускаем ещё несколько проектов с использованием лёгкого ядра. Например, решили задачу по досрочному возврату размещённых депозитов на денежном рынке (система Deposit). Она сопряжена с крупными вычислениями, которые мы выносим за пределы основной системы торгов. Deposit, в отличие от своих собратьев, взаимодействует главным образом с клиринговой частью платформы REBUS.
Результаты
В процессе создания платформы Cricket мы проверили несколько новых идей: хорошо зарекомендовали себя отложенные транзакции, значительно упростил разработку переход на хранение данных в стандартных контейнерах С++. Несмотря на различия в бизнес-логике, эксплуатация всех систем построена на схожих принципах, что упрощает подготовку специалистов к сопровождению каждой платформы.
За два года на базе Cricket мы реализовали пять проектов. Её модульная архитектура расширила возможности повторного использования кода, что существенно снизило время разработки новых систем: к примеру, на разработку Агро ушло всего 4 месяца, на разработку Deposit — 2 месяца. Все созданные системы не похожи друг на друга функционально, но используют одни и те же инструменты платформы. Это хорошая заявка на универсальность Cricket, которую мы планируем применять и дальше.