MoexFixFastTwimeFutures: Обзор кода в OsEngine, архитектура, модули.

MoexFixFastTwimeFutures: Обзор кода в OsEngine, архитектура, модули.

Сам проект OsEngine находится на GitHub по ссылке: https://github.com/AlexWan/OsEngine

Коннекторы используются для соединения с различными биржами, брокерами и их архитектура должна подчиняться определенным правилам. 

Рассмотрим исходный код коннектора MoexFixFastTwimeFutures, как учитывалась специфика работы протоколов, которые используются для совершения транзакций и получения биржевой информации. 

В структуре проекта OsEngine классы коннектора располагаются в папке MoexFixFastTwimeFutures, к которой ведет путь: OsEngine > Market > Servers:

Код коннектора поделен на 11 регионов, которые учитывают структуру интерфейса IServerRealization, который мы обязаны реализовать во всех коннекторах.

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

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

Поток 2 обрабатывает все сообщения, приходящие по FAST каналу FO-TRADES: проверяет пропуски, отделяет информацию по нужному инструменту и закидывает сообщение в очередь для разбора в потоке 3. Также в потоке 2 идет отслеживание начала дневного клиринга, в течение которого снимаются заявки и очищаются стаканы.

Поток 3 также проверяет пропуски, но уже в обновлениях по конкретному инструменту и в случае необходимости запускает процесс восстановления, парсит сообщение для создания экземпляра класса Trade:

Поток 4 обрабатывает FAST сообщения с обезличенными заявками для формирования стакана. Также проверяются пропуски, и в очередь на дальнейшую обработку уходят сообщения, относящиеся к инструментам, на которые мы подписаны.

В потоке 5 очередь сообщений с заявками разбирается на обновляемые в реальном времени и заявки, накопленные с начала торговой сессии.  Чтобы стакан правильно отображался в программе, необходимо собрать заявки из прошедшего периода и затем по уникальному идентификатору их находить, изменять или удалять, или добавлять новые.

Поток 6 - "HistoricalReplayMoexFast" запускается и ждет, когда придет команда от обработчиков трейдов или заявок о пропуске сообщений. В этом случае создается соединение по ТСР с сервером восстановления данных, и запрашивается определенный диапазон сообщений. Но этот способ восстановления можно использовать не часто, есть лимиты. Для восстановления сообщений по заявкам можно сделать только 1000 соединений в день, а по сделкам не более 15000.  Проверка на превышение количества запросов предусмотрена в коде:

В связи с тем, что в диапазон запрашиваемых сообщений входят и сообщения, не относящиеся к нашему инструменту торговли, и запросить можно не более 1000 сообщений за раз, то достичь лимита запросов за день – не проблема, по крайней мере на тестовом полигоне это наблюдается.

Поток 7 полностью отвечает за работу с торговыми протоколами TWIME и FIX. Поскольку на этапе запуска программы мы выбираем какой-то один протокол, метод ProcessTradingServerEvents разделен на соответствующие части, и в каждой содержится функция проверки данных для чтения сокета и функция поддержки связи с торговым сервером.

 

 

Протокол TWIME.

Перед отправкой сообщений на сервер их необходимо правильно сформировать в бинарный формат. Это происходит в методах класса TwimeMessageConstructor. Посмотрим на примере метода RetransmitRequest, которым мы запрашиваем пропущенные сообщения в количестве Count, начиная с FromSeqNo. Параметры сообщения должны иметь строго определенный в документации тип. Сначала объявляются переменные типа ushort - длина сообщения и ID. Далее создается список байтов типа List, затем в другом методе формируется заголовок сообщения, и полученный массив байтов добавляется в список. Далее получаем время отправки в виде наносекунд типа ulong. Используя метод GetBytes класса BitConverter, необходимые параметры конвертируем в массив байтов и также добавляем в список, который преобразуем в массив и возвращаем из метода.

Также в методе присутствует блок кода для формирования строки для логирования, которая возвращается по ссылке. Такой вид логирования потребовался для прохождения сертификации коннектора на Московской бирже.

Входящие сообщения по протоколу TWIME проходят первичную обработку в методе TwimeMessageReader. В связи с тем, что в одном TCP-пакете могут прийти несколько TWIME-сообщений от сервера, возникла необходимость сначала определить количество пришедших сообщений в массиве байтов, и если их оказывается более одного, то методом GetMessagesArrays класса ReplyTwimeMessage разделяем массив из пакета на массивы с одним сообщением и возвращаем их в списке типа List<byte[]>. А уже с отдельным сообщением разбирается метод ParseTwimeMessage:

Для разбора сообщения TWIME требуется знать его ID, который мы берем в массиве байтов, декодируя 2 и 3 индексы, и, исходя из представленной в документации схемы сообщения, мы просто, начиная с восьмого байта в массиве, достаем поля и декодируем в нужный тип:

Конечно, что-то можно улучшить в коде этого коннектора и придется адаптировать его к работе на реальном счете.

На сегодняшний день автотесты пройдены, сертификаты Московской биржи на торговые протоколы получены. Надеемся, что коннектор MoexFixFastTwimeFutures и в целом платформа OsEngine поможет вам успешно использовать ваши высокоскоростные торговые алгоритмы.

Поддержка OsEngine: https://t.me/osengine_official_support

16:20
35

Комментарии

Нет комментариев. Ваш будет первым!