Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 987

 

Прошу помощи, кусочек индикатора

//+------------------------------------------------------------------+
//|  OnCalculate 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[])
  {

   ArraySetAsSeries(time,true);

   datetime Fp=0,Ep=0,pFp=0,pEp=0,Arr[];
   int Count=0,bars=0,dt=0;

   int limit;
   if(prev_calculated==0 || prev_calculated<0 || prev_calculated>rates_total)
      limit=Nbar;
   else
      limit=rates_total-prev_calculated;

   for(int i=limit;i>=0;i--)
     {

      if(CopyTime(NULL,TimeFrame,time[i],1,Arr)>0)Ep=Arr[0]-1*PeriodSeconds(PERIOD_CURRENT);
      else return(0);

иногда массив time[i] переполняется, к примеру по ночам, когда рынок закрыт.

2019.01.25 00:06:35.191 i-Regr4_05i (Si Splice,H1)      array out of range in 'i-Regr4_05i.mq5' (134,38)

Как решить эту проблему?

 

Подскажите после такого объявления.

double Price[]; 

Размер массива всегда 0 ?

 
pivomoe:

Подскажите после такого объявления.

Размер массива всегда 0 ?

Да.

 
Artyom Trishkin ,  очень хочется услышать от Вас, как профессионала и ответственного модератора, обоснование поведению функции Bars, особенно с ссылкой на мануал, а не догадки!
 
Aleksey Vyazmikin:

Прошу помощи, кусочек индикатора

иногда массив time[i] переполняется, к примеру по ночам, когда рынок закрыт.

Как решить эту проблему?

Например правильно вычислять параметр Nbar:

   if(prev_calculated==0 || prev_calculated<0 || prev_calculated>rates_total)
      limit=Nbar;
 
Aleksey Vyazmikin:

Читаю внимательно справку к функции Bars:

"

Если указаны параметры start_time и stop_time, то функция возвращает количество баров в диапазоне дат. Если эти параметры не указаны, то функция возвращает общее количество баров.

"

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

Удивляет работа функции:

При любом из вариантов, в том числе закомментированных, StopDt получаем значение 2!

Особенно удивляет вариант, когда начальная дата (2018.01.04 10:00) позже по времени конечной (2018.01.03 23:49) в секундном выражении - почему не выдается ошибка или хотя бы 1?

Если начальная и конечная дата совпадают, то тут уж логично выдать единицу, а не опять двойку!

Проверяю на ФОРТС инструмент Si, график минутный.

Прежде чем говорить о несоответствиях надо-бы показать что на графике больше баров чем возвращает функция.

Я с этой функцией работаю достаточно много и никаких проблем не получаю. И был крайне удивлён зачем в mql5 всунули iBarShift и подобные функции.

А тот факт что функция меняет время 'от' и 'до' местами если программист вдруг перепутал, так это всё входит в понятие "Защита от дурака".

И ещё хочу посоветовать: Чтобы функция работала быстрей, ставьте в неё время начала бара. Пара дополнительных строк обеспечит скорострельность. Особенно это важно для тестера.

 
Vladimir Karputov:

Например правильно вычислять параметр Nbar:

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

И потом, у Вас речь об индикаторной проверке, а я использую Bars для расчета корректного времени начала бара, так как iBarShift себе на уме и подходит только для форекса, где нет частого провалов с историей из-за клирингов и  торговых сессий не на весь день.

 
Alexey Viktorov:

Прежде чем говорить о несоответствиях надо-бы показать что на графике больше баров чем возвращает функция.

Я с этой функцией работаю достаточно много и никаких проблем не получаю. И был крайне удивлён зачем в mql5 всунули iBarShift и подобные функции.

А тот факт что функция меняет время 'от' и 'до' местами если программист вдруг перепутал, так это всё входит в понятие "Защита от дурака".

И ещё хочу посоветовать: Чтобы функция работала быстрей, ставьте в неё время начала бара. Пара дополнительных строк обеспечит скорострельность. Особенно это важно для тестера.

Это не защита, а препятствие для выявления ошибки в коде!

Более того, уж совсем не логично возвращать цифру 2, если даты совпадают - тут то какое обоснование?

Время начала бара на ФОРТС может не совпадать, что приводит к ошибкам вычисления, к примеру бар открывается не в 14:00, а в 14:05 - так же с этим промучился.

 
Aleksey Vyazmikin:

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

И потом, у Вас речь об индикаторной проверке, а я использую Bars для расчета корректного времени начала бара, так как iBarShift себе на уме и подходит только для форекса, где нет частого провалов с историей из-за клирингов и  торговых сессий не на весь день.

И где Ваша проверка? И зачем вводить какую-то переменную, если ( при подкачке истории или изменении истории) нужно просто пересчитать индикатор полностью. Как правило это делают от "0" до "rates_total-1".

 
Vladimir Karputov:

И где Ваша проверка? И зачем вводить какую-то переменную, если ( при подкачке истории или изменении истории) нужно просто пересчитать индикатор полностью. Как правило это делают от "0" до "rates_total-1".

У меня проблема не связана с индикатором или подкачкой истории. Вот кусок кода

      datetime         StartDt=iTime(Symbol(),PERIOD_CURRENT,Bars(Symbol(),PERIOD_CURRENT,iTime(Symbol(),TF_iDeltaP,0),iTime(Symbol(),PERIOD_CURRENT,0))-1);
      datetime         StopDt=iTime(Symbol(),PERIOD_CURRENT,1); //Берем прошлый бар, что б не было расхождений между реалом и тестером при задержки на реальных данных

      int BarsGo=Bars(Symbol(),PERIOD_CURRENT,StartDt,StopDt);
      if(StartDt>StopDt)BarsGo=0;
      if(StartDt==StopDt)BarsGo=1;
      if (BarsGo>0)
        {
                //Полный расчет с вычислениями - копирование массивов цен и прочие тяжелые функции
        }
      else
        {
                //Упрощенный расчет с присвоением эмпирических значений переменным
        }
Проблема возникает при открытии нового бара в общем то, когда дата начала бара больше, чем сдвиг на 1 бар от нулевого бара на текущем TF.