Дед Нечипор
Дед Нечипор личный блог
25 июля 2023, 07:54

Немного о сервере данных для торговли

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

На данном этапе увлекло меня создание транзитного сервера для данных. Что подразумевается под транзитным сервером?
Допустим, есть сторонний датафид. И мы хотим логически (а при необходимости и физически) разнести инфраструктуру для торговли.
Наш сервер будет получать Live-данные от датафида, кэшировать, сохранять на диск и в то же время ретранслировать видоизмененный поток данных клиенту, где бы тот ни находился — на той же машине или на удаленной.

Что это нам дает?
Будем исходить из того, что, даже если датафид позволяет запрашивать исторические данные, их содержимое может существенно уступать по детализации Live-данным, поставляемым тем же датафидом.
К примеру, IQFeed в виде тиков дает историю трейдов с лучшими Ask и Bid только на момент сделки, в то время как Live-данные транслируют весь поток L1. Если торговая система L1 не использует, то разница для нас значения не имеет.
В противном случае (а также если мы позже захотим использовать эти данные для тестирования ТС на инструментах, где за день проходит малое количество сделок — малоликвидные акции или опционы), отсутствие данных послужит досадной помехой.
И вот тут критическую роль сыграют обрывы связи (или перебои электропитания), если вся торговля ведется на нашем локальном компьютере. Решение очевидное — перенести программную инфраструктуру на удаленный сервер.
Пойдем немного в сторону — создадим программную прокладку, упомянутую выше. Таким образом, мы обезопасим себя (или, во всяком случае, минимизируем риски) от пробелов данных, связанных с потерей соединения или питания, и в то же время можем разместить торговую логику на другом компьютере.
К примеру, на домашнем. Зачем так делать? Допустим, торговая логика использует очень «тяжелые» вычисления или нуждается в огромном количестве памяти, а оплачивать машину в облаке с такими параметрами выльется в немалую «копеечку». А дома уже стоит системник с подходящими характеристиками и стоимостью как аренда в облаке за полгода аналогичного. Да и если торговый алгоритм из-за ошибки при разработке «сожрет» всю доступную оперативу, это не приведет к падению сервера данных, так как они на разных машинах.
Понятно, что такой подход всего лишь решает вопрос целостности данных, но в данном случае задача состоит именно в этом.

Таким образом, убедив самого себя, что изобретать велосипеды — это совсем ни разу не потеря времени, приступил к основам.
Как я уже писал, выбор пал на Windows Registered I/O.
Учитывая, что знаний в области сетевых коммуникаций у меня было не так и много, кроме самых общих, то процесс вливания в разработку транзитного сервера сопровождался созданием некоторого количества тестовых программ для уверенности, что все будет работать так, как я ожидаю.
Что привело меня к «открытию» таких чудес, как алгоритм Нагеля и delayed ACK… В связи с чем появилась надобность новых тестов.
И вот здесь мы, наконец, подходим к теме данного топика. Все далее описанное предполагает использование протокола TCP/IP, ОС Windows Server 2019.


RIO позволяет работать с множеством буферов для отправки и получения данных. И меня заинтересовало, какими рассуждениями следует руководствоваться при выборе количества буферов и их размера.
Если вы думаете, что это не имеет значения, попробуйте отослать несколько мегабайт с сервера, имеющего один буфер размером 64 байта. Я попробовал.
Итак, покопавшись и интернете в попытках разобраться в причинах такого результата, я приобщился к таинствам вуду протокола TCP/IP. С учетом приобретенных знаний, логически рассуждая, ответ на вопрос о количестве и размере буферов становится достаточно очевидным.
Но убедиться все равно надо. Тем более, что нам нужно остановиться на разумном количестве, обеспечивающем желаемую пропускную способность сервера.

Что используем: два сервера, физически разнесенных как можно дальше друг от друга для обеспечения максимальной латенси — один в США, другой в Европе. Пинг между серверами показал 157мс, хотелось бы побольше, но и так сойдет.
На одном сервере клиент для считывания данных (со статичными значениями размера и количества буферов чтения), на другом сервер. Батником в консольном режиме запускается сервер, в командной строке параметрами передаются значения размера буфера отправки и их количество.
В течении одной минуты сервер отсылает подготовленные данные клиенту, завершает работу, затем батник запускает сервер со следующим набором параметров. В отдельном потоке логгер каждые 160 мс считывает значение счетчика отправленных байт за этот промежуток времени, при завершении работы сервера сохраняет последовательность в файл на диске.
Синхронизация не используется, просто запись-чтение (данные выровнены по 8-байтной границе). Почему 160мс? Выбирал значение, кратное 16мс, чтобы получить несколько отсчетов за 1 секунду.
Логика теста пропускной способности: сервер сначала отправляет данные из всех буферов, дожидается подтверждения первого отправленного пакета, затем активирует логгер. Как только какой-либо буфер становится свободным — сервер отправляет из него данные величиной в размер всего буфера.
Клиент после закрытия соединения ждет 3 секунды, прежде чем приконнектиться к серверу — как уже говорил, конструировалась максимально простая связка сервер-клиент для теста в пакетном режиме пропускной способности при заданных параметрах и латенси.
На мой взгляд, одной минуты достаточно, чтобы получить представление — получается около 400 отсчетов.


Проводилось три типа тестов:
1) Размер буфера фиксирован — 8192 байта; количество меняется от 1 до 8192, являясь степенью двойки (общий размер до 64 Мб)
2) Суммарный размер (<размер буфера> * количество) фиксирован 64 Мб, размер и количество меняются, являясь степенями двойки
3) Размер буфера фиксирован — 65536 байт; количество меняется от 1 до 1024, являясь степенью двойки (общий размер до 64 Мб)

Тесты проводились дважды, клиент для считывания использовал 16 буферов размером 4096 байт в первый проход, 256 буферов размером 8192 во второй. Картина наблюдалась аналогичная при соответствующих параметрах сервера.
Тестирование не предполагало получение исчерпывающих, точных результатов, поэтому не исключено влияние внешних факторов, таких как: работа планировщика потоков ОС, нагрузка на сеть сторонних приложений или клиентов, балансировка максимальной пропускной способности софтом облака (если таковой существует) и т.п.




И шо вы таки себе думаете? Этот хитрый делец Билли Гейтс ворует нашу пропускную способность!

Немного о сервере данных для торговли



Пояснения к графикам:
по оси Х — количество отсчетов от запуска сервера (каждый отсчет — 160 мс)
по оси Y — количество байт, переданных ОС «на отправку» за время отсчета
имя графика Srv_aaa_bbb — aaa — размер буфера в байтах, bbb — количество буферов

Соответственно, чтобы получить пропускную способность сервера в байтах/секунду нужно значение по Y разделить на 0.16, в битах/секунду — еще домножить полученное значение на 8
Как легко догадаться, координата 18 000 000 дает 900МБит/секунду — близко к потолку гигабитной сети


Итак, что же мы видим?

Тест1. Фиксированный размер буфера 8192, количество меняется.
Результат предсказуем:

Немного о сервере данных для торговли
Немного о сервере данных для торговли
Немного о сервере данных для торговли
Немного о сервере данных для торговли


повторный проход (приводится только часть графиков — остальные не имеют заметных отличий):


Немного о сервере данных для торговли

Немного о сервере данных для торговли


Тест3. Фиксированный размер буфера 65536, количество меняется.


Немного о сервере данных для торговли
Немного о сервере данных для торговли
Немного о сервере данных для торговли


повторный проход (приводится только часть графиков)


Немного о сервере данных для торговли



Тест2. Суммарный размер фиксирован — 64 Мб


Немного о сервере данных для торговли
Немного о сервере данных для торговли
Немного о сервере данных для торговли


повторный проход


Немного о сервере данных для торговли
Немного о сервере данных для торговли
Немного о сервере данных для торговли



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

Исходя из результатов тестов, можно предположить, что причиной нестабильных результатов является одна из трех возможностей:
а) когда канал забивается до допустимого потолка
б) если суммарный размер одновременно используемых буферов превышает максимальный размер внутреннего буфера ОС (точное значение размера не сообщается, судя по информации с сайта Майкрософта, и может варьироваться в зависимости от ОС).
  Если присмотреться к графикам, можно предположить, что проблемы начинаются, когда суммарный размер превышает 8 Мб.
в) мне просто не повезло, и именно во время тестирования конкретных параметров сеть приходилось делить с кем-то еще (может, ОС решила что-то подгрузить?). Во время обоих проходов.

Вопрос к залу: что, по вашему, послужило причиной «расколбаса» пропускной способности сервера? «Индусский код» в качестве причины пока вынесем за рамки обсуждения.

41 Комментарий
  • Fairman
    25 июля 2023, 08:09
    Как всё вышеописанное влияет на прибыльность торговли?
  • Тимофей Мартынов
    25 июля 2023, 09:44
    Спасибо! Приятно видеть такие статьи на смартлабе!
    Вывел на главную
  • Брахман Пилорама
    25 июля 2023, 10:00
    Шишки, грабли, windows не меняется.
    Не строят такие системы на винде. Если конечно хочется не получить очередными граблями под конец тяжких трудов.

    Ну и главное — нет смысла в ретрансляции данных. Есть смысл в заливке их в быструю среду, наложение на них необходимых функций, предагрегация и упаковка в быструю БД с компрессией. Тогда можно работать с этими данными в реальном времени, обставляя 99% наколенной бытовухи на винсерверах.
  • Иван Котиков
    25 июля 2023, 10:03
    Есть такая штука, называется брокер сообщений: RabbitMq, Kafka и т.д. зачем изобретать велосипед?

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн