Блог им. algofintrader
Приветствую!
Большинство знает про арбитраж, где нужна скорость, но я расскажу вам про другую область, где в основном соревнуются не такие профессионалы, но скорость также нужна.
Что такое Pump — это когда «крипто школьники» собираются и решают вместе в один момент купить какую-то монету. Монета сильно подскакивает, а потом нужно резко выйти с огромной прибылью.
Монета, как правило, выбирается с низкой ликвидностью. И поначалу в эти игры и вправду играли только школьники.
Большинство «пампов» выкладываются в телеграм и дискорд группы.
По началу все и было так мило, пока не начали появляться боты и игра начала переходить на совсем другой уровень.
Боты читают сигналы сразу из группы и покупают быстрее всех.
А что означает покупать быстрее всех?
1. Использовать «низкоуровневые» языки, которые крайне быстро обрабатывают данные в большом количестве. Нам нужно быстро «разпарсить сообщение», найти инструмент в списках, отправить ордер и т.д.
2. Минимальный пинг для биржи (аренда сервера в токио максимально близко к бирже)
3. Максимально быстро считывать сообщения из групп (телеграм и дискорд АПИ нюансы)
Что такое быстрый язык программирования?
Чем более низкоуровневые языки, тем быстрее скорость. Если прям совсем проще, то чем не удобнее программировать, тем быстрее :)
Тут надо также понимать, что тесты могут быть абсолютно разные с разными настройками, но в финтехе все равно выделяется несколько фаворитов по скорости.
Вот моя оценка скорости:
1. C++, RUST (примерно на одном месте)
2. C#
3. Python.
Я написал тут самые популярные именно финтех языки (java к примеру здесь нет и чистого С). Я сам разработчик C#, но также модерирую другую разработку на других языках. Питон очень популярен для крипто ботов, С++ для финтеха, RUST — молодое современное.
Кстати на RUST работает ядро биржи Kraken. blog.kraken.com/post/7964/oxidizing-kraken-improving-kraken-infrastructure-using-rust/
В этом проекте исключения не было и поскольку нам нужна была самая быстрая скорость, сначала мы написали под каждый язык самый простой тестер. Тест заключался в следующем — выставить заявку и замерить сколько времени уходит на ее выставление. А конкретно на получение ID с биржи.
Тест был не совсем корректный, но даже в нем была видна разница по скорости. Потому что даже в сетевом плане все работает по-разному и можно все настроить по-разному.
Далее мы добавили в тесты примерные алгоритмы, которые работают с данными. А именно «распарсить сообщение из телеграм», найти в нем инструмент. Ну и куча сопутствующих еще данных, которые проверялись для принятия решения.
Rust оказался одним из самых быстрых.Вот пример сравнения C++ (c библиотекой QT) и python в один момент. К сожалению не осталось другого скриншота. C C++ и QT были проблемы, слетало подключение и периодически отправлял заявки, сначала подключаясь, а потом снова отправляя заявки.
Мы выбрали RUST — это классный, современный низкоуровневый язык. Собственно говоря, чем более низкоуровневым является язык тем более быстрым соответственно. Но проблема RUST заключалась в том, что параллельно нам надо было писать еще Frontend. Компетентных разработчиков со знанием в трейдинге на RUST на тот момент практически не было. Нам приходилось буквально обучать на лету RUST разработчика всем нюансам финтеха. Поэтому в процессе этой работы мы отказались от этого варианта. Разработка шла слишком медленно. Также RUST разработчики крайне дорогие, потому что они также выполняют блокчейн проекты.
Пример простого проекта на RUST до которого мы дошли и в итоге отказались, поскольку разработка была не выгодна.
Внутренние логи RUSTС С++ мы столкнулись с той же проблемой. У С++ есть удобная штука, называется QT. С++ c использованием QT показывал плохие результаты.
Коннект слетал и приходилось при каждом N отправке ордера снова подключаться и отправлять ордер. В общем это означало снова писать на чистом С++ делать апи и отдельно писать фронтенд.
В итоге остановились на решении использовать C# + логические ухищрения по скорости, которые мы обнаружили позже. На C# можно было сразу писать полноценно проект, можно сразу писать и фронт и бекенд. На C# — получали незначительные проблемы по скорости + хорошая скорость внесение правок на этом языке, большое количество разработчиков — решили двигаться на этом языке.
Также далее в процессе работы мы нашли ухищрения, которые помогли ускорить C#. Если использовать опять же их в расте, то конечно можно добиться больших скоростей, но пока все еще есть куда расти по C# с логической точки зрения.
Кстати под Python можно использовать ухищрения в виде PYPY, который ускорит Python до уровня C (не путать с C++). Такое мы тоже не стали тестировать, напишите в комментариях, может кто-то работал с этим. Мне показалось, что в будущем для разработки и масштабирования это можно создать проблемы.
Чистый python, который настолько любят в финтехе для работы с данными просто невероятно медленный :)
Но опять же, как правило, все укладывается в то, чтобы проект был эффективен с экономической целесообразности, возможности поддерживать проект, обновлять его и т.д.
Выбор Биржи и Алгоритмы
Само API кукоина очень интересное и предоставляет необычные форматы получения данных, которые способствуют тому, чтобы работать на этой бирже.
Во-первых, низкая волатильность, во вторых особенные методы API. Дело в том, что когда «пампы» стали развиваться, пришлось дорабатывать алгоритмы и писать различные алгоритмы проверки фейковых пампов, где возникло много различных нюансов. А именно, когда сами создатели могут прям перед пампом закупаться в больших объёмах и такие моменты мы тоже стали отлавливать.
У самого Кукоина есть информация MatchData в которой можно собрать по кусочкам большой ордер, который прошел перед пампом и собрать его. И купить его также быстро и в момент самого пампа уже и продать.
Было написано большое количество различных обработчиков фейковых пампов, которые анализируют объем перед самими пампами.
Также, если кто не в курсе, то памп заранее объявляют к какому-то времени, соответственно, мы покупали заранее все монеты, которые оказывали хоть какое-то серьезное движение вверх прям перед пампов, а потом просто продавали их, когда приходил настоящий сигнал. И на удивление C# нас вполне устроил.
Борьба за скорость.
Я работал над большим количеством ботов под HFT. Везде действует принцип парето. То есть вы можете приложить 20% усилий и получить 80% результата и то же самое наоборот.
К вот этому варианту, где вы грузите 80% усилий надо стремиться, когда уже все варианты ускорить бота под 20% будут пройдены, но их оказывается так много и в них можно утопать просто до бесконечности. Поэтому к сожалению раст разработка в нашем случае провалилась, как раз таки по экономической нецелесообразности.
Очевидные вещи, которые правятся в любом HFT проекте. В идеале конечно не использовать готовые библиотеки, а писать полностью все с нуля. Но опять же, мы идем по пути экономически целесообразных решений.
Мы использовали библиотеку JKORF и как в любом готовом коннекторе там идет куча говна, которое может замедлять создание ордера. Поэтому приходиться раскрывать и ковыряться там, удаляя аккуратненько все лишнее. После таких ковыряний коннектор заточен конечно же только под ваш проект.
Переписывать всякие поиски по List (перебор циклов, который отнимает куча времени) на тот же Dictionary или ConCurrentDictionary. Убираем различные Lock, которые конечно же используются, чтобы обезопасить коннектор. В общем аккуратно заходим туда и если бы пример был с автомобилем — снимаем запаску, снимаем кресла, снимаем все лишнее и сидим на металле, чтобы получить больше скорости.
Нетривиальные способы решения скорости
По понятным здесь причинам я не могу описывать всю интеллектуальную собственность, но лишь хочу обозначить, что во время бесконечного количества тестов были замечены нетривиальные способы решения вопросов со скоростью, которые не лежат на поверхности. Но они показали оптимизацию в разы лучше, чем просто смена языка.
Получилось добиться ускорения на 5 — 6 мс по сравнению с обычными тестами. Так что можно соревноваться даже на таком полу любительском уровне и получать свои кусочки пирогов.
Наша скорость на C# (простые тесты)
Всем удачи, спасибо за чтение.
P.S. К моменту написания статьи просматривал API kuCoin и узнал, что они специально выпустили HFT API :) Бирже выгодно, чтобы участники играли в пампы и даже АПИ специально выпустили :)
какой же бред.
(скажем привинтили свой личный кеширующий dns сервер, который мгновенно отдает результаты итд итп)
И скорее всего для вас это бесполезный ноу-хау, т.к. у вас все другое будет.
В целом нет причин полагать, что на с# можно будет быстрее чем на С сделать, скорее всего медленнее...
Вообще с# немножко странный выбор, ониж не под виндой все это запускают, а всякие моно итп те ещё костыли.
Вероятно наиболее быстрым был бы некий «патч» прям в ядро какого-то рантайм линукса… Почти наверняка время тратиться в основном на сетевые взаимодействия, а не собственно на «работу кода»...
В принципе, это все — это довольно прикольная соревновательная задача. Тут много что учесть и наворотить надо. И то время, за которое ты выставляешь заявки — это явно не самое важное время…
Питон сильно распиаренная вещь, которая, как считается а) простая и удобная, б) быстрая.
При ближайшем рассмотрении оказывается, что
а) всё что просто, написано [кем-то] в виде библиотек и этим питон ничем не отличается от других языков
б) всё что быстро, написано на C в виде либо ядра питона либо подключаемых внешних библиотек
Например, ядро нумпи — чистый C
https://github.com/numpy/numpy/tree/main/numpy/core/src
Или сам Питон
https://github.com/python/cpython/tree/main/Python
Питон, конечно, имеет право на существование, просто а) слухи о его «могучести» слегка преувеличены б) если вам потребуется что-то новое и реально быстрое, вам скорее всего придётся самим написать либу на C.
Ну «такое себе».
Соревноваться в скорости можно только с лохами, если ставка на это, можно стать лучшим среди лохов. А любые серьезные «ребята» скорее всего вдвое-втрое быстрее вас все сделают, потому как будут выбирать не подходящий на 80% путь, а подходящий на 100… Т.е. это все чистое соревнование бюджетов на разработку в общем-то…
Впрочем: каждый тратит деньги как считает нужным…
Нет никакого смысла улучшать заранее проигрышную систему построенную не исходя из технических требований, а исходя из того «кого удалось нанять подешевле».