//+------------------------------------------------------------------+ //| MultiZigZag | //+------------------------------------------------------------------+ /* 31 октября 2008 г. Внешние параметры - строковые переменные. В каждую переменную записываются параметры для трех зигзагов. Первая цифра - для первого зигзага, вторая - для второго, третья - для третьего. Через запятую. И выводится три зигзага. ExtDepth, ExtDeviation и ExtBackstep - стандартные параметры для зигзага. Если задать ExtDepth=0, то соответствующий зигзаг выводиться не будет. ExtMaxBar - количество баров, на которых рассчитывается зигзаг. GrossPeriod - периоды графиков, по данным с которых строится зигзаг. При записи 0 зигзаг выводится на текущем таймфрейме. ExtReCalculate - количество экстремумов зигзага, начиная с 0, пересчитываемых в режиме реального времени. Применяется для зигзагов со старших таймфреймов. */ #property link "nen" // Отрисовка индикатора в основном окне #property indicator_chart_window // Количество индикаторных буфферов #property indicator_buffers 6 // Цвет индикатора #property indicator_color1 Aqua //#property indicator_color2 Aqua #property indicator_color3 Red //#property indicator_color4 Aqua #property indicator_color5 Yellow //#property indicator_color6 Aqua // Толщина индикаторной линии #property indicator_width1 0 #property indicator_width2 0 #property indicator_width3 0 #property indicator_width4 0 #property indicator_width5 0 #property indicator_width6 0 // Стиль индикаторной линии #property indicator_style1 0 #property indicator_style2 0 #property indicator_style3 0 #property indicator_style4 0 #property indicator_style5 0 #property indicator_style6 0 // ВХОДНЫЕ ПАРАМЕТРЫ ИНДИКАТОРА /* extern string ExtDepth = "14,28,102"; extern string ExtDeviation = "1,8,21"; extern string ExtBackstep = "3,5,12"; extern string ExtMaxBar = "1000,1000,1000"; // Количество обсчитываемых баров (0-все) extern string GrossPeriod = "0,0,0"; // Таймфреймы, на которых рассчитываются зигзаги, 0 - текущий таймфрейм */ extern string ExtDepth = "12,12,12"; extern string ExtDeviation = "5,5,5"; extern string ExtBackstep = "8,8,8"; extern string ExtMaxBar = "1000,300,150"; // Количество обсчитываемых баров (0-все) extern string GrossPeriod = "60,240,1440"; // Таймфреймы, на которых рассчитываются зигзаги, 0 - текущий таймфрейм extern int ExtReCalculate = 3; // Количество экстремумов зигзага старшего таймфрейма, начиная с 0, пересчитываемых // в режиме реального времени int ExtDepth_[]={0,0,0}, ExtDeviation_[]={0,0,0}, ExtBackstep_[]={0,0,0}, ExtMaxBar_[]={0,0,0}, GrossPeriod_[]={0,0,0}; // Индикаторные буферы double LowestBuffer1[],HighestBuffer1[],LowestBuffer2[],HighestBuffer2[],LowestBuffer3[],HighestBuffer3[]; // Вспомогательные буферы double LowestBufferGross1[],HighestBufferGross1[],LowestBufferGross2[],HighestBufferGross2[],LowestBufferGross3[],HighestBufferGross3[]; datetime time2[]={0,0,0}; // Флаги, показывающие, что со старшего тф первоначальное преобразование зигзага произведено bool Grosstf_DT[]={false, false, false}; // Флаги, показывающие, что на истории зигзаг построен bool ZZ_tf[]={false, false, false}; // Значение времени начала и конца второго луча datetime L2LTime[]={0,0,0},L2HTime[]={0,0,0}; // При выходе за значения переменных lBar, hBar и tiZZ производится расчет зигзага // То есть только при выходе за пределы уже посчитанного бара производится расчет. // Это позволяет рассчитывать не на каждом тике. double lBar[]={0,0,0}, hBar[]={0,0,0}; datetime tiZZ[]={0,0,0}; // Переменная для хранения значения Bars int saveBars[]={0,0,0}; int currentBars; // Переменная, хранящая количество баров, на которых рассчитывается зигзаг int limit; //+------------------------------------------------------------------+ //| Initialization function. Начало. | //+------------------------------------------------------------------+ int init() { int i,j,m; // По два индикаторных буффера использовано для счёта каждого зигзага SetIndexBuffer(0,LowestBuffer1); SetIndexBuffer(1,HighestBuffer1); SetIndexBuffer(2,LowestBuffer2); SetIndexBuffer(3,HighestBuffer2); SetIndexBuffer(4,LowestBuffer3); SetIndexBuffer(5,HighestBuffer3); // Стиль исполнения графика в виде ломаной ZigZag SetIndexStyle(0,DRAW_ZIGZAG); SetIndexStyle(1,DRAW_ZIGZAG); SetIndexStyle(2,DRAW_ZIGZAG); SetIndexStyle(3,DRAW_ZIGZAG); SetIndexStyle(4,DRAW_ZIGZAG); SetIndexStyle(5,DRAW_ZIGZAG); // Установка значений индикатора, которые не будут видимы на графике SetIndexEmptyValue(0,0.0); SetIndexEmptyValue(1,0.0); SetIndexEmptyValue(2,0.0); SetIndexEmptyValue(3,0.0); SetIndexEmptyValue(4,0.0); SetIndexEmptyValue(5,0.0); // Имена для окон данных и лэйбы для субъокон SetIndexLabel(0,"Low1" ); SetIndexLabel(1,"High1"); SetIndexLabel(2,"Low2" ); SetIndexLabel(3,"High2"); SetIndexLabel(4,"Low3" ); SetIndexLabel(5,"High3"); _stringtoarray (ExtDepth, ExtDepth_, 3); _stringtoarray (ExtDeviation, ExtDeviation_, 3); _stringtoarray (ExtBackstep, ExtBackstep_, 3); _stringtoarray (ExtMaxBar, ExtMaxBar_, 3); _stringtoarray (GrossPeriod, GrossPeriod_, 3); for (i=0;i<3;i++) { Grosstf_DT[i]=false; ZZ_tf[i]=false; j=GrossPeriod_[i]; GrossPeriod_[i]=_period(i,j); if (ExtDepth_[i]>=ExtBackstep_[i]) m=ExtDepth_[i]; else m=ExtBackstep_[i]; if ((ExtMaxBar_[i]>iBars(NULL,GrossPeriod_[i])-m) || (ExtMaxBar_[i]==0)) limit=iBars(NULL,GrossPeriod_[i])- m; else limit=ExtMaxBar_[i]; if (i==0) { arr_resize(LowestBufferGross1, HighestBufferGross1, limit+m, i); } else if (i==1) { arr_resize(LowestBufferGross2, HighestBufferGross2, limit+m, i); } else if (i==2) { arr_resize(LowestBufferGross3, HighestBufferGross3, limit+m, i); } } currentBars=0; // Завершение инициализации return(0); } //+------------------------------------------------------------------+ //| Initialization function. Конец. | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Расчет индикатора. Начало. | //+------------------------------------------------------------------+ int start() { int i, m; bool calculate; if (Bars-currentBars+1>2) { for (i=0;i<3;i++) { saveBars[i]=0; } } currentBars=Bars; for (i=0;i<3;i++) { // проверки для корректного расчёта индикатора if ((iBars(NULL,GrossPeriod_[i])-12) { calculate=true; Grosstf_DT[i]=false; ZZ_tf[i]=false; if (ExtDepth_[i]>=ExtBackstep_[i]) m=ExtDepth_[i]; else m=ExtBackstep_[i]; if ((ExtMaxBar_[i]>iBars(NULL,GrossPeriod_[i])-m) || (ExtMaxBar_[i]==0)) limit=iBars(NULL,GrossPeriod_[i])- m; else limit=ExtMaxBar_[i]; if (i==0) { arr_resize(LowestBufferGross1, HighestBufferGross1, limit+m, i); ArrayInitialize(LowestBuffer1,0); ArrayInitialize(HighestBuffer1,0); } else if (i==1) { arr_resize(LowestBufferGross2, HighestBufferGross2, limit+m, i); ArrayInitialize(LowestBuffer2,0); ArrayInitialize(HighestBuffer2,0); } else if (i==2) { arr_resize(LowestBufferGross3, HighestBufferGross3, limit+m, i); ArrayInitialize(LowestBuffer3,0); ArrayInitialize(HighestBuffer3,0); } } else { if (lBar[i]>iLow(NULL,GrossPeriod_[i],0) || hBar[i]=0; bar--) { //--- low if (bar(ExtDeviation_[x]*Point))val=0.0; else { for(back=1; back<=ExtBackstep_[x]; back++) { if(val(ExtDeviation_[x]*Point))val=0.0; else { for(back=1; back<=ExtBackstep_[x]; back++) { if(val>HB[j+back])HB[j+back]=0.0; } } } if (j==bar) HB[j]=val; } } // Конец первого большого цикла // Начало второго большого цикла lasthigh=-1; lastlow=-1; for(bar=limit; bar>=0; bar--) { curlow=LB[bar]; curhigh=HB[bar]; if((curlow==0)&&(curhigh==0)) continue; if(curhigh!=0) { if(lasthigh>0) { if(lasthigh0) { if(lastlow>curlow) LB[lastlowpos]=0; else LB[bar]=0; } if((curlow0) {if (jl==1) {L2LTime[x]=iTime(NULL,GrossPeriod_[x],bar);} jl++;} if (HB[bar]>0) {if (jh==1) {L2HTime[x]=iTime(NULL,GrossPeriod_[x],bar);} jh++;} if (jl>1 && jh>1) break; } return(0); } //+------------------------------------------------------------------+ //| Основной ZigZag. Конец. | //+------------------------------------------------------------------+ //-------------------------------------------------------- // Преобразование зигзага со старшего таймфрейма на текущий. // Начало. //-------------------------------------------------------- int ZigZagDT (double& LB[], double& HB[], double& LBG[], double& HBG[], int x) { int i=0, j, jl, jh, ext3=0, end; double el=-1, eh=-1; datetime t1; if (Grosstf_DT[x]) // Режим реального времени. { end=ExtReCalculate+1; t1=iTime(NULL, GrossPeriod_[x],i); for (j=0;ext30) { if (el>=Low[j] || el<0) {el=Low[j]; jl=j;} } else { if (el>0) {LB[jl]=el; el=-1; ext3++;} } if (HBG[i]>0) { if (eh<=High[j]) {eh=High[j]; jh=j;} } else { if (eh>0) {HB[jh]=eh; eh=-1; ext3++;} } } } else // Построение зигзага на истории. { if (limit<=ExtDepth_[x]) {saveBars[x]=0; return (-1);} end=iBarShift(NULL,Period(),iTime(NULL, GrossPeriod_[x],limit),false); if (end<=0) {saveBars[x]=0; return (-1);} Grosstf_DT[x]=true; t1=iTime(NULL, GrossPeriod_[x],i); for (j=0;j0) { if (el>=Low[j] || el<0) {el=Low[j]; jl=j;} } else { if (el>0) {LB[jl]=el; el=-1;} } if (HBG[i]>0) { if (eh<=High[j]) {eh=High[j]; jh=j;} } else { if (eh>0) {HB[jh]=eh; eh=-1;} } } } // Обновление переменных saveBars[x]=iBars(NULL,GrossPeriod_[x]); lBar[x]=iLow(NULL,GrossPeriod_[x],0); hBar[x]=iHigh(NULL,GrossPeriod_[x],0); tiZZ[x]=iTime(NULL,GrossPeriod_[x],0); return (0); } //-------------------------------------------------------- // Преобразование зигзага со старшего таймфрейма на текущий. // Конец. //-------------------------------------------------------- //-------------------------------------------------------- // Проверка корректности задания таймфрейма. Начало. //-------------------------------------------------------- int _period(int x, int tf) { if (tf0;i--) { arr[i]=arr[i-1]; arr1[i]=arr1[i-1]; } arr[0]=0; arr1[0]=0; } //-------------------------------------------------------- // Сдвиг элементов массива на 1 от 0 элемента в сторону увеличения индекса. // Конец. //-------------------------------------------------------- //-------------------------------------------------------- // Изменение размера массивов и присвоение всем элементам значения 0 // Начало. //-------------------------------------------------------- void arr_resize (double& arr[], double& arr1[], int size, int x) { if (GrossPeriod_[x]>0) { ArrayResize(arr,size); ArrayResize(arr1,size); ArrayInitialize(arr,0); ArrayInitialize(arr1,0); } } //-------------------------------------------------------- // Изменение размера массивов и присвоение всем элементам значения 0 // Конец. //-------------------------------------------------------- //-------------------------------------------------------- // Перенос значений параметров из строки в массив // Начало. //-------------------------------------------------------- void _stringtoarray (string str, int& arr[], int x) { int i,j,k=0; for (i=0;i