Ну и что прикажете делать дальше? - страница 2

 
Georgiy Merts:

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

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

Как не видите?

         double            balance_arr[];
//+------------------------------------------------------------------+
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);
   }
И далее он дополняется. А в OnTester уже идёт обращение к полностью заполненному массиву...
 
      if(MQLInfoInteger(MQL_OPTIMIZATION) || MQLInfoInteger(MQL_TESTER)) time_Attitude();

К проблеме отношения не имеет.

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

К проблеме отношения не имеет.

Нет.
Сейчас баланс может быть нулевым. Я при тестировании один раз нарвался на это - не открывались позиции. Гляжу, а баланс нулевой...
 
Artyom Trishkin:
Нет.
Сейчас баланс может быть нулевым. Я при тестировании один раз нарвался на это - не открывались позиции. Гляжу, а баланс нулевой...

)))

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

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

)))

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

Проверил. Оптимизация начинается с "правильным" балансом.

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

Как не видите?

И далее он дополняется. А в OnTester уже идёт обращение к полностью заполненному массиву...

Я вижу функцию time_Attitude(), и не вижу, чтобы она обязательно вызывалась перед OnTick()

Вижу типичную опасность возникновения неинициализированных переменных, что, видимо, и происходит.

Ты говоришь, что "эта функция вызывается на новом баре" - но ведь первая функция, которая на нем вызывается - это именно OnTick()

Сергей, на мой взгляд, следует убедиться в том, что эта функция обязательно вызывается перед OnTick() - скорее всего, в OnInit(), еще ДО прихода первого бара.

И, давай на "ты", что ты мне "выкаешь"...

 
Georgiy Merts:

Я вижу функцию time_Attitude(), и не вижу, чтобы она обязательно вызывалась перед OnTick()

Вижу типичную опасность возникновения неинициализированных переменных, что, видимо, и происходит.

Ты говоришь, что "эта функция вызывается на новом баре" - но ведь первая функция, которая на нем вызывается - это именно OnTick()

Сергей, на мой взгляд, следует убедиться в том, что эта функция обязательно вызывается перед OnTick() - скорее всего, в OnInit(), еще ДО прихода первого бара.

И, давай на "ты", что ты мне "выкаешь"...

Давай на "ты" )))

Вот так сейчас вызывается эта функция:

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
//--- пропустить бесполезные проходы оптимизации
//*
   if(!check_init && (MQLInfoInteger(MQL_OPTIMIZATION) || MQLInfoInteger(MQL_TESTER)))
   {
      if(period_HMA7C == 0 && move_profit)                                                            TesterStop();
      if(period_HMA7C == 0 && move_stop)                                                              TesterStop();
      if(period_HMA7C == 0 && shift_correction_HMA7C != 5)                                            TesterStop();
      if(indent_channel_line_a0 == 0.0 && indent_channel_line_a4 != 0.0)                              TesterStop();
      if(indent_channel_line_a4 == 0.0 && indent_channel_line_a0 != 0.0)                              TesterStop();
      if((stop_loss_buy > 0 && stop_loss_buy < 700) || (stop_loss_sell > 0 && stop_loss_sell < 700))  TesterStop();
      check_init = true;
   }
//*/
//----------------------------------------------------------------------------------------------
   new_bars    = current_chart.isNewBar();   // проверить появление нового бара
//----------------------------------------------------------------------------------------------
   //--- проверка установленных ордеров
   if(!pos_get.order_set && my_Position.Select(Symbol()) && my_Position.Symbol()==Symbol())
   {
      ..........
   }
   //--- очистка удалённых вручную и по стопу
   if(pos_get.order_set && !my_Position.SelectByTicket(pos_get.ticket))
   {
      ..........
   }
//----------------------------------------------------------------------------------------------
   if(new_bars > 0)
   {
      if(MQLInfoInteger(MQL_OPTIMIZATION) || MQLInfoInteger(MQL_TESTER)) time_Attitude();
      trading_signals buy_sell = calculation_Trading_Signals();
      ..................

Честно говоря я не вижу смысла вызывать эту функцию из OnInit. Но, возможно, ты прав. Сейчас организую.

 

Добавил вызов функции в OnInit и отредактировал саму функцию:

void time_Attitude()
{
   next_time = start_time + period_check;
   
   if(next_st_bal == 0.0)
   {
      ArrayResize(balance_arr,2);
      balance_arr[0] = NormalizeDouble(st_bal,2);
      next_st_bal    = st_bal;
   }

   if(TimeCurrent() <= next_time) return;
   
   next_st_bal    = my_tst_Account.Balance();
   balance_arr[ArraySize(balance_arr)-1] = NormalizeDouble(next_st_bal,2);
   ArrayResize(balance_arr,ArraySize(balance_arr)+1);
   start_time     = next_time;
   st_bal         = next_st_bal;
   
   return;
}

Как я и предполагал - ничего не изменилось ((

 

Нашёл я причину этого безобразия.

Дело вот в этом:

//--- пропустить бесполезные проходы оптимизации
//*
   if(!check_init && (MQLInfoInteger(MQL_OPTIMIZATION) || MQLInfoInteger(MQL_TESTER)))
   {
      if(period_HMA7C == 0 && move_profit)                                                            TesterStop();
      if(period_HMA7C == 0 && move_stop)                                                              TesterStop();
      if(period_HMA7C == 0 && shift_correction_HMA7C != 5)                                            TesterStop();
      if(indent_channel_line_a0 == 0.0 && indent_channel_line_a4 != 0.0)                              TesterStop();
      if(indent_channel_line_a4 == 0.0 && indent_channel_line_a0 != 0.0)                              TesterStop();
      if((stop_loss_buy > 0 && stop_loss_buy < 700) || (stop_loss_sell > 0 && stop_loss_sell < 700))  TesterStop();
      check_init = true;
   }
//*/

Оказывается в новом релизе после TesterStop() запускается ещё и OnTester(), хотя, по уму, запускаться не должен.

Естественно, никакие данные не подготавливаются, вот и получается чёрте что.

Косяк МТ 2085.

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

Нашёл я причину этого безобразия.

Дело вот в этом:

Оказывается в новом релизе после TesterStop() запускается ещё и OnTester(), хотя, по уму, запускаться не должен.

Естественно, никакие данные не подготавливаются, вот и получается чёрте что.

Косяк МТ 2085.

Извиняюсь. В описании как раз и написано, что после вызывается OnTester(). (((

Приходится ещё и там делать проверки. Попробую заменить на ExpertRemove()...

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