/* Bollinger Bands с различными параметрами сглаживания ст. девиации для фронта и затухания вызов из пользовательских кодов: iCustom( string symbol, int timeframe, "_BandsFBA", int period, double deviation, int bands_shift, int applied_price, double FrontPeriod, double BackPeriod, int mode, int shift); iCustom(NULL,0,"_BandsFBA",BandsPeriod,Deviation,BandsShift,PriceField,FrontPeriod,BackPeriod, 1,i); // верхняя гр. iCustom(NULL,0,"_BandsFBA",BandsPeriod,Deviation,BandsShift,PriceField,FrontPeriod,BackPeriod, 2,i); // нижняя гр. iCustom(NULL,0,"_BandsFBA",BandsPeriod,Deviation,BandsShift,PriceField,FrontPeriod,BackPeriod, 4,i); // верхняя сглаженная гр. iCustom(NULL,0,"_BandsFBA",BandsPeriod,Deviation,BandsShift,PriceField,FrontPeriod,BackPeriod, 5,i); // нижняя сглаженная гр. */ #property indicator_chart_window #property indicator_buffers 6 #property indicator_color1 MediumSeaGreen // MA #property indicator_color2 MediumSeaGreen // верхняя линия #property indicator_color3 MediumSeaGreen // нижняя линия #property indicator_color4 Red // MA сигнальная #property indicator_color5 Red // верхняя сигнальная #property indicator_color6 Red // нижняя сигнальная // входные параметры // Bollinger Bands extern int BandsPeriod=20; // период ст.девиации extern double Deviation=2; // девиация extern int BandsShift=0; // сдвиг индикатора extern int PriceField=0; // тип цены (станд. значения) // сигнальная extern double FrontPeriod=1; // период предварительного сглаживания; м.б. <1 extern double BackPeriod=55; // период раздельного сглаживания; м.б. <1 int History=0; // кол-во пересчетов; 0 - все бары // инд.буферы double SMA[], // SMA TopB[], // верхняя линия BotB[], // нижняя линия SMAS[], // верхняя сигнальная TopS[], // верхняя сигнальная BotS[]; // нижняя сигнальная // общие переменные bool first=1; // флаг первого запуска double per0,per1; // коэфф-ты EMA int FBA=0; // 1 - сглаживание фронта, -1 - сглаживание затухания, 0 - обычная MA - гладим все! int init() { first=1; int fdg,bdg,ddg; // разрядность отображения периодов if(FrontPeriod<1) fdg=2; if(BackPeriod<1) bdg=2; if(Deviation-MathRound(Deviation)!=0) ddg=2; string _fr=DoubleToStr(FrontPeriod,fdg); string _bk=DoubleToStr(BackPeriod,bdg); string _dv=DoubleToStr(Deviation,ddg); if(FrontPeriod>1) FrontPeriod=2.0/(1+FrontPeriod); // коэфф. предварительной EMA if(BackPeriod>1) BackPeriod=2.0/(1+BackPeriod); // коэфф. раздельной EMA while(true) { if(FrontPeriod==BackPeriod) { per0=FrontPeriod; per1=1; string _sg=_fr; break; } if(FrontPeriod>BackPeriod) { FBA=-1; per0=FrontPeriod; per1=BackPeriod; _sg=_fr; } else { FBA= 1; per0=BackPeriod; per1=FrontPeriod; _sg=_bk; } break; } // инд. буферы // SMA - медиана Bollinger Bands SetIndexBuffer(0,SMA); SetIndexStyle(0,DRAW_LINE); SetIndexLabel(0,"SMA("+BandsPeriod+")"); // верхняя линия SetIndexBuffer(1,TopB); SetIndexStyle(1,DRAW_LINE); SetIndexLabel(1,"TopB(+"+_dv+")"); // нижняя линия SetIndexBuffer(2,BotB); SetIndexStyle(2,DRAW_LINE); SetIndexLabel(2,"BotB(-"+_dv+")"); // SMA - медиана Bollinger Bands сигнальная SetIndexBuffer(3,SMAS); SetIndexStyle(3,DRAW_LINE); SetIndexLabel(3,"SMAS("+_sg+")"); // верхняя сигнальная линия SetIndexBuffer(4,TopS); SetIndexStyle(4,DRAW_LINE); SetIndexLabel(4,"TopS("+_fr+","+_bk+")"); // нижняя сигнальная линия SetIndexBuffer(5,BotS); SetIndexStyle(5,DRAW_LINE); SetIndexLabel(5,"BotS("+_fr+","+_bk+")"); return(0); } int reinit() // ф-я дополнительной инициализации { ArrayInitialize(SMA,0.0); ArrayInitialize(TopB,0.0); ArrayInitialize(BotB,0.0); ArrayInitialize(TopS,0.0); ArrayInitialize(BotS,0.0); return(0); } int start() { int ic=IndicatorCounted(); if(!first && Bars-ic-1>1) ic=reinit(); // int limit=Bars-ic-1; // кол-во пересчетов // if(History!=0 && limit>History) limit=History-1; // кол-во пересчетов по истории int counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; int limit=Bars-counted_bars; if(counted_bars==0) limit-=2; for(int i=limit; i>=0; i--) { // цикл пересчета по ВСЕМ барам bool reset=i==limit && ic==0; // сброс на первой итерации цикла пересчета if(reset) { static double MA0prev=0,MA1prev=0,sma0prev=0; static int BarsPrev=0; } int sh=i+BandsShift; // сдвиг // медиана Bollinger Bands double sma=iMA(NULL,0,BandsPeriod,0,0,PriceField, sh); SMA[i]=sma; // стандартная девиация double st=iStdDev(NULL,0,BandsPeriod,0,0,PriceField, sh); double std=Deviation*st; // линии Bollinger Bands TopB[i]=sma+std; // верхняя линия BotB[i]=sma-std; // нижняя линия // предварительное сглаживание double MA0=EMA_FBA(st,MA0prev,per0,0,i); double sma0=EMA_FBA(sma,sma0prev,per0,0,i); SMAS[i]=sma0; // сглаживание (сигнальная) double MA1=EMA_FBA(MA0,MA1prev,per1,FBA,i); // девиация сигнальных std=Deviation*MA1; // сигнальные линии TopS[i]=sma0+std; // верхняя линия BotS[i]=sma0-std; // нижняя линия // синхронизация if(first || BarsPrev!=Bars) {BarsPrev=Bars; MA0prev=MA0; MA1prev=MA1; sma0prev=sma0;} } first=0; // сброс флага первого запуска return(0); } // EMA с различными параметрами сглаживания для фронта и затухания double EMA_FBA(double C, double MA1, double period, int FBA, int i) { if(period==1) return(C); // коэфф. EMA if(period>1) period=2.0/(1+period); // EMA double ma=period*C+(1-period)*MA1; // разделение фронта и затухания switch(FBA) { case 0: // обычная MA if(FBA==0) return(ma); case 1: // сглаживание фронта if(C>MA1) return(ma); else return(C); case -1: // сглаживание затухания if(C