Чтение данных из диаграмм, имеющих сдвиг

Наш новый индикатор UseDemoAll почти завершен. Осталось рассмотреть один нюанс.

В подчиненном индикаторе некоторые диаграммы могут иметь сдвиг, задаваемый свойством PLOT_SHIFT. Например, при положительном сдвиге элементы таймсерии сдвигаются в будущее и отображаются правее бара с индексом 0. Их индексы, как это ни странно, являются отрицательными. С продвижением вправо номера уменьшаются все больше и больше: -1, -2, -3, и т.д. Эта адресация влияет и на функцию CopyBuffer. Когда мы используем первую форму CopyBuffer, параметр offset, равный 0, ссылается на элемент с текущим временем в таймсерии, но если сама таймсерия сдвинута вправо, мы получим данные, начиная с элемента под номером N, где N — величина сдвига в индикаторе-источнике. При этом в элементы, расположенные в нашем буфере правее индекса N, не будут заполнены данными, и в них останется "мусор".

Чтобы продемонстрировать проблему возьмем для начала индикатор без сдвига: Awesome Oscillator отлично подойдет. Напомним, что UseDemoAll копирует все значения в свои массивы, и хотя они невидны на графике из-за разных масштабов цен и показаний индикатора, мы можем сверяться по Окну данных. Куда бы мы ни сдвинули курсор мыши на графике, в Окне данных значения индикатора в подокне и в буферах UseDemoAll будут совпадать. Например, на нижеприведенном изображении наглядно видно, что на часовом баре в 16:00 оба значения равны 0.001797.

Данные индикатора AO в буферах UseDemoAll

Данные индикатора AO в буферах UseDemoAll

Теперь выберем в настройках UseDemoAll индикатор iGator (Gator Oscillator). Для простоты очистим поле с параметрами Gator — так он построится со своими параметрами по умолчанию. При этом сдвиг гистограмм составляет 5 баров (вперед), что хорошо видно на графике.

Данные индикатора Gator в буферах UseDemoAll без поправки на сдвиг в будущее

Данные индикатора Gator в буферах UseDemoAll без поправки на сдвиг в будущее

Черной вертикальной линией помечен часовой бар 16:00. Однако значения в Окне данных у индикатора Gator и в наших массивах, прочитанных из того же индикатора, отличаются. Желтым цветом подсвечены буфера UseDemoAll, содержащие мусор.

Если исследовать данные на 5 баров в прошлое, в 11:00 (оранжевая вертикальная линия), мы там обнаружим те значения, которые Gator выводит в 16:00. Попарные правильные значения верхней и нижней гистограммы подсвечены, соответственно, зеленым и розовым.

Чтобы решить данную проблему нам придется добавить в UseDemoAll входную переменную для указания пользователем сдвига диаграмм, а затем делать на неё поправку при вызове CopyBuffer.

input int IndicatorShift = 0// Plot Shift
...
int OnCalculate(ON_CALCULATE_STD_SHORT_PARAM_LIST)
{
   ...
   for(int k = 0k < m; ++k)
   {
      const int n = buffers[k].copy(Handlek,
         -IndicatorShiftrates_total - prev_calculated + 1);
      ...
   }
}

К сожалению, узнать свойство PLOT_SHIFT для стороннего индикатора из MQL5 нельзя.

Проверим, как введение сдвига 5 исправляет ситуацию с индикатором Gator (с настройками по умолчанию).

Данные индикатора Gator в буферах UseDemoAll после поправки на сдвиг в будущее

Данные индикатора Gator в буферах UseDemoAll после поправки на сдвиг в будущее

Теперь показания UseDemoAll на баре 16:00 соответствуют актуальным данным из Gator из виртуального будущего, отстоящего на 5 баров вперед (сиреневая вертикальная линия в 21:00).

Попутно у вас может возникнуть вопрос, почему в окне Gator выводится только 2 буфера, а в нашем — 4. Дело в том, что цветная гистограмма Gator использует по одному дополнительному буферу для кодирования цвета. Поскольку цветов всего два — красный и зеленый — мы их видим в своих массивах как 0 или 1.