Я использовал язык программирования D для реализации платформы высокочастотного трейдинга (HFT). Я был вполне удовлетворен полученным опытом и решил поделиться тем, как я пришел к этому. Этот путь был тернист.
В 2008 году на Amazon я наткнулся на книгу под названием "Learn to Tango with D". Это вызвало у меня любопытство, и я решил изучить D подробнее. Это привело меня к Digital Mars и Уолтеру Брайту. Впервые я услышал об Уолтере, когда узнал о Zortech C++, первом нативном компиляторе C++. Его работа оказала огромное влияние на мой путь изучения C++. Поэтому я сразу же заинтересовался языком только потому, что он его автор, и был рад узнать, что он вместе с Андреем Александреску работает над второй версией. Тем не менее, я решил подождать, пока они продвинутся дальше в работе над новой версией, прежде чем окунуться в проект.
В 2010 году я купил книгу Андрея "The D Programming Language", как только она была опубликована, и начал читать. В то время я работал в BNP Paribas, используя C++ для оптимизации своей HFT-платформы, поэтому высокая производительность доминировала в моих мыслях. Когда я увидел, что классы в D являются ссылочными типами, а их функции по умолчанию виртуальные, я был разочарован. Я не понимал, как это может быть полезно для программирования с низкими задержками (латентностью). В то время я был слишком занят работой, чтобы углубляться в изучение, поэтому я отложил книгу и язык в сторону.
В 2014 году я начал готовиться к новому начинанию. В рамках этого я начал работать над новым фреймворком обработчика входных данных (Feed-Handler) на C++, используя свою собственную давно поддерживаемую библиотеку C++ низкоуровневых компонентов, полезных в высокопроизводительных приложениях с низкими задержками. Книга Андрея снова попалась мне на глаза, и я решил взглянуть на нее еще раз.
На этот раз я дочитал книгу до конца и понял, что мое первоначальное впечатление было ошибочным. Я обнаружил, что мне нравятся возможности метапрограммирования в D и его поддержка программирования в функциональном стиле. К концу книги я был готов дать шанс D.
Я начал с переноса своей библиотеки C++ и обработчика входных данных на D. Это было несложно. В своем коде на C++ я использую очень мало наследования, предпочитая композицию и конкретные классы (Concrete class). Я обнаружил, что довольно продуктивно работаю со структурами, шаблонами и миксинами (mixin) D. При этом я внимательно следил за показателями производительности. Когда оказалось, что D дает такую же производительность, как и мой код на C++, я был куплен с потрохами. Я обнаружил, что D намного элегантнее, чище, читабельнее и проще в поддержке. Я перешел на D и больше не оглядывался назад.
Моей целью было разработать законченную систему HFT с использованием D. Система должна была состоять из различных подсистем:
Позже мне понадобилось работать с конфигурационными файлами. Я предпочитаю писать свои файлы конфигурации на Lua, легковесном скриптовом языке, который легко интегрировать в программу в качестве расширения через его C API. Для этого я нашел привязку D Lua под названием DerelictLua. Используя, опять же, средства метапрограммирования D, я разработал очень простой и практичный способ взаимодействия с Lua через DerelictLua. Примечание редактора: с тех пор DerelictLua устарел; новые проекты должны использовать его преемника, bindbc-lua.
Обработчик входных данных на бирже Bats работает с 31 параллельным каналом, поэтому эффективнее использовать многопоточность. Для этого я решил не использовать средства многопоточности, предоставляемые Phobos. Я чувствовал, что мне нужно больше контроля в такой среде с низкой задержкой, особенно возможность привязать каждый поток к определенному ядру. Я предпочел использовать библиотеку pthreads и ее работу с affinity. Благодаря совместимости с C ABI в D это было очень прямолинейно.
Я работаю в FreeBSD. Для своих коммуникационных потребностей я использую функции ядра для очередей и сокетов. Та же функциональность доступна на macOS, моей предпочтительной платформе для разработки. D не помешал мне использовать эти API ни на macOS, ни на FreeBSD. Это было так же просто, как использование функций ядра для очередей из C.
Несколько замечаний о проблемах и ограничениях:
Немного пояснений автора из комментариев (прим.ред):
Не использовались ни IDE, ни отладчик.
Я использовал Sublime Text, который имел плагин для D для отступов и подсветки синтаксиса.
Использовал терминал и систему сборки DUB и dmd и ldc2 в качестве компиляторов.
Для такого рода приложений с огромным количеством данных и многопоточностью отладчик может быть полезен, но чаще всего проблемы удается найти с помощью логов.
В D генерировать логи очень просто, достаточно использовать writeln и структуру, и все работает. В C++ вам нужно написать функцию типа dump() вручную.
Время от времени я пробовал использовать lldb в качестве отладчика, но использовал его нечасто, лишь изредка.
Никакой базы данных, так как никакие базы данных не подходят для такого типа приложений с низкой задержкой.
Все необходимые базы данных создаются на месте и находятся в памяти, в основном это хэш-таблицы.
Имеется только асинхронное архивирование сообщений между OMS и биржей, просто на случай, если что-то пойдет не так, мы можем создать требуемое состояние системы и продолжить работу.
В 2008 году на Amazon я наткнулся на книгу под названием "Learn to Tango with D". Это вызвало у меня любопытство, и я решил изучить D подробнее. Это привело меня к Digital Mars и Уолтеру Брайту. Впервые я услышал об Уолтере, когда узнал о Zortech C++, первом нативном компиляторе C++. Его работа оказала огромное влияние на мой путь изучения C++. Поэтому я сразу же заинтересовался языком только потому, что он его автор, и был рад узнать, что он вместе с Андреем Александреску работает над второй версией. Тем не менее, я решил подождать, пока они продвинутся дальше в работе над новой версией, прежде чем окунуться в проект.
В 2010 году я купил книгу Андрея "The D Programming Language", как только она была опубликована, и начал читать. В то время я работал в BNP Paribas, используя C++ для оптимизации своей HFT-платформы, поэтому высокая производительность доминировала в моих мыслях. Когда я увидел, что классы в D являются ссылочными типами, а их функции по умолчанию виртуальные, я был разочарован. Я не понимал, как это может быть полезно для программирования с низкими задержками (латентностью). В то время я был слишком занят работой, чтобы углубляться в изучение, поэтому я отложил книгу и язык в сторону.
В 2014 году я начал готовиться к новому начинанию. В рамках этого я начал работать над новым фреймворком обработчика входных данных (Feed-Handler) на C++, используя свою собственную давно поддерживаемую библиотеку C++ низкоуровневых компонентов, полезных в высокопроизводительных приложениях с низкими задержками. Книга Андрея снова попалась мне на глаза, и я решил взглянуть на нее еще раз.
На этот раз я дочитал книгу до конца и понял, что мое первоначальное впечатление было ошибочным. Я обнаружил, что мне нравятся возможности метапрограммирования в D и его поддержка программирования в функциональном стиле. К концу книги я был готов дать шанс D.
Я начал с переноса своей библиотеки C++ и обработчика входных данных на D. Это было несложно. В своем коде на C++ я использую очень мало наследования, предпочитая композицию и конкретные классы (Concrete class). Я обнаружил, что довольно продуктивно работаю со структурами, шаблонами и миксинами (mixin) D. При этом я внимательно следил за показателями производительности. Когда оказалось, что D дает такую же производительность, как и мой код на C++, я был куплен с потрохами. Я обнаружил, что D намного элегантнее, чище, читабельнее и проще в поддержке. Я перешел на D и больше не оглядывался назад.
Моей целью было разработать законченную систему HFT с использованием D. Система должна была состоять из различных подсистем:
- Feed-Handler Framework: получает рыночные данные от бирж; создает журналы для всех ценных бумаг; публикует обновления для других подсистем.
- Strategies Framework: получает обновления рыночных данных от обработчика входных данных п.1; облегчает связь с системой управления заказами п.3; позволяет подключать к ней стратегии, принимающие решения о торговле акциями.
- Order Management System: взаимодействует с биржей и системой стратегий п.2; поддерживает базу данных ордеров.
- Signal Generator: получает обновления рыночных данных от от обработчиков входных данных п.1; генерирует различные сигналы в виде значений индикаторов, прогнозов цен на акции и т.д.; посылает различные сигналы стратегиям п.2.
Позже мне понадобилось работать с конфигурационными файлами. Я предпочитаю писать свои файлы конфигурации на Lua, легковесном скриптовом языке, который легко интегрировать в программу в качестве расширения через его C API. Для этого я нашел привязку D Lua под названием DerelictLua. Используя, опять же, средства метапрограммирования D, я разработал очень простой и практичный способ взаимодействия с Lua через DerelictLua. Примечание редактора: с тех пор DerelictLua устарел; новые проекты должны использовать его преемника, bindbc-lua.
Обработчик входных данных на бирже Bats работает с 31 параллельным каналом, поэтому эффективнее использовать многопоточность. Для этого я решил не использовать средства многопоточности, предоставляемые Phobos. Я чувствовал, что мне нужно больше контроля в такой среде с низкой задержкой, особенно возможность привязать каждый поток к определенному ядру. Я предпочел использовать библиотеку pthreads и ее работу с affinity. Благодаря совместимости с C ABI в D это было очень прямолинейно.
Я работаю в FreeBSD. Для своих коммуникационных потребностей я использую функции ядра для очередей и сокетов. Та же функциональность доступна на macOS, моей предпочтительной платформе для разработки. D не помешал мне использовать эти API ни на macOS, ни на FreeBSD. Это было так же просто, как использование функций ядра для очередей из C.
Несколько замечаний о проблемах и ограничениях:
- Я раз столкнулся с ошибкой компилятора. Я нашел обходной путь, так что это не стало блокирующим фактором. Я смог воспроизвести ее с помощью нескольких строк кода и связался с сообществом D. Они решили проблему и внесли исправление в более позднюю версию компилятора.
- Я не использовал сборщик мусора (GC) в D. Однако это не является выпадом против D или его GC. В такой системе с низкой задержкой, как эта, даже использование malloc и free может стать дорогостоящим, поэтому я не собираюсь рисковать использовать недетерминированную систему с непредсказуемой задержкой. Вместо этого я использовал свою библиотеку для обработки выделения/деаллокации памяти через списки свободных блоков, с предварительным выделением памяти. Как следствие, я также отказался от использования стандартной библиотеки D.
- Мне нужно было работать со строками ASCII фиксированного размера, которые не имеют NUL-терминатора, а вместо этого дополнены пробелами в конце. Без стандартной библиотеки мне было проще работать с ними в С-стиле с помощью указателей.
Немного пояснений автора из комментариев (прим.ред):
Не использовались ни IDE, ни отладчик.
Я использовал Sublime Text, который имел плагин для D для отступов и подсветки синтаксиса.
Использовал терминал и систему сборки DUB и dmd и ldc2 в качестве компиляторов.
Для такого рода приложений с огромным количеством данных и многопоточностью отладчик может быть полезен, но чаще всего проблемы удается найти с помощью логов.
В D генерировать логи очень просто, достаточно использовать writeln и структуру, и все работает. В C++ вам нужно написать функцию типа dump() вручную.
Время от времени я пробовал использовать lldb в качестве отладчика, но использовал его нечасто, лишь изредка.
Никакой базы данных, так как никакие базы данных не подходят для такого типа приложений с низкой задержкой.
Все необходимые базы данных создаются на месте и находятся в памяти, в основном это хэш-таблицы.
Имеется только асинхронное архивирование сообщений между OMS и биржей, просто на случай, если что-то пойдет не так, мы можем создать требуемое состояние системы и продолжить работу.
Как я написал платформу для высокочастотного трейдинга на D
Я использовал язык программирования D для реализации платформы высокочастотного трейдинга (HFT). Я был вполне удовлетворен полученным опытом и решил поделиться тем, как я пришел к этому. Этот путь был...
habr.com