Bars() BUG

 

Этот баг #698470, но Саппорт мне не верит.

void OnStart()
{
   if (_Period != PERIOD_H1) return; // Часовой для теста нужен.
   
   datetime time[];
   CopyTime(_Symbol, _Period, 0, 5, time);
   
   Print(time[0]," ",
      Bars(_Symbol, _Period, time[0], TimeCurrent()),
      " == ",
      Bars(_Symbol, _Period, time[0] - 1/*sec*/, TimeCurrent()),
      " ",time[0] - 1/*sec*/," != ",
      Bars(_Symbol, _Period, time[0] + 1/*sec*/, TimeCurrent()),
      " ",time[0] + 1/*sec*/);
}

2013.03.22 09:00:00 5 == 5 2013.03.22 08:59:59 != 4 2013.03.22 09:00:01

Почему же 09:00:00 находятся на баре с 8 часами? На самом графике там реально 4 бар от 0.

Support Team

Потому что 9-ти часовой бар попадает в интервал   2013.03.22 08:59:59 - TimeCurrent()

Во как все закручено однако!

Если ObjectGetInteger(0,objname,OBJPROP_TIME) попадает на начала бара (2013.03.22 09:00:00 при PERIOD_H1), то

Bars(_Symbol, _Period, ObjectGetInteger(0,objname,OBJPROP_TIME)+1, TimeCurrent()); // реальный бар
Документация по MQL5: Стандартные константы, перечисления и структуры / Константы графиков / Периоды графиков
Документация по MQL5: Стандартные константы, перечисления и структуры / Константы графиков / Периоды графиков
  • www.mql5.com
Стандартные константы, перечисления и структуры / Константы графиков / Периоды графиков - Документация по MQL5
 

Забейте. От этих функций копирования крыша уже давно в отъезде и никто не знает как они работают... Сейчас открыл справку и очередной раз ахнул... Копируйте по одному бару и не будет проблем.

CopyTime(_Symbol, _Period, 0, 1, time) 

 

Получил такой результат:

2013.03.22 10:00:00 5 == 5 2013.03.22 09:59:59 != 4 2013.03.22 10:00:01

Считаю, что неправильно, должно быть так:

 2013.03.22 10:00:00 5 == 6 2013.03.22 09:59:59 != 5 2013.03.22 10:00:01  

Roffild, а вы как думаете, какой должен быть правильный результат? 

 

С Copy*() все логично.

Даже в моем примере

CopyTime(_Symbol, _Period, 0, 5, time);

вернет 4 от 0 (всего 5), а Bars() утверждает, что 5 от 0.

2013.03.22 10:00:00 5 == 6 2013.03.22 09:59:59 != 5 2013.03.22 10:00:01
2013.03.22 10:00:00 4 == 5 2013.03.22 09:59:59 != 4 2013.03.22 10:00:01  потому счет баров с 0 (текущий) 0-4
 
Roffild:

С Copy*() все логично.

Даже в моем примере

вернет 4 от 0 (всего 5), а Bars() утверждает, что 5 от 0.

2013.03.22 10:00:00 4 == 5 2013.03.22 09:59:59 != 4 2013.03.22 10:00:01  потому счет баров с 0 (текущий) 0-4
Не велика разница 5 6 5 или 4 5 4. Но должно быть 5 6 5, потому, что количество баров возвращается. Если время начала равно времени конца, то значит один бар, а не ноль, поэтому 5 6 5.
 

https://docs.mql4.com/ru/series/ibarshift возвращает смещение и -1 при ошибке.

Для Bars() возврат количества. Так что в этом Integer прав.

void OnStart()
{
   if (_Period != PERIOD_H1) return; // Часовой для теста нужен.
   
   datetime time[];
   CopyTime(_Symbol, _Period, 0, 5, time);
   
   Print("Должно быть на 00:00:00=",ArraySize(time)," баров");
   Print(time[0]," ",
      Bars(_Symbol, _Period, time[0], TimeCurrent()),
      " == ",
      Bars(_Symbol, _Period, time[0] + 1/*sec*/, TimeCurrent()),
      " ",time[0] + 1/*sec*/," != ",
      Bars(_Symbol, _Period, time[0] - 1/*sec*/, TimeCurrent()),
      " ",time[0] - 1/*sec*/);
}
2013.03.22 11:00:00 5 == 4 2013.03.22 11:00:01 != 5 2013.03.22 10:59:59      5 == 5 != 6

Должно быть на 00:00:00=5 баров

iBarShift - Документация на MQL4
  • docs.mql4.com
iBarShift - Документация на MQL4
 
MQL4:
int start()
{
   Print("iBarShift() ",TimeToStr(Time[4], TIME_DATE|TIME_MINUTES|TIME_SECONDS)," ",
      iBarShift(Symbol(), Period(), Time[4]),
      " == ",
      iBarShift(Symbol(), Period(), Time[4] + 1/*sec*/),
      " ",TimeToStr(Time[4] + 1/*sec*/, TIME_DATE|TIME_MINUTES|TIME_SECONDS)," != ",
      iBarShift(Symbol(), Period(), Time[4] - 1/*sec*/),
      " ",TimeToStr(Time[4] - 1/*sec*/, TIME_DATE|TIME_MINUTES|TIME_SECONDS));
      
   int bar = iBarShift(Symbol(), Period(), D'2013.03.16 17:09:05');
   Print("Выходной bar=",bar," time=",TimeToStr(Time[bar]),
         " testerror=",iBarShift(Symbol(), Period(), D'2013.03.16 17:09:05',true));
}
iBarShift() 2013.03.22 14:00:00 4 == 4 2013.03.22 14:00:01 != 5 2013.03.22 13:59:59
Выходной bar=115 time=2013.03.15 21:00 testerror=-1


MQL5:

void OnStart()
{
   datetime time[];
   CopyTime(_Symbol, _Period, 0, 5, time);
   
   Print("Должно быть на 00:00:00=",ArraySize(time)," баров");
   Print("Bars() ",time[0]," ",
      Bars(_Symbol, _Period, time[0], TimeCurrent()),
      " == ",
      Bars(_Symbol, _Period, time[0] + 1/*sec*/, TimeCurrent()),
      " ",time[0] + 1/*sec*/," != ",
      Bars(_Symbol, _Period, time[0] - 1/*sec*/, TimeCurrent()),
      " ",time[0] - 1/*sec*/,
      " - BUG!");

   Print("iBarShift() ",time[0]," ",
      iBarShift(_Symbol, _Period, time[0]),
      " == ",
      iBarShift(_Symbol, _Period, time[0] + 1/*sec*/),
      " ",time[0] + 1/*sec*/," != ",
      iBarShift(_Symbol, _Period, time[0] - 1/*sec*/),
      " ",time[0] - 1/*sec*/);
   
   int bar = iBarShift(_Symbol, _Period,D'2013.03.16 17:09:05'); // Суббота
   CopyTime(_Symbol, _Period, bar, 1, time);
   Print("Выходной bar=",bar," time=",time[0],
         " testerror=",iBarShift(_Symbol, _Period,D'2013.03.16 17:09:05',true));
}

int iBarShift(string sSymbol, ENUM_TIMEFRAMES FramePeriod, datetime time, bool exact = false)
{
   if (time < 0) return(-1);
   if (sSymbol == "0") sSymbol = _Symbol;
   datetime secs = PeriodSeconds(FramePeriod);
   //// Bars() BUG
   datetime time2 = time;
   if (time2%secs > 0) time2 -= secs;
   ////
   int bar = Bars(sSymbol, FramePeriod, time2, TimeCurrent()) - 1;
   datetime testtime[];
   if (CopyTime(sSymbol, FramePeriod, bar, 2, testtime) != 2) return(-1);
   if (exact && (time2-testtime[0])>secs) return(-1);
   else if ((time2-testtime[0])>secs) return(bar+1);
   return(bar);
}

Должно быть на 00:00:00=5 баров
Bars() 2013.03.22 14:00:00 5 == 4 2013.03.22 14:00:01 != 5 2013.03.22 13:59:59 - BUG!
iBarShift() 2013.03.22 14:00:00 4 == 4 2013.03.22 14:00:01 != 5 2013.03.22 13:59:59
Выходной bar=115 time=2013.03.15 22:00:00 testerror=-1

Bars() багнутый, а iBarShift() полностью похожа на версию из MQL4.

Баг оставим на совесть разработчикам (Наверняка "Фичей" обзовут), а код iBarShift() в своих экспертах советую заменить.

 

Поведение функции полностью соответствует поведению копифункций с 3-м вариантом вызова.

Для копифункций в справке описано:

При запросе данных в заданном диапазоне дат возвращаются только данные, попадающие в запрашиваемый интервал, при этом интервал задается и учитывается с точностью до секунды. То есть время открытия любого бара, для которого возвращается значение (объем, спред, значение в индикаторном буфере, цена Open, High, Low, Close или время открытия Time) всегда находится в запрошенном интервале.

 

То есть для вашего случая (часовки, начало бара ХХ:00:00) бар 2013.03.20 00:00:00 попадет в выборку для запросов

2013.03.19 23:59:59 - 2013.03.20 23:59:59: Bars 24, Rates 24
2013.03.20 00:00:00 - 2013.03.20 23:59:59: Bars 24, Rates 24

и не попадет в выборку 

2013.03.20 00:00:01 - 2013.03.20 23:59:59: Bars 23, Rates 23
 
alexvd:

Поведение функции полностью соответствует поведению копифункций с 3-м вариантом вызова.

...

Тогда понятно.

 
2013.03.19 23:59:59 - 2013.03.20 23:59:59: Bars 24, Rates 24

логично. 2013.03.19 23:59:59 находится на 24 баре и он крайний.

2013.03.20 00:00:00 - 2013.03.20 23:59:59: Bars 24, Rates 24

Но здесь же "время открытия бара"! Почему новый бар в этот момент является частью предыдущего? На графике он отображается, как новый.

Результат функции и отображение графика не согласованы. Этот "нюанс" становится ошибкой, когда юзер объектом пометил 23 бар*, а Bars() выдает 24.

В MQL4 такого нет и 00:00 являются частью нового бара.

* Я через индикатор после клика по бару создал объект на времени открытия бара.

Документация по MQL5: Стандартные константы, перечисления и структуры / Константы графиков / Отображение графиков
Документация по MQL5: Стандартные константы, перечисления и структуры / Константы графиков / Отображение графиков
  • www.mql5.com
Стандартные константы, перечисления и структуры / Константы графиков / Отображение графиков - Документация по MQL5