Ошибки, баги, вопросы - страница 3147

Roman #:

Спасибо, проглядел единичку.

Но теперь индикаторный буфер IndBuff[i] мозги делает, array out of range.
Что ему надо? Почему он не аллоцируется под начальный i=limit ?

   //Проверка и расчёт количества просчитываемых баров
   int limit = rates_total-prev_calculated;

   if(limit==1)
     limit=2;
   //-------------------------------------------------------------------------
   //Расчёт индикатора
   for(int i=limit-1; i>=0; i--)
   {
      c = iClose(_Symbol,PERIOD_CURRENT,i);      
      
      IndBuff[i] = c;  //на этой строке array out of range

   }
Vitaly Muzichenko #:

Так на каждом баре заходит в цикл, а нужно на каждом тике.

Раньше работало так

для тиков  i>=0,

для баров i>0

Сейчас фиг поймёшь, как с буфером работать.

А всё потому, что буфер IndBuff не аллоцируется до rates_total + 1
И ArrayResize к нему не применим.
Сломали for конструкцию. Теперь через if-ы всё городить?

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total,       
                 const int prev_calculated,   
                 const int begin,             
                 const double& price[])      
{

   ArraySetAsSeries(IndBuff, true);
   
   //-------------------------------------------------------------------------
   //Проверка и расчёт количества просчитываемых баров
   int limit = rates_total-prev_calculated;
   
   if(limit > 1)
   {
      
      Print(rates_total,": rates_total");
      Print(limit,": limit");   
      Print(ArraySize(IndBuff),": IndBuff");
   }   
   
   //-------------------------------------------------------------------------
   //Расчёт индикатора
   for(int i=limit; i>=0; i--)
   {
      c = iClose(_Symbol,PERIOD_CURRENT,i);    

      IndBuff[i] = c;  //array out of range

   }
   

   return(rates_total);
}
100686: rates_total
100686: limit
100686: IndBuff
array out of range in 'Simple.mq5' (82,15)
Roman #:

А всё потому, что буфер IndBuff не аллоцируется до rates_total + 1
И ArrayResize к нему не применим.
Сломали for конструкцию. Теперь через if-ы всё городить?

for(int i=limit - 1;....

как минимум..

Roman #:

А всё потому, что буфер IndBuff не аллоцируется до rates_total + 1
И ArrayResize к нему не применим.


Вот эдесь то Вам и нужна минус единичка :))
Распринтовка то показывает, что  с размерами все ОК.
Используйте логику:
Если limit = 0,  значит новый тик
Если limit = 1,  значит новый бар (последний элемент буфера rates_total -1, а у Вас rates_total, отсюда и переполнение)
Если limit > 1, то лучше пересчитать весь индикатор
Maxim Kuznetsov #:

for(int i=limit - 1;....

как минимум..

Знаешь, что больше всего неприятно? Что любые поведения изменяют молча, без предупреждений.
А люди потом мучаются. Надоел этот метатрейдер.

Roman #:

Знаешь, что больше всего неприятно? Что любые поведения изменяют молча, без предупреждений.
А люди потом мучаются. Надоел этот метатрейдер.

Все осталось как было.
Ваш косяк
Совет - научитесь пользоваться отладчиком и не надо делать распринтовку, также сразу будете видеть все свои косяки.
Roman #:

Знаешь, что больше всего неприятно? Что любые поведения изменяют молча, без предупреждений.
А люди потом мучаются. Надоел этот метатрейдер.

Не заметил изменения в расчёте индикаторов. Выше вам Николай всё верно расписал что означают значения limit, рассчитанного как rates_total-prev_calculated.

И это работает годами - ещё с четвёртого терминала.

Nikolai Semko #:
Вот эдесь то Вам и нужна минус единичка :))
Распринтовка то показывает, что  с размерами все ОК.
Используйте логику:
Если limit = 0,  значит новый тик
Если limit = 1,  значит новый бар (последний элемент буфера rates_total -1, а у Вас rates_total, отсюда и переполнение)
Если limit > 1, то лучше пересчитать весь индикатор

Николай я знаю конструкции if и за единичку,
но я всегда работал с for, просто привык, удобнее что-ли.
Но давно заметил странности с for, и всё откладывал разобраться с ним.
Раньше же замечательно работало

для тиков i>=0
для баров i>0

И не каких if-ов не нужно было.

Roman #:



Шаг 1: Создаём заготовку при помощи 'MQL5 Wizard':

//+------------------------------------------------------------------+
//|                                                       Simple.mq5 |
//|                              Copyright © 2022, Vladimir Karputov |
//|                      https://www.mql5.com/en/users/barabashkakvn |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2022, Vladimir Karputov"
#property link      "https://www.mql5.com/en/users/barabashkakvn"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Close
#property indicator_label1  "Close"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input int      Input1=9;
//--- indicator buffers
double         CloseBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,CloseBuffer,INDICATOR_DATA);
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+


Шаг 2: правильно прописываем 'limit' и ИСПОЛЬЗУЕМ массив close - А НЕ вызов iClose!!!

//+------------------------------------------------------------------+
//|                                                       Simple.mq5 |
//|                              Copyright © 2022, Vladimir Karputov |
//|                      https://www.mql5.com/en/users/barabashkakvn |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2022, Vladimir Karputov"
#property link      "https://www.mql5.com/en/users/barabashkakvn"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Close
#property indicator_label1  "Close"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input int      Input1=9;
//--- indicator buffers
double         CloseBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,CloseBuffer,INDICATOR_DATA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int limit=prev_calculated-1;
   if(prev_calculated==0)
      limit=0;
   for(int i=limit; i<rates_total; i++)
     {
      CloseBuffer[i]=close[i];
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+


Результат:

и нет никаких ошибок.

Файлы:
Simple.mq5  5 kb