Не работает индикатор в режима МТФ

 
Есть индикатор Зиг-заг, который коректно отображает экстремумы. Он называется ZigZagHighLow.mq4. Я склонировал код в другой такой же индикатор и решил сделать из этого индикатора МТФ Зиг-заг, назвал его ZZ.mq4, Коды прилагаю в сообщению. У второго индикатора имеются вводные параметры: Символ и Таймфрейм. Кроме как замены 3 функции я больше ничего не менял. По сути, должно было, как я понимаю, получить то, что мне нужно. Но не получилось.. В индикаторе ZZ.mq4 используется библиотека-прокладка GetTimeSeriesData.mq4. Она удобно для получения данных из таймсерий. В индикаторе ZZ.mq4 я заменил лишь данные таймсерий т.е. High[index] и High[index + 1], Low[index], Low[index + 1] и Bars, на соответственно методы сегодня написанной библиотеки, которую я проверил уже: getBarHighPrice(index, i_tf, i_instrument), getBarLowPrice(index, i_tf, i_instrument) и getTotalHistoryBars(i_tf, i_instrument). Так вот Зиг-заг рисуется какой-то левый. У меня такое ощущение, что он экстремумы рисует со сдвигом. Но почему вопрос. Ведь я получил количество баров с оответствующего таймфрейма, а так же цены максимальные и минимальные беру тоже с того же таймфрейма. Что не так?
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
//|                                                                                                                                                        ZZ.mq4 |
//|                                                                                                                                                           hoz |
//|                                                                                                                                                               |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
#property copyright "hoz"
#property link      ""
#property version   "1.00"
#property strict
#property indicator_chart_window                   // Индикатор выводится в окне графика
#property indicator_buffers 1                      // используется 1 буфер индикатора
#property indicator_color1 Red                     // Цвет отображения данных 1-го буфера
#property indicator_width1 1                       // Толщина линий 1-го буфера
// ================================================== Включения и импорт внешних модулей =================================================+
#import     "GetTimeSeriesData.ex4"
  int getTotalHistoryBars(int timeframe = 0, string instrument = NULL);
  int getBarShift(datetime time, ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT, string instrument = NULL, bool exact = false);
  double getBarHighPrice(int shift, ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT, string instrument = NULL);
  double getBarLowPrice(int shift, ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT, string instrument = NULL);
#import

//#include    "ZZProperties.mqh"
                                                   
#define NO_TREND        0                          // Нет тренда
#define TREND_UP        1                          // Восходящий тренд
#define TREND_DOWN     -1                          // Нисходящий тренд      

input string i_instrument;
input ENUM_TIMEFRAMES i_tf = PERIOD_H1;
input int i_needBarsToFormingZZ = 0;

double ZZBuf[];                                    // Буфер экстремумов
double UpDnBuf[];                                  // Буфер признака текущего тренда
int totalBarsOnGrafic;
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator initialization function                                                                                                                      |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
int init() {
  IndicatorBuffers(2);
// - 1 - == Проверка корректности значений настроечных параметров индикатора ============
//  string name = WindowExpertName();
// - 2 - == Связывание буферов с индексами, определение стилей ==========================
  SetIndexBuffer(0, ZZBuf);                       // Первый буфер - экстремумы
  SetIndexStyle(0, DRAW_SECTION);                 // В виде линии между непустыми значениями
  SetIndexBuffer(1, UpDnBuf);                     // Второй буфер - признак тренда
//  ArraySetAsSeries(UpDnBuf, true);
  SetIndexStyle(1, DRAW_NONE);                    // Не отображается
  return (0);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator deinitialization function                                                                                                                    |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
int deinit() {
  return (0);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Поиск последнего элемента ZZBuf с непустым значением                                                                                                          |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
int getLastNoEmptyValueIndex(int index) {
  while (index < getTotalHistoryBars(i_tf, i_instrument) && ZZBuf[index] == EMPTY_VALUE) {
    index++;
  }
  return (index);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Сравнение последнего максимума с новым максимумом                                                                                                             |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
void checkHigh(int index) {
  // найдём индекс бара с непустым значением (экстремумом)
  int lastNEVIndex = getLastNoEmptyValueIndex(index);
  
  if (lastNEVIndex == getTotalHistoryBars(i_tf, i_instrument)) {
    ZZBuf[index] = getBarHighPrice(index, i_tf, i_instrument);
    return;
  }
  if (getBarHighPrice(index, i_tf, i_instrument) > ZZBuf[lastNEVIndex]) {
    ZZBuf[lastNEVIndex] = EMPTY_VALUE;
    ZZBuf[index] = getBarHighPrice(index, i_tf, i_instrument);
  }
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Сравнение последнего минимума с новым минимумом                                                                                                               |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
void checkLow(int index) {
  // найдём индекс бара с непустым значением (экстремумом)
  int lastNEVIndex = getLastNoEmptyValueIndex(index);

  if (lastNEVIndex == getTotalHistoryBars(i_tf, i_instrument)) {
    ZZBuf[index] = getBarLowPrice(index, i_tf, i_instrument);
    return;
  }
  if (getBarLowPrice(index, i_tf, i_instrument) < ZZBuf[lastNEVIndex]) {
    ZZBuf[lastNEVIndex] = EMPTY_VALUE;
    ZZBuf[index] = getBarLowPrice(index, i_tf, i_instrument);
  }
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Смена тренда или его продолжение при отсутствии нового сигнала                                                                                                |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
void trendChangeOrMissing(int trend, int i) {
  // если тренд на данной итерации отсутствует, присваиваем буферу на данной итерации предыдущее значение
  if (trend == NO_TREND) {
    UpDnBuf[i] = UpDnBuf[i+1];
    return;
  }
  UpDnBuf[i] = trend;

  if (trend == TREND_UP) {
    checkLow(i);
    if (ZZBuf[i] != EMPTY_VALUE)
      ZZBuf[i-1] = getBarHighPrice(i, i_tf, i_instrument);
    else
      ZZBuf[i] = getBarHighPrice(i, i_tf, i_instrument);
    return;
  } else {
    checkHigh(i);
    if (ZZBuf[i] != EMPTY_VALUE)
      ZZBuf[i-1] = getBarLowPrice(i, i_tf, i_instrument);
    else
      ZZBuf[i] = getBarLowPrice(i, i_tf, i_instrument);
  }
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Определение тенденции по соотношению указанной и предыдущей свечей                                                                                            |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
int getTrend(int index) {
  if (getBarHighPrice(index, i_tf, i_instrument) > getBarHighPrice(index + 1, i_tf, i_instrument)) {
    return (TREND_UP);
  } else if (getBarLowPrice(index, i_tf, i_instrument) < getBarLowPrice(index + 1, i_tf, i_instrument)) {
    return (TREND_DOWN);
  }
  return (NO_TREND);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Расчет значений индикатора                                                                                                                                    |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ZigZag(int limit) {
  for (int i = limit; i > 0; i--) {
    // определение тренда на данной итерации
    int trend = getTrend(i);

    if (trend != UpDnBuf[i + 1]) {
      trendChangeOrMissing(trend, i); continue;
    }
    UpDnBuf[i] = trend;

    if (trend == TREND_UP) {
      checkHigh(i); continue;
    }
         
    if (trend == TREND_DOWN)
      checkLow(i);
  }
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Определение индекса бара, с которого необходимо производить перерасчет                                                                                        |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
int getRecalcIndex() {
  int countedBars = IndicatorCounted();
  if (countedBars == 0) {
    ArrayInitialize(ZZBuf, EMPTY_VALUE);
    ArrayInitialize(UpDnBuf, 0);
    return (totalBarsOnGrafic - 2);
  }
  return (totalBarsOnGrafic - countedBars - 1);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator iteration function                                                                                                                           |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
int start() {
  totalBarsOnGrafic = getTotalHistoryBars(i_tf, i_instrument);
  int limit = getRecalcIndex();
  ZigZag(limit);
  return (0);
}
Файлы:
 

Я прикинул. Пока что написал не оптимизированный кол. Вышло в плане поиска верхины так:

void checkHigh(int index) {
  // найдём индекс бара с непустым значением (экстремумом)
  int lastNEVIndex = getLastNoEmptyValueIndex(index);
  
  if (lastNEVIndex == getTotalHistoryBars(i_tf, i_instrument)) {
//    ZZBuf[index] = getBarHighPrice(index, i_tf, i_instrument);
    datetime barOpenTime = getBarOpenTime(index, i_tf, i_instrument);    // Время открытия бара на заданном в инпутпараметрах ТФ
    int barShift = getBarShift(barOpenTime, 0, i_instrument);            // Смещение бара на открытом ТФ
    ZZBuf[barShift] = getBarHighPrice(barShift, 0, i_instrument);
    return;
  }
  if (getBarHighPrice(index, i_tf, i_instrument) > ZZBuf[lastNEVIndex]) {
    ZZBuf[lastNEVIndex] = EMPTY_VALUE;
//    ZZBuf[index] = getBarHighPrice(index, i_tf, i_instrument);
    datetime barOpenTime = getBarOpenTime(index, i_tf, i_instrument);    // Время открытия бара на заданном в инпутпараметрах ТФ
    int barShift = getBarShift(barOpenTime, 0, i_instrument);            // Смещение бара на открытом ТФ
    ZZBuf[barShift] = getBarHighPrice(barShift, 0, i_instrument);
  }
}

График пока что конченоват, но уже видно, что я на правильном пути. Если у кого есть что подсказать, я буду рад любой критике))

 
2018.03.09 15:13:52.705 ZZ EURUSD,Daily: array out of range in 'ZZ.mq4' (142,25)


if (trend != UpDnBuf[i+1]) {

 
poruchik:
2018.03.09 15:13:52.705 ZZ EURUSD,Daily: array out of range in 'ZZ.mq4' (142,25)


if (trend != UpDnBuf[i+1]) {

У меня была подобная ошибка раньше. Уже всё поправлено. Если бы я увидел в каком месте точно ошибка, я бы сказал, что там не так. Я подумал и дописал код. Теперь он уже рисует всё иначе, но не так как хотелось бы. Код прикрепляю. Хочется мультитаймфреймовый Зиг-заг дописать, но что-то не то..

Файлы:
ZZ.mq4  24 kb
 

Посмотри вот этот вариант от nen. Вроде правильно показывает

Файлы:
 
poruchik:

Посмотри вот этот вариант от nen. Вроде правильно показывает

Спасибо, я погляжу, конечно. Но, если бы кто ткнул в чём я не прав, было бы вообще замечательно. Второй день уже долблюсь..

Причина обращения: