Имитация работы эксперта в прошлом из программы

 
Добрый день всем! Такая проблема. Есть эксперт, которому перед началом работы желательно знать историю своей работы в прошлом. Пока идея в том, чтобы хранить эту историю в файле, и перед началом работы эксперта, запускать его в тестере, чтобы создать файл истории. Потом, во время работы эксперта, он будет читать этот файл и анализировать историю. Может у кого-нибудь есть идея как все это реализовать в событии OnInit() при подключении эксперта, чтобы не прогонять его в тестере (сымитировать его работу в прошлом). Спасибо.
 
snookeredman:
Добрый день всем! Такая проблема. Есть эксперт, которому перед началом работы желательно знать историю своей работы в прошлом. Пока идея в том, чтобы хранить эту историю в файле, и перед началом работы эксперта, запускать его в тестере, чтобы создать файл истории. Потом, во время работы эксперта, он будет читать этот файл и анализировать историю. Может у кого-нибудь есть идея как все это реализовать в событии OnInit() при подключении эксперта, чтобы не прогонять его в тестере (сымитировать его работу в прошлом). Спасибо.

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

18523365;[sl];0;0.16;94.65;95.4;2009.06.01 10:42;-125.79;0;USDJPY;1.1272
18551770;cancelled;0;0.11;1.4249;1.4172;2009.06.01 16:11;0;0;EURUSD;0.016301
18589960;cancelled;0;0.11;1.418;1.416;2009.06.02 08:26;0;0;EURUSD;0.016301
18589949;cancelled;0;0.12;96.08;96.48;2009.06.02 08:25;0;0;USDJPY;1.144
18592556;[sl];0;0.12;96.53;96.15;2009.06.02 10:51;-47.43;0;USDJPY;1.144
18631488;cancelled;0;0.11;95.55;95.87;2009.06.02 17:23;0;0;USDJPY;1.1382
18658433;[tp];0;0.11;95.85;96.06;2009.06.03 08:40;24.05;0;USDJPY;1.1382
18658604;[tp];0;0.11;1.4271;1.4257;2009.06.03 10:37;15.4;0;EURUSD;0.016634
18682793;cancelled;0;0.12;96.44;95.75;2009.06.03 13:26;0;0;USDJPY;1.15
18692485;[sl];0;0.12;95.72;96.14;2009.06.03 16:37;-52.42;-2.1;USDJPY;1.139
18752066;cancelled;0;0.11;1.4243;1.4158;2009.06.04 13:16;0;0;EURUSD;0.016774

хранятся следующие данные: тикет ордера, комментарий, магик, лот, цено открытия, цена закрытия, дата закрытия, результат сделки в $, своп+комиссия в $, инструмент, текущий атр

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

  - могут в любой момент времени ее почикать

  - при переносе советника на другой счет история также становится недоступна, а здесь достатчно перенести данные в новый файл

  - файл истории легко сформировать при прогоне советника в тестере, а затем его же использовать при работе в реале

реализовано следующим образом:

перед тем, как необходимо получить историю из текстового файла (в моем случае - при установке ордеров необходимо рассчитать лот)  используется функция (здесь мт4)

void refreshbase(){
// обновить базу сделок, 
// загружается список тикетов из существующей базы
// если в среди истории какой либо из тикетов отсутствует, то он записывается в базу сделок
  string filename = genticketfilename();
  string accounthistory[1];
  loadhistory(accounthistory); //загрузить историю
  int total=OrdersHistoryTotal();
  
  
  Print("history loaded, orders in terminal history ", total );
  for(int pos=0;pos<total;pos++){
    // Print("pos = ", pos );
     if(OrderSelect(pos,SELECT_BY_POS,MODE_HISTORY)==false){
        Print("Ошибка при доступе к исторической базе (",GetLastError(),")");
        break;
     }
     if( StringFind(OrderComment(), "cancelled") != -1  ){
       //Print("break in canc");
       continue;
       break ; //сancellde order
     
     }
     Print( "ticket=", OrderTicket()," openprice=",OrderOpenPrice()," opentime=", TimeToStr( OrderOpenTime()) ," symbol=", OrderSymbol()," lots=", OrderLots());
     // если нет ордера в файле истории, то туда его записать
     if( !findticketinarray(accounthistory, OrderTicket())  ){
       // если этот ордер отсуствует в существующей истории, то туды его записать
       
       Print("order ", " нет  в истории ");
       writeordertohistoryfile();
     }else{
       Print("order ", " есть  в истории ");
     }
  }
}

потом используем

 

void loadhistory( string& hist[], int lenghthistory=0  ){
  
  string filename = genticketfilename();
  
  if( !FileExist( filename ) )return; //нет файла данных - нет истории
  int handle = FileOpen(filename, FILE_READ|FILE_CSV, "!" ); //разделитель на самом деле ;, но нужно прочитать всю строку за один раз
  if( handle < 1 ){
    Print("Ошибка открытия файла "+filename+" для чтения" );
    return;
    
  }
  
  int cnt = 0;
  while( !FileIsEnding(handle)){
    cnt++;
    ArrayResize(hist, cnt );
    
    hist[cnt-1]=FileReadString(handle);
    if( StringFind( hist[cnt-1], "cancelled")!= -1 ){
      cnt--;
      ArrayResize(hist, cnt );
    } 
  }
  if( cnt > lenghthistory && lenghthistory !=0  ){
    for( int  i = 0; i<lenghthistory; i++ ){
      hist[i] = hist[i+cnt-lenghthistory-1];
    
    }
    cnt = lenghthistory;
    ArrayResize(hist, cnt );
    Print("Размер истории умешьнешен до ", cnt );
    //for( i = 0; i<cnt; i++ ){
    //  Print(i, " ", hist[i]);
    //} 
  }
  FileClose(handle); 
}
в итоге имеем массив, содержащий всю историю работы эксперта, которая не зависит ни от дц, ни от того на одном ли или нет счете эксплуатировался эксперт. Множество всяких других плюсов: можно загрузить историю в excel, чтобы сделать какойнить анализ, творчески ее подредактировать, эти же файлы истории использую для учета и анализа результатов торговли.

Чтобы выполнить тестирование из советника, нужно пробовать запуск терминала с парамтрами, которые ему передаются в конфигурационном файле, в помощии:

 

[Tester]

Настройки тестирования, запускаемого при включении терминала:

  • Expert — имя эксперта, который должен быть запущен на тестирование (оптимизацию). Если этот параметр отсутствует, тестирование не будет запущено.
  • Symbol — название инструмента, который будет использоваться в качестве основного символа тестирования. В случае отсутствия данного параметра будет использован последний выбранный символ в тестере.
  • Period — период графика тестирования (любой период из 21 доступного в терминале). Если данный параметр отсутствует, используется период H1.
  • Login — с помощью данного параметра советнику можно передать значение счета, на котором якобы происходит его тестирование. Необходимость данного параметра закладывается в исходном MQL5-коде советника (при помощи функции AccountInfoInteger).
  • Modelрежим генерации тиков (0 — "Все тики", 1 — "OHLC на M1", 2 — "Только цены открытия"). Если данный параметр не указан, будет использован режим генерации всех тиков.
  • Optimization — включение/отключение оптимизации и указание ее вида (0 — оптимизация отключена, 1 — "Медленная (Полный перебор параметров)", 2 — "Быстрая (Генетический алгоритм)", 3 — "Все символы, выбранные в окне 'Обзор рынка'").
  • FromDate — дата начала диапазона тестирования в формате ГГГГ.ММ.ДД. Если этот параметр не указан, будет использована дата, указанная в соответствующем поле тестера стратегий.
  • ToDate — дата конца диапазона тестирования в формате ГГГГ.ММ.ДД. Если этот параметр не указан, будет использована дата, указанная в соответствующем поле тестера стратегий.
  • Report — имя файла, в который будет сохранен отчет о результатах тестирования. Файл будет создан в директории клиентского терминала. Относительно данной директории может быть указан путь сохранения файла, например \reports\tester.htm. Если в имени файла не указано его расширение, автоматически будет использовано расширение ".htm". В случае отсутствия данного параметра отчет тестирования не будет сохранен в виде файла.
  • ReplaceReport — разрешить/запретить перезапись файла отчета (0 — запретить, 1 — разрешить). Если перезапись запрещена и файл отчета с таким же именем уже существует, то к имени файла будет добавлен порядковый номер в квадратных скобках. Например, tester[1].htm. Если данный параметр отсутствует, используется значение "0" (перезапись запрещена).
  • ShutdownTerminal — разрешить/запретить выключение клиентского терминала по завершении тестирования (0 — запретить, 1 — разрешить). Если данный параметр отсутствует, используется значение "0" (выключение запрещено). Если процесс тестирования/оптимизации прерывается пользователем вручную, значение данного параметра автоматически сбрасывается на "0".
  • Deposit — сумма начального депозита для тестирования/оптимизации. Сумма указывается в валюте депозита счета. При отсутствии данного параметра используется сумма, указанная в соответствующем поле тестера стратегий.
  • Leverage — кредитное плечо, которое будет использовано при тестировании/оптимизации. Например, если указать значение 100 для данного параметра, будет использовано плечо 1:100. При отсутствии данного параметра используется плечо, указанное в соответствующем поле тестера стратегий.

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

 

чтобы запустить виндовс приложение, используйте

#import  "shell32.dll"  
  int ShellExecuteW(
    int hwnd,
    string Operation,
    string File,
    string Parameters,
    string Directory,
    int ShowCmd);  // 0-hide window 3-show window 
#import
в mt5 работает - проверено, пример использования, см. в статьях https://www.mql5.com/ru/articles/1467 https://www.mql5.com/ru/articles/34 
Автоматическая оптимизация торгового робота в процессе реальной торговли - Статьи по MQL4
  • www.mql5.com
Автоматическая оптимизация торгового робота в процессе реальной торговли - Статьи по MQL4: тестирование торговых стратегий
 
Спасибо большое gdtt. Сейчас реализовываю историю с помощью файлов. Потом займусь разработкой программного вызова тестера. Если будут вопросы, то вернусь.
 
snookeredman:
Спасибо большое gdtt. Сейчас реализовываю историю с помощью файлов. Потом займусь разработкой программного вызова тестера. Если будут вопросы, то вернусь.

не забывайте про глобальные переменные (https://www.mql5.com/ru/docs/globals).

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

Документация по MQL5: Глобальные переменные терминала
Документация по MQL5: Глобальные переменные терминала
  • www.mql5.com
Глобальные переменные терминала - Документация по MQL5
 
vikulin:

не забывайте про глобальные переменные (https://www.mql5.com/ru/docs/globals).

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

У глобальных переменных есть недостаток, короткий срок жизни, 2 недели если мне память не изменяет