Привет, Хабр! С вами Роман Потапов и Сергей Попков, ведущие специалисты по тестированию РСХБ‑Интех. В сегодняшнем материале поговорим про эмулятор отечественного биржевого терминала QUIK — посредника между системой брокера и биржами. Программный комплекс QUIK получает информацию из бирж и передает ее в систему брокера, в другом случае сам брокер идет в QUIK и получает биржевую информацию от него. Поскольку тестирование с полноценным QUIK проводить невозможно, мы сделали собственный эмулятор.

Интерфейс исходного QUIK для ПК. Источник
Интерфейс исходного QUIK для ПК. Источник

Зачем нам эмулятор

Почему нужен именно эмулятор? QUIK — это полностью коробочная система. То есть ее можно купить и сразу внедрить, и это полностью завершенная разработка вендорной компании. Был вариант подключиться через тестовый стенд, но тестовый QUIK — это просто система, по большей части для функциональных проверок, не позволяющая проводить нужные виды нагрузочного тестирования. Кроме того, QUIK подключен к тестовым системам Московской и Питерской биржи, которые поддерживают обмен биржевой информации. Но такое решение нам не подходило по трем причинам.

Первая — поток информации, поступающий от бирж, фиксированный и не подлежит регуляции, то есть мы не можем увеличить его или уменьшить, тем самым нагрузив тестируемую систему «Брокер» так, как нам необходимо. Вторая — тестовая биржа не рассчитана на серьезные нагрузки. Она нужна исключительно для того, чтобы проверить какие‑то функциональные решения. Условно, могла бы сложиться ситуация, что мы ее загрузили запросами, биржа легла и всем стало очень грустно, поскольку ею пользуются не только РСХБ, но и другие брокеры, которые есть на рынке. Третья — каждая сделка, проходящая даже через тестовую биржу, стоит денег.

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

И вот поступила задача проверить производительность нашего Брокера. Для тестирования целевой системы нам был необходим эмулятор QUIK, с помощью которого мы могли бы регулировать нагрузку со стороны бирж. Нагрузку на нашу систему создают не только клиенты, использующие приложение Брокера, но и биржи. Нагрузка на них напрямую зависит от активности клиентов остальных брокеров на рынке. Таких образом, эмулятор должен поддерживать функциональную работоспособность и нашего Брокера, и бирж.

Разработанный эмулятор позволяет нам воспроизводить различные ситуации на рынках. Например, наступил упадок экономики, и все побежали продавать свои акции. В свою очередь, агрессивные инвесторы стали откупать такую распродажу☺, на рынках творится хаос и суматоха. Соответственно, в промышленной среде возникает огромный поток сделок и разной биржевой информации, которая обрабатывается нашим Брокером. И мы такие сценарии теперь с помощью этого эмулятора можем воспроизводить.

Работа над эмулятором

За основу нашего эмулятора QUIK был взят FIX‑движок, который обеспечивает связь со сторонними системами по FIX‑протоколу. FIX‑движок отвечает за все процедуры создания сессии и обеспечения ее работы: проверки контрольных сумм, валидности, определения последовательности сообщений, восстановление сессии после потери связи с повторной передачей пропущенных сообщений и прочее.

Началось все с того, что нам нужно было понять, какие компоненты Брокера взаимодействуют с QUIK и произойдет ли коннект этих компонентов к движку. После того, как нам удалось подключить наши компоненты к движку, нам необходимо было более детально понять, как взаимодействуют эти компоненты с QUIK, то есть: какие сообщения отправляют компоненты Брокера в QUIK, какие ответы приходят от QUIK в Брокер и т. д. Для это мы собрали все логи взаимодействия наших компонентов с QUIK.

Сам FIX‑движок написан на java, соответственно, дорабатывали этот движок под наши нужды также на java. У Брокера есть 3 точки взаимодействия с QUIK по FIX‑протоколу:

  • Первый — FixLoader.Moex — получает биржевую информацию с QUIK по Московской бирже для формирования биржевых стаканов.

  • Второй — FixLoader.Spb — получает биржевую информацию с QUIK с Московской биржи для формирования биржевых стаканов.

  • Третий — EFTR.OMS — сервис учета биржевой информации, заведения биржевых заявок.

Помимо этого, Брокер взаимодействует с еще двумя компонентами QUIK:

  • Первый — QuikExport — отвечает за выгрузку данных по клиентским портфелям, котировкам, сделкам и т. д. Взаимодействие заключается в вызове хранимых процедур на стороне БД Брокера.

  • Второй — QuikExportDH — отвечает за экспорт данных по биржевым событиям, то есть отправляет сделки, с помощью которых компонент Брокера производит расчет биржевых свечей. Экспорт производится путем загрузки данных в ODBC‑источник, которым является компонент Брокера.

Первая проблема во всем этом — разобраться с FIX‑протоколом. Там мы не встречаемся с типичными сообщениями, к которым мы привыкли, такими как XML или Json. FIX‑сообщения выглядят совсем по‑другому, в них используется формат Tag=Value, где Tag — обозначает поля (версия Fix‑протокола, тип сообщения, отправитель, получатель и т. д.) и Value — значения этих полей. Во всем этом нам удалось успешно разобраться, с помощью статей на Хабре (спасибо авторам за их работу ☺), а также справочнику по Fix‑протоколу и онлайн‑парсерам.

Но самая главная проблема при разработке эмулятора — это сбор информации, которую мы могли бы использовать, поскольку QUIK это не наша разработка, и вся экспертиза находится у вендора. Собрать статистику по работе, какие данные перекидываются — это большая аналитическая работа, и она была проделана, все данные собраны и структурированы.

Найдя все точки взаимодействия Брокера с QUIK, мы приступили к доработке Fix‑движка. На основе собранной информации с логов, мы стали добавлять в наш эмулятор свои методы обработки запросов от Брокера. Работает это следующим образом:

  • приходит запрос от Брокера;

  • в зависимости от типа сообщения, запрос попадает в определенный метод на стороне эмулятора;

  • в этом методе мы парсим запрос;

  • вычленяем всю необходимую нам информацию для формирования ответа (имя отправителя, получателя, название финансового инструмента и т. д.);

  • по заранее заготовленному пулу данных, добавляем необходимую информацию по финансовому инструменту для формирования ответа;

  • подготовленные ответ отдаем Брокеру.

Существует такой тип взаимодействия между Брокером и QUIK: последний постоянно пушит Брокер сообщениями с биржевой информацией, которую сам Брокер впоследствии использует для формирования биржевых стаканов.

Вторым этапом стал сбор статистики с промышленной среды Брокера по интенсивности получения таких сообщений: сколько сообщений приходит в час/минуту от QUIK в Брокер. Также собрали пул данных по финансовым инструментам, которые используются в таких сообщениях: цена инструмента, биржа, валюта и так далее. Данную информацию удалось получить с логов двух компонентов: FixLoader.MOEX, принимающий сообщения по московской бирже, и FixLoader.SPB, принимающий сообщения по питерской бирже.

После этого в наш эмулятор был добавлен еще один метод, в котором реализовали распознавание подключаемой к эмулятору сессии (Moex или Spb). Сделано это для того, чтобы все финансовые инструменты, используемые в сообщениях, соотносились с биржей, на которой торгуются. Далее, после того как две сессии успешно подключились к эмулятору, стартует механизм отправки сообщений типа MarketData. Интенсивность отправки сообщений была настроена с помощью Sheduler. Также был создан отдельный конфигурационный файл, в котором по‑быстрому можно настроить необходимую нам интенсивность. В нем достаточно задать количество потоков и период, с которыми будет вызываться метод отправки сообщений MarketData в Брокер.

На последнем этапе по разработке полноценного эмулятора QUIK оставалось научиться эмулировать работу его компонентов — QuikExport и QuikExportDH. Здесь уже было намного проще, поскольку для эмуляции этих компонентов достаточно было разработать скрипты в Jmeter с вызовами хранимых процедур на БД.

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

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

Когда мы брались за эту задачу у всех было какое‑то скептическое настроение, что мы эмулятор не сделаем, что там слишком много шлюзов, которые надо подключать. Но в итоге все получилось. Также мы размышляли про эмуляцию биржи, но это совершенно другая задача, другие методы, архитектура. На тот момент задача казалась слишком сложной, но, как показала практика, эмулятора QUIK оказалось достаточно, и что‑то большее на текущий момент делать нет необходимости.

Комментарии (6)


  1. atd
    30.11.2023 12:35

    Не очень понятно, что в итоге вы пробенчмаркали, свой бэкофис, или сервер квика?


    1. PopkovSergey Автор
      30.11.2023 12:35

      Задача состояла в оценке производительности своего приложения, сервер квика мы просто эмулировали


      1. PopkovSergey Автор
        30.11.2023 12:35

        UPD:

        Задача состояла в оценке производительности приложения «Брокер» (сама разработка данного приложения была на стороне вендора).

        Прошу прощения, возможно кого-то ввел в заблуждение первым комментарием.


  1. uuger
    30.11.2023 12:35
    -1

    Автор эмулятора очень любит

    экшн камеры?


  1. kmatveev
    30.11.2023 12:35

    Не совсем понял

    Началось все с того, что нам нужно было понять, какие компоненты Брокера взаимодействуют с QUIK и произойдет ли коннект этих компонентов к движку. После того, как нам удалось подключить наши компоненты к движку, нам необходимо было более детально понять, как взаимодействуют эти компоненты с QUIK, то есть: какие сообщения отправляют компоненты Брокера в QUIK, какие ответы приходят от QUIK в Брокер и т. д. Для это мы собрали все логи взаимодействия наших компонентов с QUIK.

    Если "Брокер" - это ваша разработка, то не проще и правильнее было бы спросить у разработчиков (или посмотреть в документации), чем искать в логах?

    Первая проблема во всем этом — разобраться с FIX‑протоколом. Во всем этом нам удалось успешно разобраться, с помощью статей на Хабре

    Опять же, если ваш брокер интегрируется с QUIK по FIX-у, то почему бы не спросить разработчиков, что такое FIX, и какие именно поля в нём использует непосредственно ваше приложение?

    Но самая главная проблема при разработке эмулятора — это сбор информации, которую мы могли бы использовать, поскольку QUIK это не наша разработка, и вся экспертиза находится у вендора. 

    Но "Брокер" - вроде же ваша?

    За основу нашего эмулятора QUIK был взят FIX‑движок, который обеспечивает связь со сторонними системами по FIX‑протоколу

    Занятно, что сам движок вы по имени нигде не называете, кроме как в тегах статьи.


    1. PopkovSergey Автор
      30.11.2023 12:35

      Если "Брокер" - это ваша разработка, то не проще и правильнее было бы спросить у разработчиков (или посмотреть в документации), чем искать в логах?

      «Брокер», как и Quik, разработка вендора. В данной статье под словами «наши компоненты» и т.д. следует понимать, что это целевая система, которую нам нужно было протестировать.

      Что касается документации, то в ней необходимой для нас информации не было.

      Опять же, если ваш брокер интегрируется с QUIK по FIX-у, то почему бы не спросить разработчиков, что такое FIX, и какие именно поля в нём использует непосредственно ваше приложение?

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