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

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

Просмотров:
80
Рейтинг:
(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]);

    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 Dominant Candle

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

Counter Attack Candlestick Counter Attack Candlestick

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

MACD Histogram MC MACD Histogram MC

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

YURAZ_MCCH YURAZ_MCCH

Индикатор рассчитывает % роста или падения относительно CLOSE, написан с применением ООП, и легко интегрируется в любой советник или иной индикатор.