Ставь лайки и следи за новостями
Поставь на него ссылку - пусть другие тоже оценят
Оцени его работу в терминале MetaTrader 5
- Просмотров:
- 80
- Рейтинг:
- Опубликован:
- Обновлен:
-
Нужен робот или индикатор на основе этого кода? Закажите его на бирже фрилансеров Перейти на биржу
Сжатие тиковых данных для хранения в компактном виде до 3,5 раз компактнее, чем .tcs файлы MQ. И для быстрой работы с ними, т.к. на чтение 3 байт тратится меньше времени, чем на 60 байт MqlTick структуры.
Размер файла за 2023 год с Ask, Bid, time с дополнительным ZIP сжатием блоков данных видно на скриншоте:

Размер файлов в формате .tcs за 2023 год:

Сжатие в 3,56 раза.
Для хранения тиков используются разницы цен Ask и Bid от предыдущей цены. Часто (до 50...70% от всех тиков) она не превышает (-8...7) пунктов , а это можно записать 4 битами. Ask и Bid объединяем в 1 байт.
Плюс 1 байт на хранение разницы во времени от 0 до 255 миллисекунд (в коде до 229, значения выше 229 используются для кодирования тиков которые выходят за пределы -8...7 пунктов).
Если цены или время отличается на большие значения, то они упаковываются в большее число байт.
Для дополнительного сжатия можно применить ZIP архивацию. Размер данных при этом уменьшается до 2 раз.
Альтернативно можно делать сжатие до 3 байт, при этом Ask и Bid от -129 до 128 сжимаются до 8 бит или 1 байт каждый. Плюс 1 байт на время - итого 3 байта на большинство тиков.
Иногда (https://www.mql5.com/ru/forum/499639/page6#comment_58544810), если число тиков сжатых до 2 байт больше, чем до 4 байт, то эффективнее сжимать до 3 байт. Нужно смотреть по статистике инструмента.
Переключить максимальное сжатие до 3 байт можно командой:
#define compressTo3Bytes // сжимать тики до 3 байт вместо 2.
Элементы тика для хранения в сжатом виде
Запрограммировано 3 варианта элементов тика для хранения:
- Ask, Bid, time_msc
- Ask, Bid, time_msc, volume_real
- Все элементы Ask, Bid, Last, time_msc, volume_real, flags (int volume расчитается из volume_real)
Они же могут дополнительно сжиматься в ZIP. Итого будет 6 вариантов
method=1;//1...6 BidAsk_=1, BidAskVolume_=2, All_=3, BidAsk_Zipped=4, BidAskVolume_Zipped=5, All_Zipped=6
Перед запуском сжатия нужно передать в класс вариант хранения тиков и несколько стандартных параметров используемых для расчетов и нормализации цен.
TickCompressor Compressor2; double VolumeStep_=SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_STEP); Compressor2.Start(method,_Point,VolumeStep_,_Digits);
Если эксперт использует флаги, то их можно восстановить из изменений цен командой
#define RestoreFlags // восстановить флаги тика из изменения ask, bid, volume - добавит 7% к времени генерации тиков 931 вместо 869 мс
Эксперт для теста сжатия приложен, он выдаст статистику по скорости и по степени сжатия. В нем можно посмотреть пример сжатия и распаковки тиков.
Пример эксперта для торговли можно посмотреть тут https://www.mql5.com/ru/code/65821
Статистики для 2 и 3 байт сжатия:
| Сжатие до 2 байт: | Сжатие до 3 байт |
| Ticks: 47707712 Compressed size: 135718404 Compressed 2862666420 bytes into 135718404 bytes ==> 4.74% Compress performance: 764 MB/s Compress performance: 13.4 Ticks (millions)/sec. Compress performance criterion: 281.7 Decompress performance: 3550 MB/s Decompress performance: 62.0 Ticks (millions)/sec. Decompress performance criterion: 1308.8 Статистика от эксперта https://www.mql5.com/ru/code/65821 для BTCUSDT -------------------- Statistics: -------------------- 2 bytes: 70.1%, 50705359 ticks 4 bytes: 17.1%, 12350966 ticks 5 bytes: 12.7%, 9185484 ticks 6 bytes: 0.0%, 15274 ticks 11 bytes: 0.1%, 46214 ticks 12 bytes: 0.0%, 1 ticks 24 bytes: 0.0%, 1 ticks Total: 72303299 ticks, 197342036 bytes. Average: 2.729 bytes per tick UnZipped size: 197342036. Zipped size: 108302550. ZIP compression: 54.9 % Average: 1.498 bytes per tick Для EURUSD -------------------- Statistics: -------------------- 2 bytes: 66.2%, 29694779 ticks 4 bytes: 2.3%, 1022937 ticks 5 bytes: 31.5%, 14106637 ticks 6 bytes: 0.0%, 25 ticks 7 bytes: 0.0%, 8 ticks 11 bytes: 0.0%, 800 ticks 12 bytes: 0.0%, 3 ticks 13 bytes: 0.0%, 4 ticks 24 bytes: 0.0%, 1 ticks Total: 44825194 ticks, 134023609 bytes. Average: 2.99 bytes per tick UnZipped size: 134023609. Zipped size: 95495454. ZIP compression: 71.3 % Average: 2.13 bytes per tick | Ticks: 47707712 Compressed size: 169378137 Compressed 2862462720 bytes into 169378137 bytes ==> 5.92% Compress performance: 623 MB/s Compress performance: 10.9 Ticks (millions)/sec. Compress performance criterion: 183.9 Decompress performance: 3225 MB/s Decompress performance: 56.4 Ticks (millions)/sec. Decompress performance criterion: 952.6 Correct = true Статистика от эксперта https://www.mql5.com/ru/code/65821 для BTCUSDT -------------------- Statistics: -------------------- 3 bytes: 86.6%, 62644158 ticks 4 bytes: 0.6%, 412167 ticks 5 bytes: 12.7%, 9185484 ticks 6 bytes: 0.0%, 15274 ticks 11 bytes: 0.1%, 46214 ticks 12 bytes: 0.0%, 1 ticks 24 bytes: 0.0%, 1 ticks Total: 72303299 ticks, 236108596 bytes. Average: 3.266 bytes per tick UnZipped size: 236108596. Zipped size: 105802525. ZIP compression: 44.8 % Average: 1.463 bytes per tick Для EURUSD 3 bytes: 66.5%, 29801633 ticks 4 bytes: 2.0%, 916083 ticks 5 bytes: 31.5%, 14106637 ticks 6 bytes: 0.0%, 25 ticks 7 bytes: 0.0%, 8 ticks 11 bytes: 0.0%, 800 ticks 12 bytes: 0.0%, 3 ticks 13 bytes: 0.0%, 4 ticks 24 bytes: 0.0%, 1 ticks Total: 44825194 ticks, 163611534 bytes. Average: 3.65 bytes per tick UnZipped size: 163611534. Zipped size: 96541155. ZIP compression: 59.0 % Average: 2.154 bytes per tick |
Примеры кода
Сжатие тиков
Поблочно:
int ZIPpos=0;//счетчик сжатых байтов if(Amount>ticks_per_block){// > 1 блока - склейка блоков из tmp в Ticks2 for(int start=0; start<Amount; start+=ticks_per_block){ Compressor2.Compress(Ticks, tmp, start, (Amount > start + ticks_per_block ? ticks_per_block : Amount - start)); ZIPpos+=ArrayCopy(Ticks2,tmp,ZIPpos); //скопировать в конец Ticks2 } }else{//1 блок - распаковка сразу в Ticks2 Compressor2.Compress(Ticks, Ticks2, 0, Amount); }
Если задать количество тиков в 1 блоке больше, чем всего тиков в массиве, то он будет сжат в 1 блок.
Если всегда нужно сжатие в 1 блок, то можно использовать
Compressor2.Compress(Ticks,Ticks2);
Но при этом скорость распаковки такого одного большого или очень большого блока может быть раза в 2 медленнее. Так же будет большое потребление памяти под большой блок.
Распаковка тиков
При распаковке желательно знать число упакованных тиков. Массив приемник должен иметь этот размер.
ArrayResize(Ticks3,Amount); Размер можно например сохранять в файле. И потом использовать при распаковке.
Если размер неизвестен, то можно изменять размер внутри цикла на число тиков в блоке
//медленнее ArrayResize(Ticks3,total_ticks+ticks_per_block,10000000); //изменить размер большого массива - работает медленнее, чем перезапись малого блока
Этот код получает тики поблочно. Если всего 1 большой блок - он его тоже считает правильно. Тики не собираются в большой массив, а сразу могут быть обработаны вашей стратегией Strategy(Ticks3[j]);
ArrayResize(Ticks3,Amount); //изменить размер массива для чтения поблочно int total_ticks=0; int nextSize=0;//размер следущего блока ZIPpos=0;// адрес while (ZIPpos<ArraySize(Ticks2)){ nextSize=Compressor3.ArrToInt2(Ticks2,ZIPpos);//размер следущего блока ZIPpos+=4; uint s = ArrayCopy(tmp,Ticks2,0,ZIPpos,nextSize); //скопировать новый блок в tmp размером nextSize //медленнее в 3 раза ArrayResize(Ticks3,total_ticks+ticks_per_block,10000000); //изменить размер большого массива - работает медленнее, чем перезапись малого блока //total_ticks=Compressor3.DeCompress(tmp,Ticks3,nextSize,total_ticks);//распаковать блок и дописать в Ticks3 total_ticks+=Compressor3.DeCompress(tmp,Ticks3,nextSize,0); //распаковать блок и перезаписать в Ticks3 ZIPpos+=nextSize; for (int j = 0; j < ticks; j++){ Strategy(Ticks3[j]);}//стратегия };
Сборка тиков из всех блоков в один большой массив:
ArrayResize(Ticks3,Amount); Compressor3.Start(method,_Point,VolumeStep_,_Digits); nextSize=0;//размер следущего блока ZIPpos=0;// адрес total_ticks=0; while (ZIPpos<ArraySize(Ticks2)){ nextSize=Compressor3.ArrToInt2(Ticks2,ZIPpos);//размер следущего блока ZIPpos+=4; uint s = ArrayCopy(tmp,Ticks2,0,ZIPpos,nextSize); //скопировать новый блок в tmp размером nextSize //медленнее ArrayResize(Ticks3,total_ticks+ticks_per_block,10000000); //изменить размер большого массива - работает медленнее, чем перезапись малого блока total_ticks=Compressor3.DeCompress(tmp,Ticks3,nextSize,total_ticks);//распаковать блок и дописать в Ticks3 //total_ticks+=Compressor3.DeCompress(tmp,Ticks3,nextSize,0); //распаковать блок и перезаписать в Ticks3 ZIPpos+=nextSize; };
Или одной строкой
total_ticks=Compressor3.DeCompress(Ticks2,Ticks3);
Dominant Candle
Доминирующая свеча - это набор из двух свечей, в котором фитили пересекаются друг с другом, но тела свечей либо направлены вверх, либо направлены вниз, либо равны.
Counter Attack Candlestick
Свечной паттерн "Контратака
MACD Histogram MC
Гистограмма MACD
YURAZ_MCCH
Индикатор рассчитывает % роста или падения относительно CLOSE, написан с применением ООП, и легко интегрируется в любой советник или иной индикатор.