Цветной Зиг-Заг не работает?

 

После того, как  цветной Зиг-Заг не заработал в моей программе, я решил проверить его с помощью простого кода:

#property indicator_chart_window
#property indicator_buffers 3 
#property indicator_plots   1
#property indicator_type1   DRAW_COLOR_ZIGZAG
#property indicator_color1  Red, DodgerBlue 

double zz_l[], zz_h[], zz_i[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){
  SetIndexBuffer(0, zz_l, INDICATOR_DATA);
  SetIndexBuffer(1, zz_h, INDICATOR_DATA);
  SetIndexBuffer(2, zz_i, INDICATOR_COLOR_INDEX);
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
//---
  if(prev_calculated == 0){
    for(int i = 0; i < rates_total; i+=5){
      zz_l[i] = low[i];
      zz_h[i] = high[i];
      zz_i[i] = 1;
    }
  }
  return(rates_total);
}
//+------------------------------------------------------------------+

Смотрел пример из справки. Вроде все сделал правильно... Но не работает!

Получается, примерно, следующее:

После сжатия графика, стало видно нулевой уровень (где, собственно, ничего видно быть не должно (так, как это PLOT_EMPTY_VALUE, по умолчанию))

В чем причина данного бага, это Зиг-Заг сам по себе лагает или я что-то упустил?

 
Mihail Matkovskij:

После того, как  цветной Зиг-Заг не заработал в моей программе, я решил проверить его с помощью простого кода:

Смотрел пример из справки. Вроде все сделал правильно... Но не работает!

Получается, примерно, следующее:

После сжатия графика, стало видно нулевой уровень (где, собственно, ничего видно быть не должно (так, как это PLOT_EMPTY_VALUE, по умолчанию))

В чем причина данного бага, это Зиг-Заг сам по себе лагает или я что-то упустил?

PLOT_EMPTY_VALUE нужно указать явно и явно заполнить этими значениями индексы, которые не участвуют в отрисовке.
 
Mihail Matkovskij:

После того, как  цветной Зиг-Заг не заработал в моей программе, я решил проверить его с помощью простого кода:

Смотрел пример из справки. Вроде все сделал правильно... Но не работает!

Получается, примерно, следующее:

После сжатия графика, стало видно нулевой уровень (где, собственно, ничего видно быть не должно (так, как это PLOT_EMPTY_VALUE, по умолчанию))

В чем причина данного бага, это Зиг-Заг сам по себе лагает или я что-то упустил?

Я-бы добавил проверку на чётность счётчика цикла и соответственно чередование цветности линии.

    for(int i = 0; i < rates_total; i+=5)
     {
      if(i%2 > 0)
       {
        zz_l[i] = low[i];
        zz_i[i] = 0;
       }
      else
        {
         zz_h[i] = high[i];
         zz_i[i] = 1;
        }
     }

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

 
Alexey Viktorov:

Я-бы добавил проверку на чётность счётчика цикла и соответственно чередование цветности линии.

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

В том то и дело, что как должно быть скорее всего не получится, потому как, если два буфера, верхний и нижний, имеют одинаковый индекс, то они закрасятся оба в один цвет. Поэтому, сделать разные цвета экстремумов не получится, для этого нужны разные индексы этих экстремумов, что исключает нормальную подсветку такой формации, как внешний бар в Зиг-Заге.

Alexey Kozitsyn:
PLOT_EMPTY_VALUE нужно указать явно и явно заполнить этими значениями индексы, которые не участвуют в отрисовке.

Сделал, работает. Но в моей программе, где я сделал все точно так же, не хотело работать. Вот фрагмент кода:

#property indicator_chart_window
#property indicator_buffers 5 
#property indicator_plots   2 
#property indicator_type1   DRAW_COLOR_LINE 
#property indicator_width1  2
#property indicator_label1  "Downtrend;Uptrend"
#property indicator_color1  Red, Blue

#property indicator_type2   DRAW_COLOR_ZIGZAG
#property indicator_color2  DarkViolet, DodgerBlue

double ma[];
double indexes[];
double zz_h[], zz_l[], zz_i[];

#include <Cyberdev\Indicators\mtd_zig_zag.mqh>

CMTD_ZigZag ZZ;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){
  ZZ.Create();
  ZZ.Timeserie = false;
  ZZ.move_len_min = 5;
  SetIndexBuffer(0, ma, INDICATOR_DATA);
  SetIndexBuffer(1, indexes, INDICATOR_COLOR_INDEX);
  
  SetIndexBuffer(2, zz_l, INDICATOR_DATA);
  SetIndexBuffer(3, zz_h, INDICATOR_DATA);
  SetIndexBuffer(4, zz_i, INDICATOR_COLOR_INDEX);
  PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0);
  PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, 0);
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,      // размер входных таймсерий 
                 const int prev_calculated,  // обработано баров на предыдущем вызове 
                 const datetime& time[],     // Time 
                 const double& open[],       // Open 
                 const double& high[],       // High 
                 const double& low[],        // Low 
                 const double& close[],      // Close 
                 const long& tick_volume[],  // Tick Volume 
                 const long& volume[],       // Real Volume 
                 const int& spread[]         // Spread 
){
  ZZ.RefreshData(rates_total, prev_calculated);
  int count = rates_total - prev_calculated;
  int ma_count = ZZ.DataCount();

  int _begin = rates_total - 1;
  int end = rates_total - count - 15;
  if(prev_calculated == 0) end = 0;

  for(int i = _begin; i >= end; i--){
    ma[i] = ZZ.m_data[i];
    indexes[i] = ZZ.ma_indexes[i];
  }
  
  if(prev_calculated == 0){
    for(int i = 0; i < rates_total; i++){
      zz_l[i] = 0;
      zz_h[i] = 0;
      zz_i[i] = 0;
    }
    
    int index_1, index_2;
    for(int i = 0; i < ZZ.extremums_count-1; i++){
      index_1 = ZZ.Extremums[i].index;
      if(i < ZZ.extremums_count - 1){
        index_2 = ZZ.Extremums[i+1].index;
      }
      else continue;

      switch(ZZ.Extremums[i].et){
        case etLo : 
          zz_l[index_1] = ZZ.Extremums[i].price;
          zz_h[index_2] = ZZ.Extremums[i+1].price;
          zz_i[index_2] = 0;
          break;
        case etHi : 
          zz_h[index_1] = ZZ.Extremums[i].price;
          zz_l[index_2] = ZZ.Extremums[i+1].price;
          zz_i[index_2] = 1;
          break;
      
      }
    }
  }

  return(rates_total);
}

И вроде всё сделал  как надо, но в результате вижу следующее:

Не понимаю, в чём причина данного бага, если я всё сделал правильно?

 
Mihail Matkovskij:

Не понимаю, в чём причина данного бага, если я всё сделал правильно?

Нет, не все правильно. Как минимум:

PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0);
PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, 0);

вместо 2 и 3 должны быть 0 и 1 (номера граф. серий с 0 начинаются).

 
Alexey Kozitsyn:

Нет, не все правильно. Как минимум:

вместо 2 и 3 должны быть 0 и 1 (номера граф. серий с 0 начинаются).

Большое спасибо, Алексей! Сделал, всё работает. Но только не понимаю, как это индексы второй графической серии в моём индикаторе могут начинаться с 0. Я прописал:
#property indicator_plots   2 

То, есть, одна графическая серия для МА, вторая для Зиг-Зага. Если я захочу задать PLOT_EMPTY_VALUE для графической серии МА, то я сделаю следующее:

PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0);

Для Зиг-Зага будет:

PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0);
PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0);
То есть, уже с первого индекса. Или я снова путаю что-то?
 
Mihail Matkovskij:
Большое спасибо, Алексей! Сделал, всё работает. Но только не понимаю, как это индексы второй графической серии в моём индикаторе могут начинаться с 0. Я прописал:

То, есть, одна графическая серия для МА, вторая для Зиг-Зага. Если я захочу задать PLOT_EMPTY_VALUE для графической серии МА, то я сделаю следующее:

Для Зиг-Зага будет:

То есть, уже с первого индекса. Или я снова путаю что-то?

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

Соответственно, если указываете количество indicator_plots 2, то индексы их в PlotInfo..() будут 0 и 1.

Документация по MQL5: Стандартные константы, перечисления и структуры / Константы индикаторов / Стили рисования
Документация по MQL5: Стандартные константы, перечисления и структуры / Константы индикаторов / Стили рисования
  • www.mql5.com
При создании пользовательского индикатора можно указать один из 18 типов графического построения (способа отображения на главном окне графика или в подокне графика), значения которых указаны в перечислении ENUM_DRAW_TYPE. В зависимости от стиля рисования, может потребоваться от одного до четырех буферов значений (отмеченных как...
 

Или же, поскольку графических серий 2, то индексов тоже 2:

PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0);
PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0);
 
Alexey Kozitsyn:

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

Соответственно, если указываете количество indicator_plots 2, то индексы их в PlotInfo..() будут 0 и 1.

Еще раз, спасибо, Алексей. Я уже догадался, что индексов 2, для МА и для Зиг-Зага. Хотел задать уточняющий вопрос, но Вы раньше ответили :)
 
Mihail Matkovskij:

В том то и дело, что как должно быть скорее всего не получится, потому как, если два буфера, верхний и нижний, имеют одинаковый индекс, то они закрасятся оба в один цвет. Поэтому, сделать разные цвета экстремумов не получится, для этого нужны разные индексы этих экстремумов, что исключает нормальную подсветку такой формации, как внешний бар в Зиг-Заге.

Как это не получится?

#property indicator_chart_window
#property indicator_buffers 3 
#property indicator_plots   1
#property indicator_type1   DRAW_COLOR_ZIGZAG
#property indicator_color1  Red, DodgerBlue 
#property indicator_width1  2
double zz_l[], zz_h[], zz_i[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
    SetIndexBuffer(0, zz_l, INDICATOR_DATA);
    SetIndexBuffer(1, zz_h, INDICATOR_DATA);
    SetIndexBuffer(2, zz_i, INDICATOR_COLOR_INDEX);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   if(prev_calculated == 0)
    {
      ArrayInitialize(zz_l, EMPTY_VALUE);
      ArrayInitialize(zz_h, EMPTY_VALUE);
    for(int i = 0; i < rates_total; i+=5)
     {
      int z = (int)fmod(i, 2);
      if(z > 0)
       {
        zz_l[i] = low[i];
        zz_i[i] = 0;
       }
      else
        {
         zz_h[i] = high[i];
         zz_i[i] = 1;
        }
     }
    }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

В коде выделен фрагмент полностью соответствующий предложенному ранее.

Результат


 
Alexey Viktorov:

Как это не получится?

В коде выделен фрагмент полностью соответствующий предложенному ранее.

Результат


А когда индексы верхнего и нижнего буферов равны между собой?
Причина обращения: