| Формат **TKZ** готов: библиотека и скрипты MQL5, сжатие без потерь, распакованные данные совпадают с исходными побитово. Внутри компрессор с контекстным смешиванием (context mixing), настроенный на поток котировок. В MetaEditor код ни разу не компилировался, потому что MT5 здесь нет, так что возможны ошибки или предупреждения компиляции.
|
|
|
| **Результаты на реальных тиках** (байт на тик, один блок на файл):
|
|
|
| | Данные | Тиков | xz -9e по сырым записям | xz по дельтам (лучший обычный вариант) | **TKZ** |
|
| |---|---:|---:|---:|---:|
|
| | EURUSD, Dukascopy, ноябрь 2023 | 1,94 млн | 3,08 | 1,74 | **1,46** (−16%) |
|
| | XAUUSD, Dukascopy, сентябрь 2023 | 2,39 млн | 2,96 | 1,69 | **1,37** (−19%) |
|
| | XAUUSD, данные брокера, май 2026 | 0,69 млн | 3,91 | 1,91 | **1,44** (−24%) |
|
| | US500, Tickstory, февраль 2025 | 0,20 млн | 4,93 | 2,99 | **2,20** (−26%) |
|
|
|
| Это в 11–17 раз меньше 24-байтных записей time_msc+bid+ask и в 27–44 раза меньше `MqlTick`.
|
|
|
| **Как устроено сжатие:**
|
| - **Цены в целые числа.** Число знаков, шаг цены и шаг времени определяются автоматически. Для цен на грубой сетке со смещением (у XAUUSD почти все цены заканчиваются на 5) цена раскладывается по модулю 10.
|
| - **Тик раскладывается на двоичные решения:** интервал времени, какая сторона сдвинулась, величина сдвига. Если обе стороны сдвинулись на разную величину, кодируется изменение спреда: оно предсказуемее, чем сдвиг ask.
|
| - **Модель.** На каждое решение около 10 контекстов, двухслойный микшер и арифметический кодер. Вся арифметика целочисленная, поэтому архивы переносимы между машинами.
|
| - **Надёжность.** Нестандартные значения (NaN, −0.0, ненормализованные цены) хранятся как есть. У каждого блока есть контрольная сумма.
|
|
|
| Около 70% объёма у форекса занимают метки времени. Я перепробовал много вариантов, и время уже близко к своему теоретическому пределу, так что дальнейшие улучшения модели дадут единицы процентов.
|
|
|
| **Что в репозитории** (в терминал копируется папка `MQL5`):
|
| - `Include/Tkz/TkzCodec.mqh` — сам кодек.
|
| - `Include/Tkz/TkzArchive.mqh` — файлы `.tkz`: запись, дозапись, чтение по блокам и по диапазону времени.
|
| - Скрипты:
|
| - `TkzSelfTest` — запускать первым;
|
| - `TkzExport` — выгрузка истории в архив, блоками по дню, неделе или месяцу, с проверкой каждого блока;
|
| - `TkzVerify` — сверка архива с историей терминала и замер скорости распаковки;
|
| - `TkzToCustom` — загрузка архива в пользовательский символ для тестера.
|
| - `docs/FORMAT.md` — спецификация формата, `README.md` — описание и API.
|
|
|
| **Как проверено без MT5.** Я написал переводчик MQL5→C++ и эмуляцию среды MQL5 с проверкой выхода за границы массивов, поэтому тестируется тот же самый код:
|
| - все 5,2 млн реальных тиков восстанавливаются побитово;
|
| - граничные случаи: пустой блок, NaN/Inf, отрицательное время, отрицательные цены, сетка 0,25;
|
| - 3000 испорченных блоков: каждый либо отклонён, либо восстановлен точно, падений нет;
|
| - все четыре скрипта прогнаны целиком на эмулированном терминале.
|
|
|
| **Что прошу сделать у себя:**
|
| 1. **Компиляция.** Я писал на осторожном подмножестве MQL5 и вычитывал код вручную. Если MetaEditor выдаст ошибки или предупреждения, пришлите лог, поправлю.
|
| 2. **Запустите `TkzSelfTest`.** Все строки должны быть `PASS`. Главная — `golden output`: она сравнивает байты с эталонной сборкой, и `FAIL` в ней значит, что MQL5 где-то считает иначе.
|
| 3. **Скорость.** Её в MQL5 я измерить не мог. C++-сборка того же кода делает около 250 тыс. тиков/с и на сжатие, и на распаковку; в MQL5, вероятно, будет медленнее. Реальные цифры напечатают `TkzSelfTest` и `TkzExport`. Если окажется слишком медленно, могу сделать быстрый режим с меньшим числом контекстов ценой пары процентов сжатия.
|
|
|
| **Ограничения:**
|
| - Хранятся только time_msc, bid и ask. При распаковке флаги BID/ASK восстанавливаются там, где значение изменилось; `last` и объёмы равны нулю.
|
| - Размер блока влияет на сжатие: месяц практически оптимален, неделя хуже на 0,2%, день на 1%.
|
|
|
| Всё закоммичено в `main` (13 коммитов). Push не делал, потому что remote ещё нет. Тестовые данные в репозиторий не входят; их скачивает `tests/data/fetch_samples.sh`. Источник Dukascopy блокирует автоматическую загрузку (отвечает 429), поэтому взял их копии с Hugging Face:
|
| - [Henrik404/dukascopy-ticks](https://huggingface.co/datasets/Henrik404/dukascopy-ticks)
|
| - [CarlosSilva1/xauusd-ticks](https://huggingface.co/datasets/CarlosSilva1/xauusd-ticks)
|
| - [CarlosSilva1/us500-ticks](https://huggingface.co/datasets/CarlosSilva1/us500-ticks)
|