Формат **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)