datetime dayStartDt = calculateDayOpenDt(rates[indexFrom].time); for (int i = indexFrom + 1; i < limit; i++) { if (rates[0].time < dayStartDt) { isFirstBarUnclosed = true; }
- Вопервых зачем оно внутри цикла?
- Во вторых, в чем его смысл?
- Вы ведь dayStartDt вычислили от rates[0].time, поэтому rates[0].time не может быть меньше dayStartDt.
Результат выражения ((rates[0].time / 86400) * 86400) никогда не будет больше rates[0].time. - Только текущий бар является "unclosed".
Текущий бар это rates[0] (при условии, что вы для CopyRates передаете start_pos = 0 и для массива rates[] установлен AS_SERIES = true).
Другими словами, только самый правый бар на графике является "unclosed", все остальные - "closed".
Сама идея искать N-ый бар дня выглядит некорректной. Потому что вы не можете предвидеть время открытия того бара, так как несколько первых баров дня могут быть пропущены.
Если вам нужен индекс бара с конкретным временем открытия, то ищите именно его, а не N-ый бар дня. И обрабатывайте ситуацию, когда на графике отсутствует (пропущен) бар с нужным вам временем открытия.
Даже на H1 не всегда день начинается с бара со временем 00:00. Первый бар дня может иметь время открытия 01:00, 03:00, ...
Потому что это работает корректно только в скрипте, если уже 2-ой бар, т.е. индекс у него будет 1. Если бар не закрыт, результат прыгает и не всегда корректен. Может отобразить не то, что нужно.
Я это всё перенёс в бота и прогнал на истории. Открывает очередной день и вижу.. что цены открытия и закрытия дня не те, которые на самом деле у 1-го бара на заданном ТФ.
А внутри цикла условие почему.. я же писал, что return не отрабатывает почему-то..
Чтобы отследить почему пляшут цены не закрытого бара и я в голове это просимулировал. Такой косяк может быть, если мы будет искать бар с 0-индексом, как я понимаю, находясь на 0-ом индексе.
Результат выражения ((rates[0].time / 86400) * 86400) никогда не будет больше rates[0].time.
Судя по принту в журнале будет..) Обратите, внимание на скрин, так удобнее показать, что я имею в виду.
Даже на H1 не всегда день начинается с бара со временем 00:00. Первый бар дня может иметь время открытия 01:00, 03:00, ...
Так это уже от инструмента зависит. Я вот думаю, может проще не извращаться т.к. не особо много вариантов и удобств нет для комфортной реализации этой задачи. Может проще просто брать диапазон времени и всё?
Например,
0-бар, если часовик, то время открытия от 12.55 до 00.05
1-ый индекс (2-ой бар), цена открытия ищется с 00.55 до 01.05.
и т.д..
Чтобы отследить почему пляшут цены не закрытого бара и я в голове это просимулировал.
Цены незакрытого бара пляшут потому, что он не закрыт.
Такой косяк может быть, если мы будет искать бар с 0-индексом, как я понимаю, находясь на 0-ом индексе.
Если искомый вами бар находится на нулевом индексе, то у вас 2 варианта:
- либо игнорировать его (ждать пока откроется новый бар)
- либо обновлять цены ваших прямоугольников с каждым тиком (тестирование по ценам открытия здесь не подходит, само-собой)
Я не понимаю, что у вас на скриншоте и при чем здесь rates[0].time.
Print("Before for"); for (int i = indexFrom + 1; i < limit; i++) { Print("___rates[", i, "].time = ", rates[i].time); Print("___dayStartDt = ", dayStartDt);
А вы точно учли, что вы печатаете rates[i].time, но функция вернет (i - 1), а не i?
В любом случае, даже если условие верно, всё-равно оно не отрабатывается т.к. я вижу принты, которые не могут отработать, по сути.
Сделайте принты корректными.
У вас в цикле сравнение идёт с нулевым индексом
rates[0].time
а распечатываете совсем с другим индексом
Print("___rates[", i, "].time = ", rates[i].time);
Вот когда в распечатке будет, то что в сравнении
if (rates[0].time < dayStartDt)
вот тогда посмотрим как работает return )))
Зы. а какая задача у этого кода? Что вы хотите получить на выходе?
Вот когда в распечатке будет, то что в сравнении
В том то и прикол, что никогда. Переменная i (счетчик цикла) никогда не будет равна нулю. Собственно этим и был вызван тот мой вопрос:
[edit]
Цикл ищет ближайший бар предыдущего дня. А первый бар искомого дня находится на один бар правее, поэтому возвращается (i - 1).
- 2024.10.14
- Maxim Kuznetsov
- www.mql5.com
выдержка из более большого кода, как иллюстрация, лишние проверки покоцаны
тут ищется первый за предыдущий день, бар текущего ТФ (который меньше D1).
// предыдущий день (любой) int prevDayShift=iBarShift(_Symbol,PERIOD_D1,time)+1; // индекс пред.дня datetime prevDayTime=iTime(_Symbol,PERIOD_D1,prevDayShift); // время D1 int prevBarShift=iBarShift(_Symbol,PERIOD_CURRENT,prevDayTime); // индекс на текущем ТФ (но может попасть в "позавчера") datetime prevBarTime=iTime(_Symbol,PERIOD_CURRENT,prevBarShift); // и его время // так как может попасть в "позавчера" - придётся сдвигать, пока не попадём while(prevBarShift>0 && prevBarTime<prevDayTime) { prevBarShift--; prevBarTime=iTime(_Symbol,PERIOD_CURRENT,prevBarShift); }
просто iBarShift возвращает первый подходящий бар с временем меньше указанного. То есть если время попадает в выходной, или есть пропуски баров то может вернуть последний бар предыдущего дня (недели) вместо ожидаемого первого.
Поэтому его результат приходится фиксить небольшим циклом
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Сегодня я решил проверить и дописать код, над которыми сейчас думаю некоторое время. Вижу, что либо даты не сравниваются корректно, либо оператор return из функции не позволяет выйти целиком, либо ещё что-то.
Если есть такая структура:
Я опустил весь остальной код т.к. он здесь не принципиален.
Особенно, интересен участок кода:
В любом случае, даже если условие верно, всё-равно оно не отрабатывается т.к. я вижу принты, которые не могут отработать, по сути.
Вот что я вижу в журнале:
И так понятно, что ___rates[1].time < ___dayStartDt, а это означает, что из циукла должны мы выйти. И из функции firstBarOfDayCheck() тоже..
Но, далее я вижу:
А значит, из функции не выходит. С чего это вдруг? Я уже придумал переменную булевскую (извращаюсь как могу), которая становится истиной, если условие времени, сравнение которого я привёл выше соблюдается. Не помогло.
Сколько писал в других языках, если указываешь return, выполнение функции завершается. С чего в друг не так?
Прирепляю файл целиком.