Huobi Global - это сингапурская криптовалютная биржа, основанная в 2013 году. С ежедневными объемами около 2 миллиардов долларов в день Huobi Global является чрезвычайно ликвидной биржей для нескольких криптовалютных торговых пар, включая BTC, ETH, LTC, XRP и другие. По состоянию на январь 2020 года у него около 400 проверенных рынков и около 25 непроверенных рынков. Стоит отметить, что Huobi Global, в отличие от многих других бирж, никогда не подвергалась взлому и у нее миллионы клиентов по всему миру.

В этой статье мы хотели бы продемонстрировать, как создать относительно простое, но полностью функциональное торговое приложение на основе XTRD FIX API, которое будет подключаться к Huobi. Вы можете свободно использовать его как исходный код в своих проектах.

Приложение покажет, как установить два исходящих FIX-соединения со шлюзом XTRD FIX. Один из сеансов будет использоваться для получения в реальном времени нормализованных рыночных данных для одной пары - ETH / USDT. Вторая сессия предоставит доступ к торговым возможностям наряду с определенной финансовой информацией о счете, такой как открытые ордера и позиции.

Итак, в качестве первого шага мы подключимся к сеансу рыночных данных и подпишемся на обновления ETH / USDT.

Одновременно приложение установит соединение с торговой сессией и выполнит полный цикл операций восстановления - получит список открытых ордеров и доступные остатки.

После того, как мы завершим этап установления связи, приложение начнет отправлять лимитные ордера на покупку ETH. Цена ордера всегда будет на 20% вне рынка, чтобы гарантировать, что ордер останется в книге и не будет исполнен. Мы оставим заказ на книге в течение нескольких секунд, а затем отменим его. Затем цикл начнется заново. Есть. Спать. Повторить.

Huobi имеет продвинутый и богатый API. Но, как и любая большая и сложная вещь, у нее есть свои недостатки. Например, вы не можете отправлять заказы с помощью WebSocket и должны использовать REST API. Так в чем проблема? Многие биржи цифровых активов делают то же самое.

Проблема в том, что подтверждение, которое приходит через WebSocket, не содержит присвоенного клиенту идентификатора, а содержит только идентификатор заказа, созданный Huobi. Однако вы сможете узнать этот внешний идентификатор заказа только после того, как получите и проанализируете ответ на свой запрос REST API. Иногда сообщение WebSocket доставляется быстрее, чем вы получаете свой идентификатор заказа, что заставляет вас догадываться, о чем этот отчет.

Маршрутизатор заказов XTRD успешно решает эту проблему, поэтому наши клиенты могут надлежащим образом получать оптимизированные заказы ExecutionReport.

Учитывая, что это приложение не будет таким простым, мы будем использовать несколько вспомогательных классов, разработанных нашей командой. Мы не рекомендуем использовать эти классы в высоконагруженных приложениях из-за отсутствия оптимизации, но этого достаточно для целей этого курса.

Для создания простого торгового приложения мы будем использовать Java и OnixS FIX Engine. Конечно, вы всегда можете заменить Java на C ++, Python или JavaScript и OnixS на QuickFIX или Fix8, в этом вся прелесть FIX API - он полностью независим от языка и движка. Да, мы предпочитаем использовать библиотеки OnixS из-за их преимуществ, но это только внутреннее решение команды.

Не стесняйтесь обращаться к нам, если вам нужна помощь в переносе на другой язык / библиотеку FIX, мы будем рады помочь!

Приложение, которое мы создадим, представляет собой конечный автомат, который переходит от одного этапа к другому в зависимости от предыдущих условий. Вот диаграмма с возможными (упрощенными для удобства чтения) состояниями:

Как видите, приложение начнет отправлять заказы, только если оно находится на этапе APP_ENTER_MARKET, который представляет собой комбинацию MD_READY и ORD_READY. Если случилось что-то неожиданное, например в одной из сессий потеряна связь, вся торговая деятельность будет остановлена.

Давайте начнем с самого простого - установления соединения с сеансом рыночных данных и подписки на обновления ETH / USDT.

Устройство подачи XTRD MD ожидает, что вы начнете свое рукопожатие, отправив специальное сообщение под названием «Вход в систему», которое содержит поля «Имя пользователя» и «Пароль».

Вы можете задать резонный вопрос - безопасно ли отправлять незашифрованные учетные данные? Итак, клиенты XTRD подключаются к нашему серверу одним из следующих способов:

  • Канал IPSec VPN
  • Перекрестное соединение
  • Совместное размещение в дата-центре Equinix NY4

Таким образом, весь трафик между вами и нами полностью изолирован от других людей. И, поскольку ваш пароль мы уже знаем, нет смысла его скрывать от нас :)

В случае успешной авторизации наш сервер ответит сообщением Logon, которое переводит нас на этап отправки сообщения для подписки на поток рыночных данных.

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

Чтобы действовать как настоящий слой нормализации, мы решили сохранить наши собственные символы. Таким образом, вместо того, чтобы торговать ethusdt (на Huobi), usdteth (на Bittrex) или 4 (на BlockTrade), вы можете использовать только одно имя для использования - ETH / USDT.

Вот образец структуры MarketDataRequest и часть кода Java для создания соответствующего сообщения:

После получения сервером сообщение MarketDataRequest вызовет цепочку событий:

  • Полный снимок книги будет возвращен в виде сообщения MarketDataSnapshotFullRefresh.
  • Сервер будет отправлять инкрементальные обновления в реальном времени для необходимого инструмента, когда соответствующий символ будет изменен на стороне Huobi. Вместо отправки полной книги (которая иногда может быть очень большой) XTRD использует подход к оптимизации потока данных, отправляя только те части, которые действительно были изменены - например, сделок, добавлены или удалены новые уровни цен, обновлены размеры.

Наши правила управления книгами основаны на широко используемых принципах традиционных финансов - комбинации событий NEW (0), UPDATE (1) и DELETE (2). Это очень простой подход, который помогает легко создавать надежное и предсказуемое программное обеспечение.

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

Так что мы будем «кормить» все события рыночных данных в нашу простую книгу. Таким образом, мы можем быть уверены, что имеем точную картину того, что происходит на рынке (с одним конкретным инструментом).

Отлично, у нас есть данные! Но что мы будем с этим делать? Давайте погрузимся в создание торгового коннектора!

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

Первый шаг полностью совпадает с сеансом рыночных данных - Вход. После прохождения авторизации пора запросить список наших активов под управлением. У FIX есть специальное сообщение для этого - RequestForPositions. В зависимости от контекста использования сервер вернет снимок текущей позиции и / или продолжит уведомлять вас в режиме реального времени, если размер позиции изменится в случае торговли, вывода или депозита.

Рабочий процесс следующий: вы отправили сообщение RequestForPositions, и сервер ответит вам одним сообщением RequestForPositionAck, которое указывает, чего ожидать дальше. Если у вас есть позиции, информация будет поступать в виде сообщений PositionReport.

В самом последнем сообщении PositionReport будет специальный маркер, который мы будем использовать для перехода к другому этапу - синхронизации заказов.

Иногда в вашей торговой сессии могут быть живые рабочие ордера, лежащие где-то в книгах. В XTRD FIX API есть специальное сообщение для вызова этих рабочих лошадок - OrderMassStatusRequest. В мире FIX большая часть информации об ордерах передается с помощью сообщения ExecutionReport. Это сообщение содержит наибольшее количество полей по сравнению с другими сообщениями на языке FIX. Но это помогает точно идентифицировать заказы и их соответствующие статусы.

Пока XTRD действует как поставщик DMA, мы хотим убедиться, что все наши операции прозрачны на 100%. Таким образом, рядом с идентификатором, назначенным клиенту (передается в поле ClOrdID (тег 11)) и идентификатором, назначенным XTRD (идентификатор заказа (тег 37), всегда целое число), вы увидите идентификатор, назначенный обменом (в поле SecondaryOrderID (тег 198)).

Наша стратегия синхронизации заказов работает следующим образом - отправьте OderMassStatusRequest и дождитесь ответа сервера. Возможны два сценария (в случае правильного исходного сообщения):

  • Сервер ответит списком ExecutionReports, который можно отфильтровать по MdReqId (идентификатор запроса, назначенный клиентом) и ExecType = STATUS (I)
  • В случае, если у вас нет открытых ордеров, сервер ответит специально отформатированным ExecutionReport. Мы сделали это таким образом, потому что, в отличие от контрагента по запросу о позициях - RequestForPositionsAck, FIX не имеет сообщения с подтверждением по умолчанию для статуса заказа, что может означать, что вы будете ждать своих отчетов вечно.

На данный момент наши позиции и приказы синхронизированы, так что давайте повеселимся на стрельбу!

Наше приложение возьмет верхнюю часть балансовой цены, а затем отправит лимитный ордер с ценой на X пунктов в сторону от лучшего предложения или предложения (в зависимости от того, какую сторону мы выберем). Наша цель - создать заказ, который будет оставаться в книге в течение определенного времени, прежде чем алгоритм отменит его.

Чтобы разместить заказ, мы будем использовать сообщение под названием NewOrderSingle. Его поля довольно просты и не требуют пояснений - вам нужно указать Сторона (Тег 54) (покупка или продажа), Тип (Тег 40) (Лимит в нашем случае), указать лимитную цену и размер ордера, установить Символ (Тег 55) и пункт назначения маршрутизации (Тег 11) (в данном случае HUOBI). Полное описание полей для сообщения NewOrderSingle можно найти здесь.

После отправки заказа сервер ответит определенным количеством ExecutionReports, указывающим на изменения жизненного цикла. Платформа XTRD использует следующие статусы, чтобы указать, что происходит с вашим заказом:

  • PENDING_NEW: заказ прошел первоначальную проверку и принят нашей платформой для дальнейшего исполнения.
  • НОВИНКА (0): ордер доставлен на целевую биржу и принят к исполнению
  • ЧАСТИЧНО ВЫПОЛНЕНО (1) / ВЫПОЛНЕНО (2): часть размера ордера или весь ордер согласован с контрагентом и исполнен
  • ОТМЕНЕН (4): заказ был отменен вручную или через запрос API
  • ОТКЛОНЕН (8): заказ был отклонен из-за внутренней ошибки или неверных параметров

Конечно, все мы хотим видеть идеальный цикл PENDING_NEW / NEW - ›FILLED, и наши инженеры делают все возможное, чтобы предоставить самые быстрые технологии. Мы также полагаемся на наших партнеров-LP, таких как Huobi Global.

Отлично, ваш заказ находится в книге, поэтому давайте поспешим отменить его, прежде чем он будет выполнен!

Чтобы отменить заказ, вам необходимо отправить сообщение OrderCancelRequest. Вот сложная часть - вам нужно предоставить 3 идентификатора:

  • ClOrdID: идентификатор вашего запроса на отмену
  • OrigClOrdID: это внутренний идентификатор вашего торгового приказа, отправленного на предыдущем шаге.
  • OrderID: ID на стороне XTRD

В переводе на человеческий язык эту запись следует читать следующим образом: «используйте Order ClOrdID, чтобы отменить мой ранее размещенный заказ OrigClOrdID / OrderID».

Как только мы отменим ваш ордер, сервер уведомит вас соответствующим ExecutionReport, подтверждающим, что торговый / рабочий ордер был отменен.

В соответствии с рабочим процессом демонстрационного приложения, алгоритм перейдет в спящий режим на 2 секунды, а затем отправит еще один лимитный ордер. Опять таки. И снова.

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

Независимо от того, что вы будете использовать в качестве мозга для своего реального приложения, будьте уверены, что XTRD FIX API для торговли на криптовалютных биржах, таких как Huobi, останется надежным и надежным партнером!