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

MathTicker - генератор тиков в математическом режиме - библиотека для MetaTrader 5

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

Альтернатива для библиотеки EAToMath  https://www.mql5.com/ru/code/61283

Записывает тики в режиме по реальным тикам и считывает их в математическом вызывая вашу стратегию с каждым записанным тиком.

Причина создания: Тестер MQ, записывает файлы с тиковыми данными каждому агенту при каждом запуске оптимизатора. У меня 36 агентов записывают по 10 Гб для одного из инструментов и периода тестирования - итого 360Гб на диске в 480 Гб. Занимает времени этот процесс около 1 часа перед каждой оптимизацией. Обычные SSD имеют ресурс в 500-1000 циклов записи. Перезаписывая 360 Гб каждый раз ресурс очень быстро исчерпается. Данная библиотека записывает только 1 файл и потом все 36 агентов будут читать данные из этого одного файла. Всё это и было причиной написания библиотеки: используем только 1 файл + экономия 1 часа на запись данных каждому агенту + ускорение по сравнению с тестером MQ и даже с Virtual в режиме по реальным тикам.
Проблему исследовали одновременни с fxsaber (автором EAToMath), каждый со своей версией. Мой код мне более понятен, поэтому использую его.

Для торговых операций используется библиотека MT4Orders https://www.mql5.com/ru/code/16006
Для виртуальной торговли нужно использовать библиотеку Virtual https://www.mql5.com/ru/code/22577
Для просмотра результатов торговли можно использовать MT4Orders QuickReport https://www.mql5.com/ru/code/47816 или Report
Для сжатия тиков TickCompressor https://www.mql5.com/ru/code/66201
Для удаления возможно лишних тиков подключается библиотека  Control_Trade_Sessions https://www.mql5.com/ru/code/48059 например, если котировочная сессия больше торговой. Её можно и удалить, если используются все тики. т.е. сессии совпадают.


Отличия от EAToMath:

Плюсы:

  • код короче и проще, всего 5 подключаемых библиотек. При необходимости доработки - будет проще разобраться.

  • данные сжимаются лучше, благодаря другому алгоритму https://www.mql5.com/ru/code/66201. При сохранении только time_msc, ask и bid - до 86% тиков сохраняются как 3 char числа, т.е. 3 байта. Средний размер на тик = 3.266 Байта при сохранении тиковых данных BTCUSDT за 2023 год.
    При сохранении с объемами среднее = 4.835 Байта. И при сохранении полном тике = 8.439 Байта. Ниже будет таблица с результатами теста.
    Дополнительно можно использовать встроенную ZIP архивацию. Размер файлов уменьшается еще в 2 раза. Такой файл занимает 245 Мб, при этом сумма рамеров файлов в .tcs за 2023 год занимает 364 Мб, т.е. сжатие в 1,5 раза лeчше чем у MQ. А скорость генерации тиков в математическом режиме в ~2 раза выше. См. таблицу ниже.

  • Вариантов сохранения больше:


  • файл можно сохранять как на SSD, так и на RAM диск, сделав ссылку в системе. Файлы могут занимать много места и RAM диска может не хватать, поэтому можно выбрать сохранение на основной диск. Скорость чтения с SSD и с RAM примерно одинаковы, Читал, что SSD кеширует до 5% от полного объема самые часто запрашиваемые данные.
    При чтении есть небольшой износ SSD, т.к. чаще нужно перезаписывать ячейки памяти, чем при хранении без чтения. Точных цифр не знаю, но например 1 перезапись на 10 чтений или на 1000... Но это мало значимо по сравнению с износом диска тестером MQ.

Минусы:

  • Подключение Virtual нужно делать самостоятельно (инструкция по использованию тут https://www.mql5.com/ru/code/22577), EAToMath  сам передаст вашу стратегию в Virtual.

Скорость работы для BidAsk варианта соизмерима с EAToMath. Другие варианты медленнее, т.к. или содержат больше данных или имеют дополнительное ZIP сжатие.

Особенности использования:

В стратегии нельзя использовать стандартные функции Symbol(), Digits() (=4), Point() (=0.0001), т.к. они выдадут дефолтные значения, а не относящиеся к тестируемому символу. Вместо них используйте _Symbol, _Digits, _Point которые переопределены на значения считанные из файла. Так же добавлены новые константы _TickSize и _TickValue с значениями от записанного символа - они нужны для правильного расчета прибыли, комиссии и свопов в валюте депозита.

Порядок работы с периодом тестирования выбранным при сохранении тиков:

  1. Выбрать режим тестирования по реальным тикам, нужный инструмент и даты тестирования. Переменную Task установить в один из Save и выбрать вариант сохранения тиков. Запустить тестер. После этого в указанной папке будет создан файл с тиками.

  2. Установить переменную Task в Run_Strategy. Режим можно оставить по реальным тикам, чтобы потом сравнить. Запустить тестер. Расчеты производятся по реальным тикам, а не из файла. Получить результат.


  3. Установить режим тестирования в математические расчеты. Запустить тестер. Расчеты производятся по тикам из файла. Сравнить с результатом из п.2. Должно быть одинаково, но в несколько раз быстрее.

Порядок работы с архивом:

  1. Создать архив со всеми тиками из истории: Выбрать режим тестирования по реальным тикам, нужный инструмент. Даты тестирования установить от <= первого тика, до >= последнего тика в имеющейся истрии . Переменную Task установить в один из Save...To_Archive и выбрать вариант сохранения тиков. Запустить тестер. После этого в указанной папке будет создана папка с именем инструмена в которой сохранятся файлы с тиками для каждого года. Последний год можно по мере необходимости перезаписывать, для этого в датах выбрать только текущий год, чтобы не перезаписывать предыдущие годы.
  2. Установить режим тестирования в математические расчеты. Установить переменную Task в Run_Strategy_Fron_Archive.
  3. В группе инпутов MathTicker: using the full archive установить:
    Instrument - в название инструмента (должно совпадать с названием папки, где хранятся его тики), стартовую и конечную дату теста.

  4. Запустить тестер. Расчеты производятся по тикам из требуемых годовых файлов. Из за того, что работа идет не с одним файлом, а с несколькими, то это немного медленнее, т.к. тратится время на открытие и закрытие файлов. Например вместо 1.7 секунды будет 2.7 секунды на генерацию тиков за 3 года.
  5. Сумма тиков полученная экспертом ниже может отличаться на небольшое значение одного первого тика. При тестах на кастоминых символах в режиме реальных тиков первый тик выдает только Ask или Bid (если вы не сохраняли оба). При тесте из архива они оба восстановлены из предыдущих тиков.

Пример простейшего эксперта для оценки скорости работы:

#property tester_no_cache
#include <Forester\MathTicker.mqh> // подключение торговли в математическом режиме
input int rep=0;//Repeats for optimization
sinput bool AddVolumes=true;
void OnInit(){}

void OnTick(){
   static MqlTick Tick;
   if (SymbolInfoTick(_Symbol, Tick)){
      #ifdef _MathTick_
         if(MathTick.SaveTick(Tick)){ return; }//если сохраняем тики, то выход и не торгуем. 
      #endif
      Strategy(Tick);
   }
}
double Sum = 0;int tk=0;
void Strategy(MqlTick& Tick){ // простейшая стратегия - использована для сравнения скорости чтения с EAToMath  
   Sum += Tick.bid+Tick.ask+(AddVolumes?Tick.volume_real:0.0); tk++;
   //if(tk<100){Print(Tick.time," ",Tick.ask," ",Tick.bid," ",Tick.last," ",Tick.volume_real," ",Tick.flags);}
}

ulong StartTime  = GetMicrosecondCount();
double OnTester(){
   #ifdef _MathTick_ // запуск с MathTick - он считает параметры символа из файла с тиками. Для тестов в мат режиме
      if(MathTick.SaveTicksEnd()){return 0;}//закрыть файл после записи тиков и выйти
      if(MathTick.ReadSymbolVars()){
         MathTick.Ticker();//в режиме мат расчетов подаст все тики в Strategy(MqlTick &Tick).
      }
   #endif
   Print("ticks: ",tk);
   long work_time = (long)(GetMicrosecondCount() - StartTime)/1000;
   //return(NormalizeDouble(work_time, 1)); // для получения скорости работы и
   return Sum;// для сравнения результатов расчета
}

Можно переключать 1 настройку:

//#define RestoreFlags // восстановить флаги тика из изменения ask, bid, volume - добавит 7% к времени генерации тиков 931 вместо 869 мс

При генерации тиков будет выведена статистика о сжатии тиков.
Ниже распечатки статистики, объемов и времени генерации тиков.

-----------
MQ тестер без объемов
pass 1 returned result 4345830621850.311523 in 0:00:08.232

  C ZIP сжатием
AskBid. Размер файла: 225 mb
-------------------- 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
final balance 0.00 USD

pass 10 returned result 4345830621850.311523 in 0:00:01.485
без нормализации
pass 1 returned result 4345830621850.311523 in 0:00:00.892
AskBid_Zipped. Размер файла: 106 mb
-------------------- 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:111720863. ZIP compression: 47.3 %

pass 10 returned result 4345830621850.311523 in 0:00:02.548
без нормализации
pass 2 returned result 4345830621850.311523 in 0:00:01.890



MQ тестер с объемами
pass 1 returned result 4345879117123.356445 in 0:00:07.962

  C ZIP сжатием  
AskBidVolume. Размер файла: 333 mb
-------------------- Statistics: --------------------
4 bytes: 60.4%, 43684907 ticks
5 bytes: 1.1%, 809676 ticks
6 bytes: 33.5%, 24194111 ticks
7 bytes: 4.9%, 3548666 ticks
8 bytes: 0.0%, 7909 ticks
12 bytes: 0.1%, 40022 ticks
13 bytes: 0.0%, 17964 ticks
14 bytes: 0.0%, 2 ticks
19 bytes: 0.0%, 41 ticks
32 bytes: 0.0%, 1 ticks
Total: 72303299 ticks, 349571243 bytes.
Average: 4.835 bytes per tick

pass 1 returned result 4345879117123.356445 in 0:00:02.803
без нормализации
pass 4 returned result 4345879117123.356445 in 0:00:01.659
AskBidVolume_Zipped. Размер файла: 204 mb
-------------------- Statistics: --------------------
4 bytes: 60.4%, 43684907 ticks
5 bytes: 1.1%, 809676 ticks
6 bytes: 33.5%, 24194111 ticks
7 bytes: 4.9%, 3548666 ticks
8 bytes: 0.0%, 7909 ticks
12 bytes: 0.1%, 40022 ticks
13 bytes: 0.0%, 17964 ticks
14 bytes: 0.0%, 2 ticks
19 bytes: 0.0%, 41 ticks
32 bytes: 0.0%, 1 ticks
Total: 72303299 ticks, 349571243 bytes.
Average: 4.835 bytes per tick
UnZipped size:349571243. Zipped size:214897079. ZIP compression: 61.5 %

pass 2 returned result 4345879117123.356445 in 0:00:04.260
без нормализации
pass 2 returned result 4345879117123.356445 in 0:00:03.096
All. Размер файла: 582 mb
-------------------- Statistics: --------------------
8 bytes: 61.5%, 44494583 ticks
9 bytes: 33.5%, 24194111 ticks
10 bytes: 4.9%, 3548666 ticks
11 bytes: 0.0%, 7909 ticks
15 bytes: 0.1%, 40022 ticks
16 bytes: 0.0%, 17964 ticks
17 bytes: 0.0%, 2 ticks
22 bytes: 0.0%, 41 ticks
44 bytes: 0.0%, 1 ticks
Total: 72303299 ticks, 610166056 bytes.
Average: 8.439 bytes per tick

pass 2 returned result 4345879117123.356445 in 0:00:03.768
без нормализации
pass 1 returned result 4345879117123.356445 in 0:00:02.256
All_Zipped. Размер файла: 245 mb
-------------------- Statistics: --------------------
8 bytes: 61.5%, 44494583 ticks
9 bytes: 33.5%, 24194111 ticks
10 bytes: 4.9%, 3548666 ticks
11 bytes: 0.0%, 7909 ticks
15 bytes: 0.1%, 40022 ticks
16 bytes: 0.0%, 17964 ticks
17 bytes: 0.0%, 2 ticks
22 bytes: 0.0%, 41 ticks
44 bytes: 0.0%, 1 ticks
Total: 72303299 ticks, 610166056 bytes.
Average: 8.439 bytes per tick
UnZipped size:610166056. Zipped size:257105213. ZIP compression: 42.1 %

pass 1 returned result 4345879117123.356445 in 0:00:05.388
без нормализации
pass 10 returned result 4345879117123.356445 in 0:00:03.936

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

Все варианты с ZIP, даже полное сохранение тиков - компактнее (от 3,5 до 1,5 раз).

Пример эксперта для виртуальной торговли и вывода отчетов:

#property tester_no_cache

#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006
#include <Forester\MathTicker.mqh> // подключение торговли в математическом режиме

#define ORDER_CURRENCY_DIGITS 2 // Задание Digits для вычисления профита/комиссии/свопа при помещении в историю торгов.
#define VIRTUAL_LIMITS_TP_SLIPPAGE // Лимитники и TP исполняются по первой цене акцепта - положительные проскальзывания
#define ORDER_COMMISSION -0 // Задание комиссии = Lots * ORDER_COMMISSION. 
#include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/ru/code/22577


#define REPORT_TESTER             // В тестере будут автоматически записываться отчеты
#define REPORT_BROWSER            // Создание отчета с запуском браузера - требует разрешения DLL.
#define USE_highcharts //- You can download and try out all Highcharts products for free. Once your project/product is ready for launch, purchase a commercial license. https://shop.highcharts.com/
#include <MT4Orders_QuickReport.mqh>//


enum VirtTyp {MQ_Tester=0,Virtual1=1,Virtual2=2};
sinput VirtTyp tester1=1;//Tester 1
sinput VirtTyp tester2=2;//Tester 2

input int rep=0;//Repeats for optimization

bool isOptimization = false, isTester=false; double balInit=0;
VIRTUAL_POINTER Virtual[10];

void OnInit(){
   Virtual[0] = 0; // 0 - реальное торговое окружение
   Virtual[1] = VIRTUAL::Create(AccountBalance()); // Создали виртуалку 1.
   Virtual[2] = VIRTUAL::Create(AccountBalance()); // Создали виртуалку 2.
   //Virtual[tester1].Select();
   isOptimization = MQLInfoInteger(MQL_OPTIMIZATION) ;
   isTester = MQLInfoInteger(MQL_TESTER);
   balInit=AccountBalance();
}

void OnTick(){
   //Virtual[0].Select();
   VIRTUAL::NewTick();//отправить тик в текущую виртуалку
   static MqlTick Tick;
   if (SymbolInfoTick(_Symbol, Tick)){
      #ifdef _MathTick_
         if(MathTick.SaveTick(Tick)){ return; }//при записи тиков выйдет из функции, Strategy() не будет вызвана
      #endif
      Strategy(Tick);//trading
   }
}

void Strategy(MqlTick& Tick){ // простейшая стратегия - использована для сравнения скорости чтения с EAToMath  
   if(Tick.ask==0 || Tick.bid==0){return;}//MQ тестер торгует при сбойном тике, Virtual нет. Запрет и для MQ
   if(tester1>0){Virtual[tester1].Select(); VIRTUAL::NewTick(Tick);}//выбрать виртуалку 1 и отправить тик
   if(tester2>0){Virtual[tester2].Select(); VIRTUAL::NewTick(Tick);}//выбрать виртуалку 2 и отправить тик
   if(isNewHour(Tick.time)){//первый тик каждого часа
      if(GetHour0(Tick.time) % 2==0){// купить по четным часам в тестере 1
         Virtual[tester1].Select();//выбрать виртуалку 1
         OrderSend(_Symbol, OP_BUY, 1, Tick.ask, 0, Tick.ask - 100 * _Point, Tick.ask + 100 * _Point); 
      }else{//продать по нечетным часам в тестере 2
         Virtual[tester2].Select();//выбрать виртуалку 2
         OrderSend(_Symbol, OP_SELL, 1, Tick.bid, 0, Tick.bid + 100 * _Point, Tick.bid - 100 * _Point);   
      } 
   }
}

double OnTester(){
   #ifdef _MathTick_ // запуск с MathTick - он считат параметры символа из файла с тиками. Для тестов в мат режиме
      if(MathTick.SaveTicksEnd()){return 0;}//return after ticks saving
      if(MathTick.isMath && MathTick.ReadSymbolVars()){
         if(tester1==0){Alert("   >>>>>>>>>   Virtual tester 1=MQ. In math mode can be used only virtual tester.   <<<<<<<<");return 0;}
         if(tester2==0){Alert("   >>>>>>>>>   Virtual tester 1=MQ. In math mode can be used only virtual tester.   <<<<<<<<");return 0;}

         SYMBOL_BASE sb; sb.Point=_Point; sb.Digits=_Digits; sb.Symbol=_Symbol; sb.SymbolID=0; sb.TickSize=_TickSize; sb.TickValue=_TickValue / _TickSize;//this.TickValue_ /= this.TickSize_; //as in SetSymbol() in \fxsaber\Virtual\Symbol_Base.mqh
         Virtual[1].Select(); VIRTUAL::SetSymbolBase(sb); Virtual[2].Select(); VIRTUAL::SetSymbolBase(sb);
         //minFreezeLevel = _minFreezeLevel*_Point; minStopLevel = _minStopLevel*_Point;

         Virtual[tester1].Select();
         MathTick.Ticker();//в режиме мат расчетов подаст все тики в Strategy(MqlTick &Tick). 
      }
   #endif

  double ret_val=0;
  for (int v = 0 ; v <= VIRTUAL::Total(); v++){
    if(Virtual[v].Select()){
      if(v > 0){
         VIRTUAL::Stop();
         #ifdef _MathTick_ // запуск с MathTick - он считат параметры символа из файла с тиками. Для тестов в мат режиме
            if(MathTick.isMath){ VIRTUAL::CalcSwaps( MathTick.swapShort, MathTick.swapLong, 0, MathTick.swap3days ); }//свопы из файла с тиками
            else{VIRTUAL::CalcSwaps( _Symbol, 0 );}
         #else
          VIRTUAL::CalcSwaps( _Symbol, 0 );//расчитать свопы - всем сделкам один своп, т.е. если 2+ разных инструмента, то обоим будет своп основного символа
         #endif
      }// закрыть незавершенные сделки по цене последнего тика, как в тестере

      if( !isOptimization){QuickReport("report_"+(string)v, true, v,false,true);}
      Print((string)v+" AccountBalance = ",AccountBalance(), "   AccountEquity = ",AccountEquity());
      double prib=AccountBalance()-balInit;
      ret_val += prib; //
  }}
  return ret_val;// для сравнения результатов расчета
}



bool isNewHour  (datetime &t){ static int next_h=-1; if(t < next_h){ return false; } else { next_h = (GetHour0(t)+1)*3600;return true;}}
int GetHour0    (datetime &t){return((int)( t / 3600));}//current hour from 1 Jan 1971

Этот пример создает 2 виртуальные машины в которых идет разная торговля. По четным часам в одном тестере происходит покупка, в другом по нечетным часам продажа.

Сделан сложный пример с 2-мя тестерами, его можно упростить, если нужна работа с одним тестером.

Так же для контроля правильности расчетов можно выбрать тестер MQ и сравнить с результатами виртуальных тестеров. Может не совпадать только комиссия, т.к. разных комиссий придумано много, а в виртуальном тестере запрограммирован только один вариант.

OHLC Candles with Ask and Bid OHLC Candles with Ask and Bid

Свечной график, который соединяет цену спроса и цену предложения с максимумом и минимумом свечи

Custom Bollinger Bands Custom Bollinger Bands

Стандартный индикатор Bollinger Bands с добавлением функции усреднения

OHLC Candles with extreme tick price tracking OHLC Candles with extreme tick price tracking

Это свечной график OHLC, который фиксирует максимальную цену покупки и минимальную цену продажи на каждом новом баре.

Manual Backtest Bar Replay Simulator Manual Backtest Bar Replay Simulator

Простой индикатор, который может помочь вам в ручном бэктесте, просто перемещая вертикальную линию, чтобы показать скрытые бары.