Получил такой результат:
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.
С 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-4https://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 баров
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
Поведение функции полностью соответствует поведению копифункций с 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 являются частью нового бара.
* Я через индикатор после клика по бару создал объект на времени открытия бара.
- www.mql5.com
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Этот баг #698470, но Саппорт мне не верит.
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), то