Работа с результатами оптимизации - страница 3

 
Написал советник для тестирования обработки форварда в разных функциях и запустил на разных компьютерах с win_10 и server_2008: результаты одни и те-же, описаны в посте выше. С включённым форвардом файл не пишется (FrameNext() не работает). Протестируйте, пожалуйста это у себя или укажите на ошибки - почему это не работает.
input double param_1=1.0;//Тестовый параметр
int filehandle;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnTesterInit()
  {
   Print(__FUNCTION__" FORWARD ",(string)MQLInfoInteger(MQL_FORWARD));
   Print(__FUNCTION__" FRAME_MODE ",(string)MQLInfoInteger(MQL_FRAME_MODE));
   ResetLastError();
   string subfolder="Opt_reports";
   string rep_name="\\"+"Forw_Test"+".csv";
//--- общая папка всех клиентских терминалов
   string common_folder=TerminalInfoString(TERMINAL_COMMONDATA_PATH);
//--- выведем имя этой папки
   PrintFormat("Откроем файл в общей папке клиентских терминалов %s",common_folder);
//--- откроем файл в общей папке (указан флаг FILE_COMMON)
   filehandle=FileOpen(subfolder+rep_name,FILE_WRITE|FILE_READ|FILE_COMMON);
   return INIT_SUCCEEDED;
  }//OnTesterInit() 
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   Print(__FUNCTION__" FORWARD ",(string)MQLInfoInteger(MQL_FORWARD));
   Print(__FUNCTION__" FRAME_MODE ",(string)MQLInfoInteger(MQL_FRAME_MODE));

   return(INIT_SUCCEEDED);
  }//OnDeinit
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Print(__FUNCTION__" FORWARD ",(string)MQLInfoInteger(MQL_FORWARD));
   Print(__FUNCTION__" FRAME_MODE ",(string)MQLInfoInteger(MQL_FRAME_MODE));
  }//OnDeinit
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double OnTester()
  {
   Print(__FUNCTION__" FORWARD ",(string)MQLInfoInteger(MQL_FORWARD));
   Print(__FUNCTION__" FRAME_MODE ",(string)MQLInfoInteger(MQL_FRAME_MODE));
//---
   static long pass_calk;
   pass_calk++;
//---Переменные для фрейма
   string fram_name="back_test";
   double frame_val=0;//Значение фрейма
   if(MQLInfoInteger(MQL_FORWARD)==true)
     {
      fram_name="forward";
      frame_val=1;
     }//
   double pass_result[1];//Оптимизируемый символ
   ArrayInitialize(pass_result,0);
   pass_result[0]=param_1*pass_calk;
   if(FrameAdd(fram_name,pass_calk,frame_val,pass_result)==false)Print("OnTester(): Фрейм не создан");
   else Print(pass_calk," OnTester(): Frame created");
   return(pass_result[0]);
  }//OnTester()
//+------------------------------------------------------------------+
//| TesterDeinit function                                            |
//+------------------------------------------------------------------+
void OnTesterDeinit()
  {
   Print(__FUNCTION__" FORWARD ",(string)MQLInfoInteger(MQL_FORWARD));
   Print(__FUNCTION__" FRAME_MODE ",(string)MQLInfoInteger(MQL_FRAME_MODE));
//---
   ulong pass_num=0;// получение номера прохода из фрейма
   string fr_name="";// публичное имя/метка из фрейма
   long publ_id=0;// публичный id из фрейма
   double frm_val=0;// значение  из фрейма
   double rep_data[1];// массив приёма результата
   ArrayInitialize(rep_data,0);
   double test_result[1];//Масиив сбора результатов теста: [0]-бэк, [1]-форвард
   ArrayInitialize(test_result,0);
//--Пишем фреймы в файл
   if(filehandle!=INVALID_HANDLE)
     {
      FrameFirst();
      int str_count=0;
      while(FrameNext(pass_num,fr_name,publ_id,frm_val,rep_data)==true)
        {
         str_count++;
         FileWrite(filehandle,str_count,_Symbol,fr_name,DoubleToString(frm_val,2),DoubleToString(rep_data[0],2));
         FileSeek(filehandle,0,SEEK_END);//Курсор в конец файла
        }//while
      FileClose(filehandle);
     }
   else Print("Операция FileOpen неудачна, ошибка ",GetLastError());
   if(filehandle!=INVALID_HANDLE)
     {
      FileClose(filehandle);
     }//
   ChartClose();//Закрыть чарт оптимизации  
  }//OnTesterDeinit()

Вот результаты:

Окно "Эксперты"

эксперты

Окно "Агенты

агент #1

 

Прикладываю модификацию, которая у меня пишет и оптимизацию и форварды.

В файле csv получаем:

1       GBPUSD  back_test       0.00    1.00
1       GBPUSD  back_test       0.00    2.00
1       GBPUSD  back_test       0.00    3.00
1       GBPUSD  back_test       0.00    4.00
1       GBPUSD  back_test       0.00    5.00
1       GBPUSD  back_test       0.00    6.00
1       GBPUSD  back_test       0.00    7.00
1       GBPUSD  back_test       0.00    8.00
1       GBPUSD  back_test       0.00    9.00
1       GBPUSD  back_test       0.00    10.00
1       GBPUSD  forward 1.00    10.00
1       GBPUSD  forward 1.00    9.00
1       GBPUSD  forward 1.00    8.00
1       GBPUSD  forward 1.00    7.00
1       GBPUSD  forward 1.00    6.00
1       GBPUSD  forward 1.00    5.00
1       GBPUSD  forward 1.00    4.00
2       GBPUSD  forward 1.00    3.00
3       GBPUSD  forward 1.00    2.00
4       GBPUSD  forward 1.00    1.00
Нумерация (пакетирование) фреймов как в примере выше (1, 2, 3, 4 в первой колонке внизу) происходит не всегда. Обычно фреймы приходят по одному, т.е. во всех строках первая колонка содержит 1.
Файлы:
fwdfrmfl.mq5  3 kb
 
Stanislav Korotky:

Прикладываю модификацию, которая у меня пишет и оптимизацию и форварды.

В файле csv получаем:

Нумерация (пакетирование) фреймов как в примере выше (1, 2, 3, 4 в первой колонке внизу) происходит не всегда. Обычно фреймы приходят по одному, т.е. во всех строках первая колонка содержит 1.

Мы что-то оба упускаем. Ваш пример не может работать: Нет перевода курсора после FileWrite() и FrameFirst() перед FrameNext(). Я их добавил, но форварды не пишуться всё равно. Ко мне тоже приходила идея собирать данные в OnTesterPass(), но ничего не получалось. Работала только OnDeinit(). Я создавал файлы там-же и они разбрасывались по папкам агентов. Но форварды писались. Я отказался от этой идеи потому что в итоге нужен результат только лучшего прохода а не всех сразу. Попробую  пособирать данные в массив структур (если получится) и обработать данные в OnTesterDeinit(). Всё равно, спасибо вам большое за участие. Для меня было открытием, что в OnTesterPass() фреймы могут приходить пачками. Вот что у меня выдал ваш советник:

результат

 
Good Beer:

Мы что-то оба упускаем. Ваш пример не может работать: Нет перевода курсора после FileWrite() и FrameFirst() перед FrameNext(). Я их добавил, но форварды не пишуться всё равно. Ко мне тоже приходила идея собирать данные в OnTesterPass(), но ничего не получалось. Работала только OnDeinit(). Я создавал файлы там-же и они разбрасывались по папкам агентов. Но форварды писались. Я отказался от этой идеи потому что в итоге нужен результат только лучшего прохода а не всех сразу. Попробую  пособирать данные в массив структур (если получится) и обработать данные в OnTesterDeinit(). Всё равно, спасибо вам большое за участие. Для меня было открытием, что в OnTesterPass() фреймы могут приходить пачками. Вот что у меня выдал ваш советник:


Я упущений не вижу, у меня модифицированный код работает на 100%. Выделенное желтым - заблуждение, надеюсь мой вариант запускался без исправлений, иначе работоспособность действительно могла пострадать. Перевод курсора в файле - лишний (позиция в файле запоминается), как и вызов FrameFirst (это имеет смысл только если нужно несколько раз пройтись по всем феймам, что не есть этот случай - здесь единожды получаем и читаем). Убрал специально.

PS. Попробуйте на разных билдах. У меня 2093.
 
Stanislav Korotky:

Я упущений не вижу, у меня модифицированный код работает на 100%. Выделенное желтым - заблуждение, надеюсь мой вариант запускался без исправлений, иначе работоспособность действительно могла пострадать. Перевод курсора в файле - лишний (позиция в файле запоминается), как и вызов FrameFirst (это имеет смысл только если нужно несколько раз пройтись по всем феймам, что не есть этот случай - здесь единожды получаем и читаем). Убрал специально.

PS. Попробуйте на разных билдах. У меня 2093.
Тестил на своём компе и сервере - не работает. FrameFirst и FileSeek действительно не нужны. Видимо билд 2085 не подходит. Новее не грузится. Откладываю до выхода нового билда. Большое вам спасибо за проявленный интерес.
 

Ну, вот, о чем я и говорил, в работе с фреймами много тонкостей, и новичкам будет  непросто.

Но Хорошее Пиво, как я погляжу, имеет достаточный опыт и квалификацию.

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

 
Georgiy Merts:

Ну, вот, о чем я и говорил, в работе с фреймами много тонкостей, и новичкам будет  непросто.

Но Хорошее Пиво, как я погляжу, имеет достаточный опыт и квалификацию.

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

У вас наверно тоже бета - версия нового билда или наоборот - старая. А на текущей (2085) - фреймов форвард тестов не существует, куда их не пиши. Ждём нового релиза.
 
Good Beer:
У вас наверно тоже бета - версия нового билда или наоборот - старая. А на текущей (2085) - фреймов форвард тестов не существует, куда их не пиши. Ждём нового релиза.

То есть, как "не существует" ???

У меня СЕГОДНЯ - прекрасно оптимизировались очередные ТС из Лиги, и с бек, и с форвард, с фреймами, все нормально было проанализировано и выбрано. Похоже, все-таки, тонкости работы с фреймами есть. И какие-то ты (давай на "ты"), видимо, не учел.  

 
Georgiy Merts:

То есть, как "не существует" ???

У меня СЕГОДНЯ - прекрасно оптимизировались очередные ТС из Лиги, и с бек, и с форвард, с фреймами, все нормально было проанализировано и выбрано. Похоже, все-таки, тонкости работы с фреймами есть. И какие-то ты (давай на "ты"), видимо, не учел.

Об этом уже написано выше. Если фреймы в форварде и пишуться, то OnTesterPass() на них не реагирует и FrameNext() не запускается. Stanislav Korotky написал свой код и он у меня не работал, и ещё другой тоже не работал. Я проверял его на двух разных компьютерах, с разной операционкой (даже уст. в разных странах) - результат один. Если я чего и не учёл - так это в настройках тестера. Я тестил в медленном и быстром режиме оптимизации.

 
Good Beer:

Об этом уже написано выше. Если фреймы в форварде и пишуться, то OnTesterPass() на них не реагирует и FrameNext() не запускается. Stanislav Korotky написал свой код и он у меня не работал, и ещё другой тоже не работал. Я проверял его на двух разных компьютерах, с разной операционкой (даже уст. в разных странах) - результат один. Если я чего и не учёл - так это в настройках тестера. Я тестил в медленном и быстром режиме оптимизации.

Ну, это и есть те самые тонкости.

Хотя, я не понял, разве OnTesterPass() должен реагировать на фреймы ? 

Вот моя функция OnTesterPasss():

void CExpert::MyOnTesterPass()
{
#ifdef __MQL5__

   ulong ulPass = ULONG_MAX;
   string strName;
   long lID = LONG_MAX;
   double dValue = EMPTY_VALUE;
   SInputComplexStats icsStatsArray[1];
   CEAPartsFactoryT* pepfFactory = NULL;
   string arrInputs[];
   uint uiInputsCount = NULL;

   ResetLastError();

   bool bRes = FrameNext(ulPass,strName,lID,dValue,icsStatsArray);
   
   if(bRes != true) Print("FrameNext Error: ",GetLastError());
   
   // _NOT_TESTED_IF(bRes != true);

   bRes = FrameInputs(ulPass,arrInputs,uiInputsCount);

   if(bRes != true) Print("FrameInputs Error: ",GetLastError());

   // _NOT_TESTED_IF(bRes != true);
   
   EAddFrameResult afrRes = m_fcFrameCollection.AddFrame(ulPass,strName,lID,dValue,arrInputs,icsStatsArray[0]);

   if(afrRes != AFR_OK) Print("AddFrameRes = ",afrRes);
   
   // _NOT_TESTED_IF(afrRes != AFR_OK);

   for(uint uiI=0; uiI<m_fpaEAFactories.Total(); ++uiI)
      {
      pepfFactory = m_fpaEAFactories.GetFactory(uiI);
      ASSERT_MYPOINTER(pepfFactory);
      pepfFactory.MyOnTesterPass(icsStatsArray[0]);
      };


#endif // __MQL5__   
};

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

Затем эта информация записывается в коллекцию фреймов.

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