Я и раньше замечал периодически, что с расчётом индикаторов что-то не так, а вчера вот поймал... И даже могу примерно описать, при каких условиях он возникает. Сравните третий бар на двух графиках.
Возникает примерно так: открываем МТ4, он рисует графики, подгружает историю, открываем второй график и наслаждаемся разницей. В аттаче нижний индюк. Вопрос - что я не так делаю?
Все так. Это умеют делать очень много индикаторов. У меня таких много. Дело в дыре в истории, возникающей при подключении к серверу. Приходит тик, запускается индикатор, история еще может быть не загружена, а индикатор считается с пропущенными барами. Где-то, в Code Base, встречались индикаторы с принудительной переинициализацией индикатора. Я тогда не понимал, какая проблема решается. На сегодня программного решения у меня нет. Руками обновляю индикаторы. Если индикаторов много и используются таймфреймы выше М1, можно перезапустить терминал.
Все так. Это умеют делать очень много индикаторов. У меня таких много. Дело в дыре в истории, возникающей при подключении к серверу. Приходит тик, запускается индикатор, история еще может быть не загружена, а индикатор считается с пропущенными барами. Где-то, в Code Base, встречались индикаторы с принудительной переинициализацией индикатора. Я тогда не понимал, какая проблема решается. На сегодня программного решения у меня нет. Руками обновляю индикаторы. Если индикаторов много и используются таймфреймы выше М1, можно перезапустить терминал.
// Главный цикл. int start() { int i = Bars - IndicatorCounted(); if (i>1) i=Bars-1; // Если обрабатываемый бар не нулевой или первый - полный перерасчет for(; i >= 0; i--) { double range = High[i] - Low[i]; buf[i]=0; if (range>0) buf[i] = (Close[i] - Low[i]) / range - 0.5; } return(0); }
У Вас решение радикальное.
У меня более спорное, но, мне кажется, тоже должно работать
// Главный цикл. int start() { // индикатор считается неверно на первом загружаемом баре // увеличение глубины пересчета на один бар должно решить проблему int i = Bars - IndicatorCounted() + 1; for(; i >= 0; i--) { double range = High[i] - Low[i]; buf[i]=0; if (range>0) buf[i] = (Close[i] - Low[i]) / range - 0.5; } return(0); }
А так, лаконичный вид конструкции, что была предложена выше, выглядит так:
void start() { // граница пересчета int limit=Bars-IndicatorCounted()-1; if(limit>1) limit=Bars-1; // цикл пересчета for(int i=limit; i>=0; i--) {//} }
Если нужна доп. реинициализация, то она вызывается по условию в секции // граница пересчета. Она нужна, в частности, если используются стат.переменные.
Дабы не усложнять main, можно перенести limit=Bars-1 (с возратом результата) в код reinit() и тогда это будет выглядеть так:
void start() { // граница пересчета int limit=Bars-IndicatorCounted()-1; if(limit>1) limit=reinit(); // цикл пересчета for(int i=limit; i>=0; i--) {//} }
)) Видимо, Виктор имел ввиду в т.ч. и мои варианты с ф-й reinit() - дополнительной переинициализацией.
А так, лаконичный вид конструкции, что была предложена выше, выглядит так:
Если нужна доп. реинициализация, то она вызывается по условию в секции // граница пересчета. Она нужна, в частности, если используются стат.переменные.
Дабы не усложнять main, можно перенести limit=Bars-1 (с возратом результата) в код reinit() и тогда это будет выглядеть так:
Маленькая поправка
void start() { // граница пересчета int limit=Bars-IndicatorCounted(); // Единицу отнимать не надо. if(limit>1) limit=Bars-1; // цикл пересчета for(int i=limit; i>=0; i--) {//} }Иначе не всегда будет рассчитываться первый бар. Недавно столкнулся с этим
самый надежный вариант - рассчитать самостоятельно какое должно быть время у нулевого бара и в старте ничего не делать пока Time[0] не станет равным рассчитанному (т.е. пока не приедет самая последняя котировка).
к сожалению здесь есть грабли и большие. локальное время своей машинки мы знаем. а вот серверное - нет. точнее не время а таймзоны чтобы по ней зная свое локальное время вычислить что сейчас должно быть на сервере. Проблема была поднята здесь https://www.mql5.com/ru/forum/123222, но поскольку разработчики уже забили на четверку ответ их был таков:
К сожалению, мы не добавим новую функциональность в четвёрку.
Маленькая поправка
Что-то я не догоняю - это как же? К тому же при нулевом значении IndicatorCounted() будет выход индекса за границы пересчитываемых ценовых массивов.
===
Виктор, ты уверен, что у тебя глюк был связан именно с этим? У меня при такой конструкции никаких проблем не наблюдалось. Впрочем, все бывает когда-то в первый раз...)))
Есть еще один тонкий момент в штатном без пропусков рабочем режиме (когда пересчитываются только 0-й и 1 бары). Он также связана с использованием статики. Алгоритм может быть построен так,что посчитанная ранее стат переменная по приходу нового бара будет пересчитана заново, и, если ее значение зависит от триггера, то может возникнуть ошибка - значение это переменной будет др., чем при первом вычислении. Это тоже нужно учитывать. Вообще, подводных камней много.
А... Может ты имел ввиду принудительный пересчет 0-го и 1- баров на каждом тике, а не только по приходу первого тика нового бара?
Ну... м.б. И скважность загрузки ЦП нормализуется. Но тогда конструкция будет выглядеть несколько иначе. Но это тоже не снимает нектр. проблем - напр., как в посте выше.
Попробуй это вариант
Ок, попробую подловить. Решение сильно "радикально", имхо. Но интересно - поможет ли? Я так понимаю, IndicatorCounted() в случае "догона" котировок возвращает (может, не всегда) неправильное значение. По идее ведь он должен захватывать и этот бар тоже. А если обновляться должно 2 бара (а он вернёт 1, т.е.) - то фокус, по идее, не сработает... :(
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Я и раньше замечал периодически, что с расчётом индикаторов что-то не так, а вчера вот поймал... И даже могу примерно описать, при каких условиях он возникает. Сравните третий бар на двух графиках.
Возникает примерно так: открываем МТ4, он рисует графики, подгружает историю, открываем второй график и наслаждаемся разницей. В аттаче нижний индюк. Вопрос - что я не так делаю?