Недавно OsEngine начал поддержку бинарного формата хранения и трансляции данных по стаканам. Это было нужно, чтобы:
1)Облегчить работу эмулятора биржи на уровне стаканов.Статья предназначена для программистов, знакомых с OsEngine, которым интересна внутренняя реализация функционала.
В этой статье посмотрим на загрузку стаканов в формате QSH и их тестирование через код OsEngine.
QSH — это специализированный бинарный формат, разработанный для эффективного хранения и воспроизведения исторических рыночных данных с высокой точностью и минимальными требованиями к дисковому пространству. Проще говоря, стаканы теперь занимают в сотни раз меньше места, чем раньше.
Вместо записи полных снимков состояния рынка через равные промежутки времени, формат фиксирует только изменения (дельты) между последовательными состояниями. Каждое изменение привязано ко времени UTC, поэтому даже при скачивании акций MOEX время стаканов будет указано по UTC.
QSH формат в OsEngine реализован на основе данной документации:
https://www.qscalp.ru/store/qsh.pdf.
1. OsData. Скачивание стаканов в формат QSH в коде.
Для скачивания стаканов через OsData используется поток Quotes. Скачивание сделок (Deals) не предусмотрено.
За скачивание стаканов в формате QSH отвечает класс MarketDepthLoader. Для каждой бумаги создается отдельный экземпляр класса с собственным потоком Task, который обеспечивает последовательную запись данных в бинарный файл.
При получении стакана от коннектора он помещается в очередь, после чего в потоке UpdateMarketDataAsync стакан считывается и записывается в файл.
1. Конструктор класса. Данный регион отвечает за создание объектов для работы с QSH, создание задачи Task для чтения и записи стаканов в бинарный файл, удаление и очистка всех объектов при завершении работы приложения.
2. В данном регионе находится основной поток класса, методы для записи заголовков файла и логика для создания новых файлов для каждого дня.
3. Регион, отвечающий за поиск изменений между новым стаканом и старым, после чего данные изменения записываются в бинарный файл. Здесь также реализованы базовые проверки стакана: Ask не должен быть меньше Bid, и не должно быть дублированных цен.
4. Здесь находится метод для чтения бинарного файла. Он нужен для продолжения записи в существующий файл, если приложение было закрыто. Через данный метод восстанавливаются все поля, необходимые для корректной записи данных, в особенности поле _lastMarketDepth, которое хранит последний слепок сохраненного стакана.
5. Хранит приватные поля, необходимые для работы класса.
6. Хранит публичные свойства.
7. Событие, из которого приходит слепок стакана. Он помещается в очередь для последующей обработки.
8. Регион с методом для логирования ошибок.
Отдельно стоит рассмотреть на метод CreateHeader, который отвечает за создание заголовка файла. В спецификации QSH предусмотрен произвольный пользовательский комментарий в заголовке файла. В нашем случае в этом комментарии указывается шаг объёма в формате VolumeStep:{_volumeStep}. При этом _volumeStep имеет тип decimal. Формат QSH не предусматривает дробные числа, поэтому для того, чтобы иметь возможность скачивать стаканы для криптовалют, нужно знать шаг объема.
Помимо основного класса MarketDepthLoader, который отвечает за обработку входящих стаканов и поиска изменений, существуют вспомогательные классы, обеспечивающие запись и чтение данных, а также их преобразование в бинарный формат.
2. Тестер. Чтение файлов со стаканами и сделками в коде.
За работу с QSH-файлами отвечает метод CheckMarketDepth, который находится в классе SecurityTester в регионе MarketDepth.
В метод CheckMarketDepth поступает время, эмулирующее текущее. При каждом вызове метода к этому времени добавляется одна миллисекунда.
В методе CheckMarketDepth выполняются базовые проверки файла: корректность формата, времени, даты и типа данных (Quotes или Deals). Для файлов, скачанных через OsData, существует комментарий VolumeStep, который указывает шаг объёма. Если данный параметр отсутствует, шаг объёма по умолчанию устанавливается равным 1. Проверки по объему находятся в методе ParseVolumeStepFromComment.
Формат QSH обеспечивает идеальный баланс между эффективностью хранения, скоростью чтения и записи, а также полнотой сохраняемых данных, что делает его отличным выбором для долгосрочного архивирования рыночной информации и последующего анализа.
QSCALP
Отдельные благодарности и лучи добра отправляем Николаю Морошкину из Qscalp за разработку формата и сервисы, которые вокруг него формируются.
Удачных алгоритмов!
Комментарии открыты для друзей!
https://smart-lab.ru/company/os_engine/blog/1024149.php
OsEngine: https://github.com/AlexWan/OsEngine
Поддержка OsEngine: https://t.me/osengine_official_support
Канал Научный трейдинг (Bad Quant): https://t.me/bad_quant