#property indicator_chart_window // в окне инструмента #property indicator_buffers 3 #property indicator_color1 Aqua #property indicator_color3 Blue //--внешние переменные extern double Step=0.02; // начальное значение и шаг extern double Maximum=0.2; // конечное значение extern bool ExtremumsShift=1; // положение экстремумов: 0 - по времени их определния; 1 - по их фактическому положению extern int History=0; // кол-во баров предыстории; 0 - все //-- double Peak[], // буфер ZigZag по пикам Trough[], // буфер ZigZag по впадинам SAR[]; // буфер Parabolic //============================================================= int init() { SetIndexBuffer(0,Peak); // пики SetIndexStyle(0,DRAW_ZIGZAG); SetIndexLabel(0,"Peak"); SetIndexEmptyValue(0,0.0); SetIndexBuffer(1,Trough); // кресты, т.е. впадины))) SetIndexStyle(1,DRAW_ZIGZAG); SetIndexLabel(1,"Trough"); SetIndexEmptyValue(1,0.0); SetIndexBuffer(2,SAR); // Параболик SetIndexStyle(2,DRAW_ARROW); SetIndexArrow(2,159); SetIndexLabel(2,"SAR"); SetIndexEmptyValue(2,0.0); return(0); } //============================================================= int start() { static int BarsPrev; // значение Bars на пред.баре bool MissBars=Bars-BarsPrev>1; // 1 - есть пропущенные бары bool NewBar=Bars-BarsPrev==1; // 1 - первый тик нулевого бара if(MissBars && BarsPrev!=0) BarsPrev=reinit(); // пропущенные бары в процессе - пересчет заново int limit=Bars-BarsPrev-(BarsPrev==0); BarsPrev=Bars; // кол-во пересчетов if(History!=0 && limit>History) limit=History-1; // кол-во пересчетов по истории int counted_bars = IndicatorCounted(); if(counted_bars < 0) return(-1); if(counted_bars > 0) counted_bars--; limit = Bars - counted_bars; if(counted_bars==0) limit-=2+ExtremumsShift*10; for(int i=limit; i>=0; i--) // цикл по непосчитанным и предпоследнему барам { SAR[i]=iSAR(NULL,0,Step,Maximum, i); // Параболик double mid[2]; // ср. цена mid[0]=(High[i]+Low[i])/2; // ср.цена на текущем баре mid[1]=(High[i+1]+Low[i+1])/2; // ср.цена на пред.баре static int j; // счетчик смещения между моментом определеня экстремума и его положением во времени static bool dir; // флаг направления; 0 - вниз, 1 - вверх static double h,l; // текущие экстремальные значения int shift; // смещение между моментом определеня экстремума и его положением во времени if(i>0) j++; // если бар завершен, то инкремент счетчика смещения if(dir) // ловля пика { if(hmid[0]) // переворот Параболика вниз { shift=i+ExtremumsShift*(j+NewBar); // смещение if (shift>=ArraySize(Peak)) break; Peak[shift]=h; // пик dir=0; // направление вниз l=Low[i]; j=0; // текущий максимум, сброс счетчика смещения } } else // ловля впадины { if(l>Low[i]) {l=Low[i]; j=NewBar;} // текущий минимум; сброс счетчика смещения if(SAR[i+1]>=mid[1] && SAR[i]=ArraySize(Trough)) break; Trough[shift]=l; // впадина dir=1; // направление вверх h=High[i]; j=0; // текущий максимум, сброс счетчика смещения } } } // if(MissBars) Print("limit: ",limit," Bars:",Bars," IndicatorCounted: ",IndicatorCounted()); return(0); } //============================================================= // ф-я дополнительной инициализации int reinit() { ArrayInitialize(Peak,0.0); ArrayInitialize(Trough,0.0); ArrayInitialize(SAR,0.0); return(0); }