После того, как цветной Зиг-Заг не заработал в моей программе, я решил проверить его с помощью простого кода:
Смотрел пример из справки. Вроде все сделал правильно... Но не работает!
Получается, примерно, следующее:
После сжатия графика, стало видно нулевой уровень (где, собственно, ничего видно быть не должно (так, как это PLOT_EMPTY_VALUE, по умолчанию))
В чем причина данного бага, это Зиг-Заг сам по себе лагает или я что-то упустил?
После того, как цветной Зиг-Заг не заработал в моей программе, я решил проверить его с помощью простого кода:
Смотрел пример из справки. Вроде все сделал правильно... Но не работает!
Получается, примерно, следующее:
После сжатия графика, стало видно нулевой уровень (где, собственно, ничего видно быть не должно (так, как это 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; } }
Плюс ко всему такой вариант будет работать только при запуске. Надеюсь, что это написано исключительно для тренировки и в окончательной версии будет сделано как должно быть.
Я-бы добавил проверку на чётность счётчика цикла и соответственно чередование цветности линии.
Плюс ко всему такой вариант будет работать только при запуске. Надеюсь, что это написано исключительно для тренировки и в окончательной версии будет сделано как должно быть.
В том то и дело, что как должно быть скорее всего не получится, потому как, если два буфера, верхний и нижний, имеют одинаковый индекс, то они закрасятся оба в один цвет. Поэтому, сделать разные цвета экстремумов не получится, для этого нужны разные индексы этих экстремумов, что исключает нормальную подсветку такой формации, как внешний бар в Зиг-Заге.
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); }
И вроде всё сделал как надо, но в результате вижу следующее:
Не понимаю, в чём причина данного бага, если я всё сделал правильно?
Не понимаю, в чём причина данного бага, если я всё сделал правильно?
Нет, не все правильно. Как минимум:
PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0); PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, 0);
вместо 2 и 3 должны быть 0 и 1 (номера граф. серий с 0 начинаются).
Нет, не все правильно. Как минимум:
вместо 2 и 3 должны быть 0 и 1 (номера граф. серий с 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);То есть, уже с первого индекса. Или я снова путаю что-то?
Большое спасибо, Алексей! Сделал, всё работает. Но только не понимаю, как это индексы второй графической серии в моём индикаторе могут начинаться с 0. Я прописал:
То, есть, одна графическая серия для МА, вторая для Зиг-Зага. Если я захочу задать PLOT_EMPTY_VALUE для графической серии МА, то я сделаю следующее:
Для Зиг-Зага будет:
То есть, уже с первого индекса. Или я снова путаю что-то?Графическая серия может включать несколько буферов (например, отображение в виде свечей - 4 буфера, в виде цветного зиг-зага - 3 буфера).
Соответственно, если указываете количество indicator_plots 2, то индексы их в PlotInfo..() будут 0 и 1.
- www.mql5.com
Или же, поскольку графических серий 2, то индексов тоже 2:
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0); PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0);
Графическая серия может включать несколько буферов (например, отображение в виде свечей - 4 буфера, в виде цветного зиг-зага - 3 буфера).
Соответственно, если указываете количество indicator_plots 2, то индексы их в PlotInfo..() будут 0 и 1.
В том то и дело, что как должно быть скорее всего не получится, потому как, если два буфера, верхний и нижний, имеют одинаковый индекс, то они закрасятся оба в один цвет. Поэтому, сделать разные цвета экстремумов не получится, для этого нужны разные индексы этих экстремумов, что исключает нормальную подсветку такой формации, как внешний бар в Зиг-Заге.
Как это не получится?
#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); } //+------------------------------------------------------------------+
В коде выделен фрагмент полностью соответствующий предложенному ранее.
Результат
Как это не получится?
В коде выделен фрагмент полностью соответствующий предложенному ранее.
Результат
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
После того, как цветной Зиг-Заг не заработал в моей программе, я решил проверить его с помощью простого кода:
Смотрел пример из справки. Вроде все сделал правильно... Но не работает!
Получается, примерно, следующее:
После сжатия графика, стало видно нулевой уровень (где, собственно, ничего видно быть не должно (так, как это PLOT_EMPTY_VALUE, по умолчанию))
В чем причина данного бага, это Зиг-Заг сам по себе лагает или я что-то упустил?