tkz-summary/TKZ_SUMMARY.md
2026-11-06 18:09:56 -08:00
50 lines
6.9 KiB
Markdown
Формат **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)