Пропуски расчетов при тестировании (оптимизации) на многоядерной сети. Кто встречал? Как бороться? - страница 5

 
Natalja Romancheva:

Как искать причину проблемы - непонятно. :-(

Без воспроизведения - никак.

 

В настоящий момент проблема более не проявлялась.

Для облегчения анализа подобной проблемы в будущем сделано следующее.

1. Оптимизация проводится "по максимуму пользовательского критерия" (уже использовалось на момент обнаружения проблемы).

2. В качастве пользовательского критерия выбрано "прибыльность" - "profit factor" (уже использовалось на момент обнаружения проблемы).

3. Плановые прерывания тестирования выполняются со специальным кодом деинициализации 782.

      {if(условие прерывания)
      {
         OnDeinit(782);
         ExpertRemove();
      }}//if(условие прерывания)

Который обрабатывается в OnDeinit():

//=========================================================================================== MQL4/5 ===
//  OnDeinit()  - Деинициализация советника. Подготовка к завершению работы.
//------------------------------------------------------------------------------------------------------
void OnDeinit(const int reason)
{
   string text="";
   {switch(reason)
   {
      case 782:
         text="[782] Спецкод.";TestRes=0.0;break;//Для прерывания и обнуления результата тестирования
      default:text="Another reason";
   }}//switch(reason)
   if(PrintDeinit)Print(" Deinit reason [",reason,"] >> "+text);
   return;
}//OnDeinit()

Сигнальная переменная TestRes устанавливается в 1.0 при инициализации советника и сбрасывается в 0.0 при деинициализации по плановому прерыванию работы.

Переменная TestRes используется при расчете результата тестирования:

//=========================================================================================== MQL4/5 ===
//    OnTester
//------------------------------------------------------------------------------------------------------
double OnTester()
{
   double Testr1=0;
   switch(OnTesterMode){
      case   0:  Testr1=TesterStatistics(STAT_PROFIT_FACTOR);break;
      default:    Testr1=0.0;break;
   }//switch(OnTesterMode)
   return((TestRes<=0.1)?(0.0):(((Testr1>0.0)&&(Testr1<999999.0))?(Testr1):(-1.0)));
}//OnTester

Теперь имеем следующие возможные значения оптимизируемого параметра:

0 .. 999999 - нормальное завершение прогона с расчетом результата.

0                - нормальное прерывание работы, результат не рассчитан.

-1               - что-то пошло не так, внеплановое прерывание работы (ожидается при повторении проблемы).

 
Natalja Romancheva:

3. Плановые прерывания тестирования выполняются со специальным кодом деинициализации 782.

Который обрабатывается в OnDeinit():

Это самообман - OnDeinit будет вызван дважды. Вызвать OnDeinit можно сколько угодно раз самому. А вот создать Deinit-событие, по которому сработает OnDeinit - это только ExpertRemove в Тестере. И он свой Reason сгенерирует, а не кастомный.

 
примерно такая же ситуация была. поднимал тему не чего врозумительного не ответили
В чем же дело?
В чем же дело?
  • 2018.04.19
  • www.mql5.com
один и тот же советник 1 вариант оптимизировал по отдельности 2 параметра из 3 затем последний и получил результат вот такой фактор востановления...
 
fxsaber:

Это самообман - OnDeinit будет вызван дважды. Вызвать OnDeinit можно сколько угодно раз самому. А вот создать Deinit-событие, по которому сработает OnDeinit - это только ExpertRemove в Тестере. И он свой Reason сгенерирует, а не кастомный.

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

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