Странный баг индикатора при смене инструмента

 

Покоя не дает странный баг, сколько уже провозилась. Обычный индикатор, оформлен по классике, но выдает ошибку Out of array если я с уже прикрепленным индикатором пытаюсь открыть не прогружавшийся ранее график (например перетягиванием инструмента на график). Проблема исчезает сразу же, если переключить таймфрейм и вернуться обратно.

Начала копать глубже и разбираться. Вот что выяснилось:

На первой отрисовке индикатора количество баров равно 512, а bars_counted = 0. Все норм, рисует.

На втором проходе: баров 512, а bars_counted 511 - тоже все ок.

На третьем или четвертом тике: баров 1024, а bars_counted 0 и тогда вылетает ошибка выхода за пределы массива.

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

 
Olga Miakhovich:


На третьем или четвертом тике: баров 1024, а bars_counted 0 и тогда вылетает ошибка выхода за пределы массива.

Посмотрите, к какому именно массиву идет обращение. Исходя из этого и нужно делать выводы. То, что bars_counted (я так понимаю, что речь идет о prev_calculated) равно нулю, явно указывает на то, что нужно произвести повторный перерасчет всех показаний индикатора. Ведь баров стало намного больше.

 
Обычно наоборот, такая проблем может случаться при первом расчете. Так что, случай нестандартный.
 
Такое может быть, если в алгоритме делаются допущения на обычное поведение данных. Исключите допущения, делайте все необходимые проверки на индексы массивов.
 
Olga Miakhovich:

Покоя не дает странный баг, сколько уже провозилась. Обычный индикатор, оформлен по классике, но выдает ошибку Out of array если я с уже прикрепленным индикатором пытаюсь открыть не прогружавшийся ранее график (например перетягиванием инструмента на график). Проблема исчезает сразу же, если переключить таймфрейм и вернуться обратно.

Начала копать глубже и разбираться. Вот что выяснилось:

На первой отрисовке индикатора количество баров равно 512, а bars_counted = 0. Все норм, рисует.

На втором проходе: баров 512, а bars_counted 511 - тоже все ок.

На третьем или четвертом тике: баров 1024, а bars_counted 0 и тогда вылетает ошибка выхода за пределы массива.

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

а можно скинуть файл индикатора?

если вам не жалко

Файлы:
 
Aleksandr Klapatyuk:

а можно скинуть файл индикатора?

если вам не жалко

не, нельзя)

 
Olga Miakhovich:

не, нельзя)

Временное решение - удалите директиву strict в начале кода, закомментируйте. И не будет выход за пределы  массива Вам писать. Они, конечно, останутся, но работать будет

 
Olga Miakhovich:


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

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

 
Алексей Тарабанов:

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

Так почему тогда в нормальной ситуации нормально все, а именно на новом графике без прогруженной истории выходит выход?

 
Olga Miakhovich:

Так почему тогда в нормальной ситуации нормально все, а именно на новом графике без прогруженной истории выходит выход?

Сделайте проверку на минимальное количество баров истории в самом начале OnCalculate():

if(rates_total<нужное_минимально_возможное_количество_баров_для_правильного_расчёта)
   return 0;

Тогда, если баров не достаточно для расчёта индикатора - будет выход с возвратом нуля, что означает, что ещё ничего не расчитано, но история начнёт подгружаться. На новом тике опять будет выполнена эта проверка, и если баров стало достаточно, то дальше уже будет расчёт индикатора.

В самом конце OnCalculate() возвращаете посчитанное количество баров:

return(rates_total);
 
Artyom Trishkin:

Сделайте проверку на минимальное количество баров истории в самом начале OnCalculate():

Тогда, если баров не достаточно для расчёта индикатора - будет выход с возвратом нуля, что означает, что ещё ничего не расчитано, но история начнёт подгружаться. На новом тике опять будет выполнена эта проверка, и если баров стало достаточно, то дальше уже будет расчёт индикатора.

В самом конце OnCalculate() возвращаете посчитанное количество баров:

Совет отличный, спасибо. Но я нашла ошибку: ошибка была в том, что мои буферы после первого расчета были со значениями, а counted bars сбрасывается в 0 при изменении кол-ва баров не смотря на то, что в буферах все же что-то есть, ну я их и наполнила значениями EMPTY_VALUE через ArrayInitialize()