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

 
Georgiy Merts:

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

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

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

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

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

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

OnTesterPasss() только для того и существует, чтобы реагировать на фреймы. Я использовал почти такую же обработку фреймов как у вас. Дело не в этом, а втом как вы заставляете метод MyOnTesterPass() реагировать на новый фрейм. Да и это не нужно - лучше сделать всё в OnTesterDeinit(). Я обновился до бета-билда 2151. Может быть всё будет работать, но без мультитестера толку от этого мало.

 

Ну, вот поставил последний бета-билд 2155. Стало всё наоборот: В OnTesterDeinit() в режиме извлекаются только результаты форвард-теста. При выключенном форварде результаты бэк-теста извлекаются нормально. В OnTesterPass() всё работает в любом режиме, но собирать там фреймы на лету не удобно и чревато потерями.

Вот результаты извлечения из фреймов в разных функциях:

содержымое фреймов

Очевидно, что фремы существуют как для форварда, так и для бэка; но в OnTesterDeinit() извлекается только форвард.

3-й столбик - значение  MQLInfoInteger(MQL_FORWARD).

Вот кусок кода, где шло извлечение:

void OnTesterDeinit()
  {

////---
   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,__FUNCTION__,fr_name,DoubleToString(frm_val,2),DoubleToString(rep_data[0],2),"pass_num=",pass_num);
         FileSeek(filehandle,0,SEEK_END);//Курсор в конец файла
        }//while
      FileClose(filehandle);
     }
   else Print(__FUNCTION__" Операция FileOpen неудачна, ошибка ",GetLastError());
   if(filehandle!=INVALID_HANDLE)
     {
      FileClose(filehandle);
     }//
   ChartClose();//Закрыть чарт оптимизации  
  }//OnTesterDeinit()

Для сравнения - прогон на билде 2085 с форвардом

forv_2085

Вывод: работа над тестером молчаливо ведётся, но до конца не доведена. Жду релиз с нетерпением. Бету - под снос!

 
Оптимизация дело хорошее, правда чем она отличается от подгонки под историю
 
Good Beer:

Ну, вот поставил последний бета-билд 2155. Стало всё наоборот: В OnTesterDeinit() в режиме извлекаются только результаты форвард-теста. При выключенном форварде результаты бэк-теста извлекаются нормально. В OnTesterPass() всё работает в любом режиме, но собирать там фреймы на лету не удобно и чревато потерями.

Вот результаты извлечения из фреймов в разных функциях:

Очевидно, что фремы существуют как для форварда, так и для бэка; но в OnTesterDeinit() извлекается только форвард.

3-й столбик - значение  MQLInfoInteger(MQL_FORWARD).

Вот кусок кода, где шло извлечение:

Для сравнения - прогон на билде 2085 с форвардом


Вывод: работа над тестером молчаливо ведётся, но до конца не доведена. Жду релиз с нетерпением. Бету - под снос!

Ну, я не знаю... У меня хоть раньше, хоть сейчас - все фреймы вроде как нормально собираются, бек-форвард пары организуются... Просто, как я уже написал, я их различаю по времени запуска. Получается надежнее.

 
Vladimir Baskakov:
Оптимизация дело хорошее, правда чем она отличается от подгонки под историю
Это те же монеты, но только в профиль. Здесь обсуждается форвард-оптимизация, когда результат подгонки определяется на последующем периоде. В результате определяется 1) Прибыльность советника; 2) Периоды подгонки и торговли для с оптимальным соотношением прибыль/убыток; 3) Совершенствуется алгоритм советника. Я считаю, что лучше еще ничего не придумали. Всякие там математические вычисления и монтекарлы не отражают структуру живого рынка.
 
Georgiy Merts:

Ну, я не знаю... У меня хоть раньше, хоть сейчас - все фреймы вроде как нормально собираются, бек-форвард пары организуются... Просто, как я уже написал, я их различаю по времени запуска. Получается надежнее.

Если не починят рот, для приёма пищи придётся искать альтернативные пути.
 
Здравствуйте.У меня такой вопрос советник работал хорошо полтора года,приносил прибыль.А сейчас уже полтора месяца не открыл ни одной сделки.Такое бывает с советниками?Может его надо оптимизировать?
 
Leon_28:
Здравствуйте.У меня такой вопрос советник работал хорошо полтора года,приносил прибыль.А сейчас уже полтора месяца не открыл ни одной сделки.Такое бывает с советниками?Может его надо оптимизировать?

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

1) Проверьте разрешение торогвли: рядом со значком советника в левом верхнем углу графика должен быть зеленый кружочек.

2) Прочитайте журнал советника в разделе "эксперты": ести ли ошибки и сообщения от советника или брокера.

3) Выставтьте небольшой период контроля (например мувинг с периодом в 10) если такой есть, если нет - на маленький ТФ (напр. М-1) и минимальный риск. В настройках  тестера "только цены открытия" и оптимизация "отключена". Форвард - отключить. Сделайте прогон на периоде оптимизации в 1 неделю. И смотрите: открываются ли сделки и ошибки в журнале. Если проблема не нашлась - теребите изготовителя вашего советника. Может быть всё что угодно.

Тестировать имеет смысл только полностью рабочий советник.

 

Вышел новый билд 2170. "Исправлены ошибки и оптимизирована работа с фреймами" написано в п. 24 в анонса. Посмотрим. Я тоже пересмотрел советник для теста работы с фреймами. Были там места, дающие возможность записи одних строк поверх других. Удалил записи данных "сразу в файл" потому что функция FileWrite() не работает в функциях OnInit(), OnDeinit() и OnTester(), о чём в документации не предупредили.

Вот и код:

input double param_1=1.0;//Тестовый параметр
int filehandle;

int OnTesterInit()
  {
   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);

if(filehandle!=INVALID_HANDLE)
{
string fram_name="back_test";
if(MQLInfoInteger(MQL_FORWARD)==1)fram_name="forward";
FileSeek(filehandle,0,SEEK_END);//Курсор в конец файла
FileWrite(filehandle,__FUNCTION__,"mode=",fram_name,"файл создан");
}// filehandle==true
   return INIT_SUCCEEDED;
  }//OnTesterInit()
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--Функция FileWrite()не работает
   return(INIT_SUCCEEDED);
  }//OnDeinit
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   //--Функция FileWrite()не работает
  }//OnDeinit
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double OnTester()
  {
   string fram_name="back_test";
//---
   static long pass_calk;
   pass_calk++;   
//---Переменные для фрейма
   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(): Фрейм не создан");  
   return(pass_result[0]);
  }//OnTester()
void OnTesterPass()
  {
  static int frm_count=0;
  frm_count++;
   string mode="back_test";
   if(MQLInfoInteger(MQL_FORWARD)==1)mode="forward";
   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)
     {
      string fram_name="back_test";
      if(MQLInfoInteger(MQL_FORWARD)==1)
         fram_name="forward";
      //---
      while(FrameNext(pass_num,fr_name,publ_id,frm_val,rep_data)==true)
        {
         FileSeek(filehandle,0,SEEK_END);//Курсор в конец файла
         FileWrite(filehandle,__FUNCTION__,"mode=",mode,"fr_name=",fr_name,"frm_val=",DoubleToString(frm_val,2),"rep_data=",DoubleToString(rep_data[0],2),"pass_num=",frm_count);
        }//while
     }
   else
      Print(__FUNCTION__" Операция FileOpen неудачна, ошибка ",GetLastError());
  }//
//+------------------------------------------------------------------+
//| TesterDeinit function                                            |
//+------------------------------------------------------------------+
void OnTesterDeinit()
  {
////---
   string mode="back_test";
   if(MQLInfoInteger(MQL_FORWARD)==1)mode="forward";
   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)
     {
      //--- 
      if(FrameFirst()==true)
        {
         int str_count=0;
         while(FrameNext(pass_num,fr_name,publ_id,frm_val,rep_data)==true)
           {
            str_count++;
            FileSeek(filehandle,0,SEEK_END);//Курсор в конец файла
            FileWrite(filehandle,__FUNCTION__,"mode=",mode,"fr_name=",fr_name,"frm_val=",DoubleToString(frm_val,2),"rep_data=",DoubleToString(rep_data[0],2),"pass_num=",str_count);
           }//while
        }//FrameFirst()==true
      else
        {
         FileSeek(filehandle,0,SEEK_END);//Курсор в конец файла
         FileWrite(filehandle,__FUNCTION__," Ошибка функции FrameFirst");
        }
      FileClose(filehandle);
     }
   else
      Print(__FUNCTION__" Операция FileOpen неудачна, ошибка ",GetLastError());
   ChartClose();//Закрыть чарт оптимизации
  }//OnTesterDeinit()

Результат прогона с включенным форвардом:

форвард тест

Mode - это показатель MQLInfoInteger(MQL_FORWARD) внутри текущей функции, а fr_name - показатель записанный во фрейм во время его создания в функции OnTester(). pass_num - это счётчик фреймов. Остальное очевидно.

Получается что было создано 10 фреймов - по 5 в форварде и бэк-тесте, а в OnTesterDeinit() пришло только 5 с форвардом. Куда делись фреймы бек-теста?  В общем, еще не конец. Но с этим уже можно работать, хотя в OnTesterPas() фреймы при обработке будут теряться, особенно в облачных агентах. Обратите внимание, что признак MQLInfoInteger(MQL_FORWARD) работает только в OnTester() - везде mode= back_test.

При отключённом форварде фреймы в OnTesterDeinit() приходят в полном объёме:

бэктест

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

 
Good Beer:

Очевидно, что фремы существуют как для форварда, так и для бэка; но в OnTesterDeinit() извлекается только форвард.

Воспроизвели описанную проблему. Исправляем

Причина обращения: