Чем заменить INIT_PARAMETERS_INCORRECT ? Найдено решение )))

 

Нашёл ответ на свой же вопрос в теме:

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Не для разработчиков МТ! Чем заменить INIT_PARAMETERS_INCORRECT ?

Сергей Таболин, 2018.07.10 15:57

Столкнулся с такой проблемой: по логике программы существует необходимость отсеять не допустимые варианты вызова функций. Использую для этого INIT_PARAMETERS_INCORRECT. Но генетическая оптимизация стопориться практически сразу. Разработчиков аж бесят вопросы касающиеся этой ситуации. Советуют учить генетический анализ и т.п. и т.д..

А на кой мне это надо? Я, как пользователь, хочу получить результат, а как оно там работает - мне глубоко фиолетово.

Так вот, пример на трёх функциях 1, 2 и 3. 0 - это не использовать.

В цепочке функции не должны повторяться и между функциями не должно быть 0-я (иначе возможны повторения). 

Пример допустимых цепочек:

  • 100
  • 120
  • 130
  • 123
  • 132
  • 2..
  • 3..

Пример не допустимых цепочек:

  • 010
  • 001
  • 110
  • 101
  • 111
  • 121
  • 122
  • 131
  • 133
  • 112
  • 113
  • 102
  • 103
  • 2..
  • 3..
Как видно, недопустимых цепочек на порядок больше чем допустимых. Как произвести выборку? Чем заменить INIT_PARAMETERS_INCORRECT ? Куда копать?

Всё оказалось довольно просто. Достаточно перенести проверку на недопустимые параметры из OnInit() в OnTick()

bool                 check_init              = false;                // флаг проверки входных параметров
..........
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
//--- пропустить бесполезные проходы оптимизации
//*
   if(!check_init && (MQLInfoInteger(MQL_OPTIMIZATION) || MQLInfoInteger(MQL_TESTER)))
   {
      if(period_HMA7C == 0 && move_profit)                                 ExpertRemove();
      if(period_HMA7C == 0 && move_stop)                                   ExpertRemove();
      if(period_HMA7C == 0 && shift_correction_HMA7C != 5)                 ExpertRemove();
      check_init = true;
   }
//*/ 
//+------------------------------------------------------------------+ 

Проверено! Работает. Генетика не валится )))

 
ExpertRemove

Работает ли это для индикатора?

Завершение OnInit() значением INIT_FAILED, не выгружает индикатор с графика, в МТ4 работает. 

 
Farkhat Guzairov:

Работает ли это для индикатора?

Завершение OnInit() значением INIT_FAILED, не выгружает индикатор с графика, в МТ4 работает. 

Это нужно для оптимизации с генетическим алгоритмом. При чем здесь индикатор?

 
Andrey Khatimlianskii:

Это нужно для оптимизации с генетическим алгоритмом. При чем здесь индикатор?

Рад, что это нужно для работы эксперта с генетическим алгоритмом. 

В моем случае это Индикатор, нужно чтобы индикатор при определенных условиях выгружался полностью, как это реализовано в MT4, на сколько понял функция ExpertRemove работает только для эксперта. 

 
Сергей Таболин:

Проверено! Работает. Генетика не валится )))

https://www.mql5.com/ru/docs/common/testerstop

Есть ещё такой вариант

Документация по MQL5: Общие функции / TesterStop
Документация по MQL5: Общие функции / TesterStop
  • www.mql5.com
Функция TesterStop() предназначена для штатного досрочного завершения работы советника на агенте тестирования – например, при достижении заданного количества убыточных сделок или заданного уровня просадки. Вызов TesterStop() считается нормальным завершением тестирования, и поэтому будет вызвана функция OnTester() с отдачей тестеру стратегий...
 
Igor Zakharov:

https://www.mql5.com/ru/docs/common/testerstop

Есть ещё такой вариант

Судя по описанию, этот вариант должен работать быстрее. Спасибо.

 
Farkhat Guzairov:

Работает ли это для индикатора?

Завершение OnInit() значением INIT_FAILED, не выгружает индикатор с графика, в МТ4 работает. 

https://www.mql5.com/ru/docs/chart_operations/chartindicatordelete

Документация по MQL5: Операции с графиками / ChartIndicatorDelete
Документация по MQL5: Операции с графиками / ChartIndicatorDelete
  • www.mql5.com
//|                                    Demo_ChartIndicatorDelete.mq5 | //|                        Copyright 2011, MetaQuotes Software Corp. | //|                                              https://www.mql5.com | //| Custom indicator initialization function                         |                           ...
 

Большое спасибо! Искал в справочнике, но даже не подумал что это может быть в этом разделе.

 

В новом билде 2085 к этому решению (костылю) необходимо прикрутить ещё один костыль. Правда он нужен только, если нужно делать какие-то расчёты в OnTester() и необходимо сразу прекратить тест.

Сразу - это громко сказано, тем не менее.

Итак 

bool                 check_init              = false;                // флаг проверки входных параметров
bool                 tester_stop             = false;                // флаг проверки выхода по ExpertRemove

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
//--- пропустить бесполезные проходы оптимизации
//*
   if(!check_init && (MQLInfoInteger(MQL_OPTIMIZATION) || MQLInfoInteger(MQL_TESTER)))
   {
      if(недопустимый параметр)
      {
         tester_stop = true;
         ExpertRemove();
      }
      
      check_init  = true;
   }
//*/
   if(!IsStopped()) // в принципе можно использовать и if(!tester_stop)
   {
      тут рабочий код советника
   }
}
//+------------------------------------------------------------------+
double OnTester()
{
   if(tester_stop) return(нужное вам значение);

   остальной код
}

К сожалению TesterStop() тут уже не работает, ибо требует чтобы тест уже прошёл некоторый_неизвестный процент. Выдаёт такое

2019.06.16 18:49:25.464 Core 1  TesterStop() called on 0% of testing interval
 

ПОПРАВКА.

Можно сделать несколько элегантнее, спасибо Slava.

bool                 tester_stop             = false;                // флаг проверки выхода по TesterStop
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
//--- пропустить бесполезные проходы оптимизации
   if(MQLInfoInteger(MQL_OPTIMIZATION) || MQLInfoInteger(MQL_TESTER))
   {
      if(недопустимый параметр) tester_stop = true;
      ..........
   }
//+------------------------------------------------------------------+
.............
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
//--- пропустить бесполезные проходы оптимизации
   if(tester_stop)
   {
      TesterStop();
      return;
   }
......................
}
//+------------------------------------------------------------------+
double OnTester()
{
   if(tester_stop) return(-9999999.99); // возвращать можно любое значение
.................   
}

TesterStop() работает. А то, что он пишет в журнал при одиночном тесте - просто информация о том, что теста, как такового не было. На работу никак не влияет.

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