Кнопка "Обновить"

 

Столкнулся с проблемой при нажатии кнопки "Обновить". Много времени потратил на ее поиск и исправление, так что, дабы не забыть в будущем решил описать ее и ее решение.

Из справки терминала билд 1159 (МТ5):

  • Обновить — обновить окно графика. При этом также происходит повторное вычисление ценовых данных, представленных на графике, из хранящихся на компьютере минутных данных.

Также в терминале установлена настройка: макс. баров в окне = 5000. Это важно!

К сожалению, в данном описании не указано, что эта функция делает, в моем случае, с индикатором. А делает она следующее.

1. Переменная rates_total сбрасывается на значение макс. баров в окне. Т.е. значение устанавливается = 5000. Хотя значение до сброса могло быть больше;

2. Переменная prev_calculated становится равной 0.

Собственно, все как после инициализации индикатора (например, после смены ТФ). Но самое интересное в том, что этой инициализации (вызова функции OnInit()) не происходит! Т.е. после нажатия на кнопку обновить в случае, если Вы использовали глобальные или статические переменные их значения не обнулятся. И дальше можно спокойно получить выход за пределы массива, корявые графические построения и т.п. В моем случае, я надеялся на конструктор. Из справки:

Статические переменные существуют с момента выполнения программы и инициализируются однократно перед вызовом специализированной функции OnInit(). 

Вот случай с нажатием кнопки "Обновить" как раз говорит о том, что нельзя надеяться на эту инициализацию.

Надеюсь, кому-нибудь поможет. Будьте осторожны! Удачи. 

P.S. На кнопку "Обновить" изначально нажимал при старте терминала, т.к. на одном из графиков не отображался индикатор, а рынок по символу был низковолатильным.

 

пф.... у меня при нажатии кнопки, уже давно, ничего не происходит..

нет кнопки - нет проблем.. 

 
Yury Antipov:

пф.... у меня при нажатии кнопки, уже давно, ничего не происходит..

нет кнопки - нет проблем.. 

Мы говорим про одну и ту же кнопку? В терминале после нажатия ПКМ?
 
да
 
Yury Antipov:

пф.... у меня при нажатии кнопки, уже давно, ничего не происходит..

нет кнопки - нет проблем.. 

Кнопка нужна, например, для обновления оффлайн графиков, когда тики не приходят, а индикатор посмотреть нужно.

А куда кнопка делась? 

 
она не делась никуда.. просто при нажатии не реагирует.. причину я не знаю, да и привык уже..
 
Yury Antipov:
она не делась никуда.. просто при нажатии не реагирует.. причину я не знаю, да и привык уже..
Она реагирует, поверьте. Выше расписал на примере индикатора.
 
Tapochun:

1. Переменная rates_total сбрасывается на значение макс. баров в окне. Т.е. значение устанавливается = 5000. Хотя значение до сброса могло быть больше;

Как это значение могло быть больше, если окно ограничено по количеству баров (в таком случае это, по идее, баг терминала)? Если значение больше, то тут как раз и будет получен выход за пределы массива.

 2. Переменная prev_calculated становится равной 0.

Собственно, все как после инициализации индикатора (например, после смены ТФ). Но самое интересное в том, что этой инициализации (вызова функции OnInit()) не происходит! Т.е. после нажатия на кнопку обновить в случае, если Вы использовали глобальные или статические переменные их значения не обнулятся. И дальше можно спокойно получить выход за пределы массива, корявые графические построения и т.п. В моем случае, я надеялся на конструктор. Из справки:

Вот случай с нажатием кнопки "Обновить" как раз говорит о том, что нельзя надеяться на эту инициализацию.

Не заострял внимание на поведении индикаторов при нажатии обновить, но, на мой взгляд, поведение логичное. Ведь когда нажимается эта кнопка, то должно произойти обновление данных с сервера с возможной подгрузкой пропущенных баров. В итоге само собой, что prev_calculated должно сбрасываться в 0, указывая индикатору на необходимость проведения полного перерасчета показаний. Вызов OnInit в данном случае неуместен. Но если структура индикатора такова, что нужно вызывать OnInit при prev_calculated, равном 0, то несложно это сделать принудительно. 

 
Игорь Герасько:

Как это значение могло быть больше, если окно ограничено по количеству баров (в таком случае это, по идее, баг терминала)? Если значение больше, то тут как раз и будет получен выход за пределы массива.

Не заострял внимание на поведении индикаторов при нажатии обновить, но, на мой взгляд, поведение логичное. Ведь когда нажимается эта кнопка, то должно произойти обновление данных с сервера с возможной подгрузкой пропущенных баров. В итоге само собой, что prev_calculated должно сбрасываться в 0, указывая индикатору на необходимость проведения полного перерасчета показаний. Вызов OnInit в данном случае неуместен. Но если структура индикатора такова, что нужно вызывать OnInit при prev_calculated, равном 0, то несложно это сделать принудительно. 

Из справки по mql5. Раздел "Организация доступа к данным":

Объем запрашиваемых у сервера данных соответствует требуемому количеству баров данного таймфрейма с учетом значения параметра "Max bars in charts". Ограничение, задаваемое параметром, не является жестким, и в некоторых случаях количество доступных баров по таймфрейму может быть незначительно больше текущего значения параметра. 

Поэтому возможен выход за пределы массивов.

Поведение логичное, но не документированное и сразу не всегда получается понять что к чему. Именно поэтому я и опубликовал первый пост. Самому не забыть и другим рассказать.

Нет, OnInit() при prev_calculated = 0 не нужно было вызывать. Нужно было инициализировать статический объект структуры. Я просто добавил этот код в блок if( prev_calculated == 0 ).

 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Alexey Kozitsyn, 2016.11.19 14:34

Заметил одну интересную особенность терминала МТ5. Если открыто несколько окон одного и того же инструмента, то при нажатии на кнопке "обновить" одного окна, обновляются ВСЕ окна этого инструмента. Так и должно быть?

Добавлено:

Сейчас, на закрытом рынке с тиковыми индикаторами на других графиках этого инструмента (Si-12.16) приводит к жутким зависанием пустого графика!