Смотри, как бесплатно скачать роботов
Ищи нас в Telegram!
Ставь лайки и следи за новостями
Интересный скрипт?
Поставь на него ссылку - пусть другие тоже оценят
Понравился скрипт?
Оцени его работу в терминале MetaTrader 5
Библиотеки

TickCompressor - со сжатием 1 тика до 2-3 байт в среднем - библиотека для MetaTrader 5

Просмотров:
311
Рейтинг:
(1)
Опубликован:
Обновлен:
\MQL5\Include\Forester\
MQL5 Фриланс Нужен робот или индикатор на основе этого кода? Закажите его на бирже фрилансеров Перейти на биржу

Сжатие тиковых данных для хранения в компактном виде до 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 варианта элементов тика для хранения:

  1. Ask, Bid, time_msc
  2. Ask, Bid, time_msc, volume_real
  3. Все элементы 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]);

    while (ZIPpos<ArraySize(Ticks2)){
       nextSize=Compressor3.ArrToInt(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]);}//стратегия
    };


Сборка тиков из всех блоков в один большой массив:

    while (ZIPpos<ArraySize(Ticks2)){
       nextSize=Compressor3.ArrToInt(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;
       //for (int j = 0; j < ticks; j++){ Strategy(Ticks3[j]);}//стратегия
    };


Или одной строкой. При этом записан должен быть только 1 блок. Если больше - то используйте 2 варианта кода выше.

total_ticks=Compressor3.DeCompress(Ticks2,Ticks3);



Dominant Candle Dominant Candle

Доминирующая свеча - это набор из двух свечей, в котором фитили пересекаются друг с другом, но тела свечей либо направлены вверх, либо направлены вниз, либо равны.

Counter Attack Candlestick Counter Attack Candlestick

Свечной паттерн "Контратака

MACD Histogram MC MACD Histogram MC

Гистограмма MACD

Bollinger Bands Squeeze Bollinger Bands Squeeze

Он сигнализирует о том, что период низкой волатильности на рынке скоро закончится, предвещая значительное движение цены.