Ну и что прикажете делать дальше?

 

Оптимизировал советник. Всё было нормально до выхода нового релиза: 

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

NJ      0       14:22:56.427    Core 8  common synchronization completed
ER      0       14:22:56.438    Core 5  common synchronization completed
KS      2       14:23:08.645    Core 3  genetic pass (0, 176) tested with error "critical runtime error 503 in OnTester function (zero divide, module Experts\SLTv1FD_2.21.ex5, file onTesterV21a.mqh, line 99, col 70)" in 0:00:04.805
GL      0       14:23:08.645    Core 3  genetic pass (0, 177) returned result -13780.30 in 0:00:03.603
HK      0       14:23:08.723    Core 3  genetic pass (0, 178) returned result -11367.48 in 0:00:03.792
PK      2       14:23:08.784    Core 5  genetic pass (0, 368) tested with error "critical runtime error 502 in OnTester function (array out of range, module Experts\SLTv1FD_2.21.ex5, file onTesterV21a.mqh, line 77, col 56)" in 0:00:01.465
RQ      2       14:23:08.784    Core 5  genetic pass (0, 369) tested with error "critical runtime error 503 in OnTester function (zero divide, module Experts\SLTv1FD_2.21.ex5, file onTesterV21a.mqh, line 99, col 70)" in 0:00:03.692
OL      2       14:23:08.784    Core 5  genetic pass (0, 370) tested with error "critical runtime error 503 in OnTester function (zero divide, module Experts\SLTv1FD_2.21.ex5, file onTesterV21a.mqh, line 99, col 70)" in 0:00:03.626
FG      2       14:23:08.784    Core 5  genetic pass (0, 371) tested with error "critical runtime error 503 in OnTester function (zero divide, module Experts\SLTv1FD_2.21.ex5, file onTesterV21a.mqh, line 99, col 70)" in 0:00:03.536
RN      2       14:23:08.819    Core 2  genetic pass (0, 64) tested with error "critical runtime error 502 in OnTester function (array out of range, module Experts\SLTv1FD_2.21.ex5, file onTesterV21a.mqh, line 77, col 56)" in 0:00:01.242
IO      0       14:23:08.819    Core 2  genetic pass (0, 65) returned result -16247.41 in 0:00:03.866
OK      0       14:23:08.819    Core 2  genetic pass (0, 66) returned result -5032.77 in 0:00:03.565
FE      0       14:23:08.819    Core 2  genetic pass (0, 67) returned result -14045.67 in 0:00:03.690
KN      0       14:23:09.047    Core 6  genetic pass (0, 224) returned result -1847.87 in 0:00:05.100
KE      2       14:23:09.047    Core 6  genetic pass (0, 225) tested with error "critical runtime error 502 in OnTester function (array out of range, module Experts\SLTv1FD_2.21.ex5, file onTesterV21a.mqh, line 77, col 56)" in 0:00:00.162
NF      2       14:23:09.047    Core 6  genetic pass (0, 226) tested with error "critical runtime error 503 in OnTester function (zero divide, module Experts\SLTv1FD_2.21.ex5, file onTesterV21a.mqh, line 99, col 70)" in 0:00:03.588
GR      2       14:23:09.047    Core 6  genetic pass (0, 227) tested with error "critical runtime error 503 in OnTe

Думаю, ладно, посмотрю что делается в этих проходах. Добавил распринтовку....

А дальше что?

Кто-нибудь видит хоть один ошибочный проход в результатах оптимизации? Что запускать в одиночном тесте для поиска ошибки? 


Повторюсь, на билде 2007 ничего подобного не наблюдалось!

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

Оптимизировал советник. Всё было нормально до выхода нового релиза: 

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

Думаю, ладно, посмотрю что делается в этих проходах. Добавил распринтовку....

А дальше что?

Кто-нибудь видит хоть один ошибочный проход в результатах оптимизации? Что запускать в одиночном тесте для поиска ошибки? 


Повторюсь, на билде 2007 ничего подобного не наблюдалось!

Вам же написали имена модулей, номера строк и позицию курсора, где появляются ошибки - деление на ноль и выход за пределы массивов. Исправляйте. 
 
Artyom Trishkin:
Вам же написали имена модулей, номера строк и позицию курсора, где появляются ошибки - деление на ноль и выход за пределы массивов. Исправляйте. 

Я читать ещё не разучился )))

Тут вопрос, в принципе, другой. Повторю. 

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

И если с делением на ноль всё понятно, хотя его там быть не должно в принципе, то с ошибкой массива не понятно ничего.

И ещё вопрос, который Вы почему то игнорируете: почему на предыдущем стабильном релизе этих проблем не было?

P.S.

Я могу предположить источник проблем - это не вызов определённой функции на новом баре. Но причину найти... Разве это моя ошибка, если на одних проходах всё нормально отрабатывает, а на других нет? Не говоря уже о том, что до обновления вообще проблем не было!

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

Я читать ещё не разучился )))

Тут вопрос, в принципе, другой. Повторю. 

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

И если с делением на ноль всё понятно, хотя его там быть не должно в принципе, то с ошибкой массива не понятно ничего.

И ещё вопрос, который Вы почему то игнорируете: почему на предыдущем стабильном релизе этих проблем не было?

Если есть массив, о котором вы точно знаете, и есть индекс массива, который вы отправляете за пределы массива, то об этом вы должны же иметь представление - вот вам и направление поиска.
О том, почему раньше работало, а теперь - нет, я вам не подскажу. Но исправьте свои ошибки - у вас есть точное на них указание, и должно заработать везде.
Для поиска ошибки не обязательно тест запускать. Достаточно просто быть внимательным в собственном коде.
 
Сергей Таболин:
Попробуйте через функцию FrameInputs узнать значения параметров для выбранного прохода.  Возможно она и без фрэймов работает.
 
Alexey Navoykov:
Попробуйте через функцию FrameInputs узнать значения параметров для выбранного прохода.  Возможно она и без фрэймов работает.

Я с фреймами не дружу (((

Artyom Trishkin:
Если есть массив, о котором вы точно знаете, и есть индекс массива, который вы отправляете за пределы массива, то об этом вы должны же иметь представление - вот вам и направление поиска.
О том, почему раньше работало, а теперь - нет, я вам не подскажу. Но исправьте свои ошибки - у вас есть точное на них указание, и должно заработать везде.
Для поиска ошибки не обязательно тест запускать. Достаточно просто быть внимательным в собственном коде.

Вот фрагмент кода, с комментариями, где появляется ошибка:

//+------------------------------------------------------------------+
//|                                                     onTester.mqh |
//|                                     Copyright 2019, Tabolin S.N. |
//|                           https://www.mql5.com/ru/users/vip.avos |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, Tabolin S.N."
#property link      "https://www.mql5.com/ru/users/vip.avos"
//+------------------------------------------------------------------+
#ifndef  GS
   #define           GS    1.618
#endif
#ifndef  PI
   #define  PI                3.14159
#endif 
//+------------------------------------------------------------------+
CAccountInfo               my_tst_Account;            // доступ к свойствам текущего открытого торгового счета
//+------------------------------------------------------------------+
sinput   string            str999                     = "======";                   // <<< Оптимизация Тестирование >>>
sinput   double            max_equity_loss            = 10;                         // Максимальная просадка в % от начального баланса
sinput   datetime          optimization_end_date      = D'2019.01.01';              // Конечная дата оптимизации
sinput   int               number_evaluation_periods  = 52;                         // Количество периодов оценки
//+------------------------------------------------------------------+
         datetime          start_time        = TimeCurrent();
         datetime          period_check      = (optimization_end_date - start_time) / number_evaluation_periods;  // Период проверки баланса
const    datetime          start_time_const  = start_time;
         datetime          next_time;
         double            st_bal            = my_tst_Account.Balance();
         double            next_st_bal       = 0.0;
         double            balance_arr[];
//+------------------------------------------------------------------+
// Эта функция вызывается на новом баре и заполняет массив balance_arr[]
// В итоге размер массива равен number_evaluation_periods  = 52
// Нулём быть не может
void time_Attitude()
{
   next_time = start_time + period_check;
   if(TimeCurrent() <= next_time) return;
   
   //if(st_bal == my_tst_Account.Balance()) return;
   
   if(next_st_bal == 0.0)
   {
      ArrayResize(balance_arr,2);
      balance_arr[0] = NormalizeDouble(st_bal,2);
   }
   next_st_bal    = my_tst_Account.Balance();
   //Print("1/ ArraySize(balance_arr) = "+IntegerToString(ArraySize(balance_arr)));
   balance_arr[ArraySize(balance_arr)-1] = NormalizeDouble(next_st_bal,2);
   ArrayResize(balance_arr,ArraySize(balance_arr)+1);
   //Print("2/ ArraySize(balance_arr) = "+IntegerToString(ArraySize(balance_arr)));
   start_time     = next_time;
   st_bal         = next_st_bal;
   
   return;
}
//+------------------------------------------------------------------+
double ratioTrades2Time(double trd)
{
   datetime duration = TimeCurrent() - start_time_const;
   
   return(NormalizeDouble((double)trd / ((double)duration / (double)PeriodSeconds(PERIOD_W1)),8));
}
//+------------------------------------------------------------------+
double OnTester()
{
   double   equity_dd_percent             = TesterStatistics(STAT_EQUITY_DDREL_PERCENT);
   if(equity_dd_percent > 0.0)
   {
      equity_dd_percent = 100.0 / equity_dd_percent;
   }
   else     equity_dd_percent    = 1.0;
   
   double   param                         = 0.0;
   double   profit                        = TesterStatistics(STAT_PROFIT);
   double   stability                     = 0.0;
   int      balance_arr_size              = ArraySize(balance_arr) - 1;
   int      alpha_size                    = balance_arr_size - 1;
   int      beta_size                     = alpha_size - 1;
   double   trade2time                    = ratioTrades2Time(TesterStatistics(STAT_TRADES));
   double   max_balance                   = balance_arr[0]; // здесь появляется ошибка переполнения
//+-------------------   
   double   series_signific               = 1.0;
   double   signific_increase             = 0.01;
   double   signific[];
   double   signific_add[];
   
   ArrayResize    (signific               ,balance_arr_size    );
   ArrayInitialize(signific               ,0.0                 );
   ArrayResize    (signific_add           ,balance_arr_size    );
   ArrayInitialize(signific_add           ,0.0                 );
   
   signific[0]                            = series_signific;
   for(int i = 1; i < balance_arr_size - 1; i++) signific[i]      = signific[i-1] + series_signific;
   
   signific_add[0]                        = signific_increase / 5;
   signific_add[1]                        = signific_increase / 5;
   for(int i = 2; i < balance_arr_size - 1; i++) signific_add[i]  = signific_add[i-1] + signific_add[0];
//+-------------------   
   double   balance_max                   = balance_arr[ArrayMaximum(balance_arr)];
   double   balance_min                   = balance_arr[ArrayMinimum(balance_arr)];
   //double   ratio_min_max                 = balance_min / balance_max;
   double   ratio_min_max                 = MathAbs(balance_arr_size / (balance_arr[balance_arr_size-1] - balance_arr[0])); // здесь ошибка деления на ноль
// но это практически не возможно в нормальных условиях
// это возможно только, если не вызывается функция time_Attitude()
//+-------------------   

Подскажите, где невнимательность? Ну и почему эта "невнимательность" проявилась только в этом релизе?

 
Сергей Таболин: здесь ошибка деления на ноль// но это практически не возможно в нормальных условиях

где то неинициализированная переменная, чтобы найти баг, сделайте проверку в подозрительных участках кода

double tmp = (balance_arr[balance_arr_size-1] - balance_arr[0]);
double   ratio_min_max                 = tmp==0.0 ? MathAbs(balance_arr_size / DBL_MIN ) : MathAbs(balance_arr_size / tmp );


когда локализуете ошибку, тогда можно что то думать, как раньше работало и как сейчас

ЗЫ: вроде в новом релизе МТ5 был анонс новых функций для работы с балансом счета в тестере, возможно инициализация баланса стала доступна после OnOnit(), но это только гадать, проверять нужно 

 
Igor Makanu:

где то неинициализированная переменная, чтобы найти баг, сделайте проверку в подозрительных участках кода


когда локализуете ошибку, тогда можно что то думать, как раньше работало и как сейчас

Я попробую, спасибо.

Но пока ещё вопрос по вызову функции:

   if(new_bars > 0)
   {
      if(MQLInfoInteger(MQL_OPTIMIZATION) || MQLInfoInteger(MQL_TESTER)) time_Attitude();
...........

Возможна ли проблема в этом?

 
Igor Makanu:

ЗЫ: вроде в новом релизе МТ5 был анонс новых функций для работы с балансом счета в тестере, возможно инициализация баланса стала доступна после OnOnit(), но это только гадать, проверять нужно 

Тогда бы вообще не работало, а так ведь есть проходы, которые отрабатываются нормально...

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

Тогда бы вообще не работало, а так ведь есть проходы, которые отрабатываются нормально...

Может у кого остался билд 2007? А то я сдуру вчера пообновлял все терминалы... (((

 

Лично я вижу, что при первом же вызове OnTester() мы получаем размер неинициализированного массива balance_arr[], а он может быть любым.

Так делать нельзя. Неудивительно, что в одном билде - все работает, там этот "любой" размер, скажем, равен десяти, а сейчас (он ведь "любой") - может быть равен нулю.