/* Bollinger Bands Oscillator с различными параметрами сглаживания ст. девиации для фронта и затухания вызов из пользовательских кодов: iCustom( string symbol, int timeframe, "_BandsFBA_NR_Osc", int period, int bands_shift, int applied_price, double FrontPeriod, double BackPeriod, int mode, int Sens, int shift); iCustom(NULL,0,"_BandsFBA_NR_Osc",BandsPeriod,BandsShift,OscPrice,FrontPeriod,BackPeriod,Sens, 0,i); // главная. iCustom(NULL,0,"_BandsFBA_NR_Osc",BandsPeriod,BandsShift,OscPrice,FrontPeriod,BackPeriod,Sens, 1,i); // сигнальная */ #property indicator_separate_window #property indicator_buffers 2 #property indicator_color1 MediumSeaGreen // главная #property indicator_color2 Red // сигнальная #property indicator_level1 100 #property indicator_level2 0 // входные параметры // Bollinger Bands extern int BandsPeriod=20; // период ст.девиации double Deviation=2; // девиация extern int BandsShift=0; // сдвиг индикатора extern int OscPrice=0; // тип цены (станд. значения) // сигнальная extern double FrontPeriod=1; // период сглаживания фронта; м.б. <1 extern double BackPeriod=55; // период сглаживания затухания; м.б. <1 // порог extern int Sens=0; // порог чувствительности в пп. int History=0; // кол-во пересчетов; 0 - все бары // инд.буферы double Main[], // главная Sign[]; // сигнальная // общие переменные bool first=1; // флаг первого запуска double per0,per1; // коэфф-ты EMA int FBA=0; // 1 - сглаживание фронта, -1 - сглаживание затухания, 0 - обычная MA - гладим все! double sens; // порог чувствительности в ценах int init() { // короткое имя int fdg,bdg; if(FrontPeriod<1) fdg=2; if(BackPeriod<1) bdg=2; string _fr=DoubleToStr(FrontPeriod,fdg); string _bk=DoubleToStr(BackPeriod,bdg); if(Sens>0) string ShortName=Sens+" "; ShortName=ShortName+"BandsOsc"+_Price(OscPrice)+"("+BandsPeriod+")"; if(BandsShift>0) ShortName=ShortName+"+"+BandsShift; if(FrontPeriod!=1 || BackPeriod!=1) { if(FrontPeriod==BackPeriod) ShortName=ShortName+" ("+_fr+")"; else { if(FrontPeriod!=1) ShortName=ShortName+" Front("+_fr+")"; if(BackPeriod!=1) ShortName=ShortName+" Back(" +_bk+")"; } } IndicatorShortName(ShortName); first=1; sens=Sens*Point; // порог чувствительности в ценах 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; break; } if(FrontPeriod>BackPeriod) { FBA=-1; per0=FrontPeriod; per1=BackPeriod; } else { FBA= 1; per0=BackPeriod; per1=FrontPeriod; } break; } // инд. буферы // главная линия SetIndexBuffer(0,Main); SetIndexStyle(0,DRAW_LINE); SetIndexLabel(0,"Main("+BandsPeriod+")"); // сигнальная линия SetIndexBuffer(1,Sign); SetIndexStyle(1,DRAW_LINE); SetIndexLabel(1,"Sign("+_fr+","+_bk+")"); return(0); } int reinit() // ф-я дополнительной инициализации { ArrayInitialize(Main,0.0); ArrayInitialize(Sign,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--; 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,0, sh); // стандартная девиация double st=iStdDev(NULL,0,BandsPeriod,0,0,0, sh); st=MathMax(st,sens); // учет порога чувствтительности double std=Deviation*st; // девиация // линии Bollinger Bands double topB=sma+std; // верхняя линия double botB=sma-std; // нижняя линия // предварительное сглаживание double MA0=EMA_FBA(st,MA0prev,per0,0,i); double sma0=EMA_FBA(sma,sma0prev,per0,0,i); // сглаживание (сигнальная) double MA1=EMA_FBA(MA0,MA1prev,per1,FBA,i); // девиация сигнальных std=Deviation*MA1; // сигнальные линии double topS=sma0+std; // верхняя линия double botS=sma0-std; // нижняя линия // осциллятор // главная double price=Price(OscPrice,i); double deltaB=topB-botB; // ширина канала if(deltaB==0) double main=1; else main=(price-botB)/deltaB; Main[i]=100*main; // сигнальная double deltaS=topS-botS; // ширина канала if(deltaS==0) double sign=1; else sign=(price-botS)/deltaS; Sign[i]=100*sign; // синхронизация 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