Дед Нечипор
Дед Нечипор личный блог
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 и т.д. зачем изобретать велосипед?
    • Брахман Пилорама
      25 июля 2023, 11:02
      Иван Иванов, нужно следить за развитием технологий, пожелаем автору этого, потому что энергии у него уже есть (был) вагон
        • Брахман Пилорама
          25 июля 2023, 11:24
          Дед Нечипор, знания — сила, потому что позволяют не заниматься велосипедингом.
  • Roman Ivanov
    25 июля 2023, 10:17
    От прочитанного картинка не сложилась. Вроде речь про TCP, но в то же время и про какие-то подтверждения. Отправка запуском бантиков порядка 10раз в секунду доставляет.
    В сетевых коммуникациях я разбираюсь, можем голосом обсудить
  • Sprite
    25 июля 2023, 10:37
    Лонгрид осилил. Это конечно очень интересно, но по моему маркет-дату лучше покупать. Во первых не надо городить инфраструктуру, а во вторых, если вам завтра захочется новый инструмент исследовать, то вместо исследований вы будете ждать пока накопите данные. Ну а если вы вообще весь поток сохраняете, то вы сами становитесь копией какого-нибудь IQ-фида. Эдакое «Закешируйте мне весь интернет, я его на даче в офлайне читать буду» )
      • Sprite
        25 июля 2023, 11:22

        Дед Нечипор, всё продается, L1, L2, full order log
        PS Но сам я коплю, а не покупаю )

  • Сиделец
    25 июля 2023, 11:29
    Вам бы с таким на хабр. Тут всё такие «серьёзные трейдеры» собрались, которые знают как изменение ставки влияет на бизнес и потребителя, а Вы им про delayed Ack :)
      • Сиделец
        25 июля 2023, 12:30
        Дед Нечипор, это скорее на хабре в последнее время странности разные полезли левые — давно забросил читать.
        Так то да, может тут тоже кто в теме откликнется. Мне просто казалось что «бытовые алгоритмисты» обычно более высокоуровнеными инструментами пользуются, тут же слишком приземлённо и многие вопросы ценны сами по себе, без привязки к торговле.

        (имхо лезть в такое имеет смысл чтобы набить руку и зарабатывать прикладными навыками в другой области, или на дядю работать за зарплату. Ну может конечно еще и просто как развлечение если пассивный доход уже позволяет в игрушечки играться).
  • vlad1024
    25 июля 2023, 12:16
    Так и не понял, что там тестировалось и зачем. Windows registered IO, и задержка в 160 мс, вы серьезно? Там ожидаемые улучшения от WRIO, будут в районе микросекунд или меньше. Речь конечно про latency, гигабит throughput прокачивается без проблем и на сокетах.
    А по поводу ваших вопросов, данные не телепортируются. Они бьются на пакеты, и идут по проводам/оптике, через маршрутизаторы, чем длиннее этот путь, тем больше задержки и меньше пропускная способность.
      • vlad1024
        25 июля 2023, 12:27
        Дед Нечипор, да это я более менее понял. Проблема в том что в алготрейдинге вы вряд ли упретесь в пропускную способность канала(throughput), гораздо важнее задержка(latency). Никто не ставит сервера, чтобы торговать на другой стороне океана от источника данных и исполнения.
        И вторая проблема, что Windows RIO это достаточно сложная технология тем более прибитая к винде(да есть io uring, но сути не меняет). Поэтому для начала хорошо бы было сравнить WRIO со стандартными сокетами. И посмотреть, есть ли у WRIO какие-то реальные преимущества на ваших задачах.
          • vlad1024
            25 июля 2023, 13:01
            Дед Нечипор, так это лично у меня основной вопрос, есть ли существенные преимущества у WRIO перед обычными сокетами. Сокеты это и есть самый низкий уровень, они дальше уходят в ядро, сетевой стек и железо. Проблема очевидно не в винде и сокетах, а в кривой прикладной программке.
              • vlad1024
                25 июля 2023, 13:34
                Дед Нечипор, так Delphi уже давно не поддерживается, и косяки там вполне могут быть. Вероятность найти ошибку в виндовых сокетах, просто нулевая. Если бы вы сами написали код с вызовом системных send/receive/select без делфи, тогда можно было бы посмотреть.
          • Иван Котиков
            27 июля 2023, 09:31
            Дед Нечипор, у дельфи менеджер памяти не очень работает под нагрузкой, или уменьшайте операции с памятью создание/удаление объектов, делайте фиксированные буфферы или высоконагруженые части лучше переписать на C#.
      • Андрей К
        25 июля 2023, 14:05
        Дед Нечипор, 
         Цель тестирования — проверить, есть ли разница в том, какой набор буферов использовать. Если утрировать — один, но большой, или маленькие, но ооочень много (повторять голосом Карцева). Я-то не знаю, вдруг, начиная с какого-то размера будет заметная деградация
        с большой долей уверенности могу сказать, что какой бы буфер не послали, ваша же система сразу нарежет его пакетами = MTU, то есть по 1514 байт и будет фигачить в кабель такими пакетами.

        поэтому пропускная способность линка выходит на пиковое значение в диапазоне 1300-1500 байт на пакет. Если вы начинаете повышать сайз, то сразу попадает на фрагментацию (нарезка по 1500б), а это тоже время и задержки
        • vlad1024
          25 июля 2023, 14:39
          Андрей К, вызовы сокетов не нарезают пакеты, лишь копируют во внутренний буфер сокета/ОС, дальше идет вниз по сетевому стеку и прерываниям железки, где уже поток байт сокета превращается в пакеты. Оптимально закидывать по свободному размеру буфера сокета, так как системный вызов — тоже действие затратное.
          • Андрей К
            25 июля 2023, 14:42
            vlad1024, так это… когда идет вниз, там и нарезается ) либо в в ОС, либо если сетевуха нормальная не дешевая, то нарезает она на уровне TCP
      • vlad1024
        25 июля 2023, 12:42
        Дед Нечипор, а вы уверены что WRIO дает какие либо значимые улучшения, по сравнению с обычными сокетами? )
  • Synthetic
    25 июля 2023, 13:54
    Тогда надо было и Windows Server с нуля переписать. Под свои задачи.

  • Андрей К
    25 июля 2023, 14:01
    в tcp еще много секретов ) временами они мне все снятся ) удачи в посвящении
  • Anest
    25 июля 2023, 14:29
    Мне кажется, это тот случай, когда из алготрейдинга «убегают в серверостроителей/программистов». Такое часто бывает, вместо того, чтобы допиливать системы, погружаются в «рисование красивых кнопочек». Сам такое проходил. Хотя красивые и кликабельные кнопки конечно тоже важны :)Имхо стандартные слишком убогие. Но не влияют на результаты торговли.
  • Paulmarko
    25 июля 2023, 16:23
    Еще часто бывает на серверах начального уровня сетевые карты. Нормальная карта будет стоить 30к и выше. Если брать intel или что-то из похожего, то задержки могут уйти. Не один раз с таким сталкивался

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

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