//+------------------------------------------------------------------+ //| ProjectName | //| Copyright 2012, CompanyName | //| http://www.companyname.net | //+------------------------------------------------------------------+ /* вызов из пользовательских кодов: iCustom(string symbol, int timeframe, "_StDevFBA", int ma_period, int ma_shift, int ma_method, int applied_price, double FrontPeriod, double BackPeriod, int shift) iCustom(NULL,0,"_StDevFBA",StDperiod,StDshift,StDmethod,PriceField,FrontPeriod,BackPeriod, 0,i); // ст.девиация iCustom(NULL,0,"_StDevFBA",StDperiod,StDshift,StDmethod,PriceField,FrontPeriod,BackPeriod, 1,i); // сигнальная */ #property indicator_separate_window #property indicator_buffers 2 #property indicator_color1 Green // стандартная девиация #property indicator_color2 Red // сигнальная // входные параметры extern int StDperiod=20; // период ст.девиации extern int StDshift=0; // сдвиг extern int StDmethod=0; // метод сглаживания extern int PriceField=0; // тип цены extern double FrontPeriod=1; // период предварительного сглаживания; м.б. <1 extern double BackPeriod=55; // период раздельного сглаживания; м.б. <1 int History=0; // кол-во пересчетов; 0 - все бары // инд.буферы double StD[], // стандартная девиация EMA[]; // сигнальная // общие переменные bool first=1; // флаг первого запуска double per0,per1; // коэфф-ты EMA int FBA=0; // 1 - сглаживание фронта, -1 - сглаживание затухания, 0 - обычная MA - гладим все! //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ 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); string ShortName="StDev("+StDperiod+") "; 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; 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,StD); SetIndexStyle(0,DRAW_LINE,0); SetIndexLabel(0,"StDev("+StDperiod+")"); // сигнальная SetIndexBuffer(1,EMA); SetIndexStyle(1,DRAW_LINE,0); SetIndexLabel(1,"EMA("+_fr+","+_bk+")"); return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int reinit() // ф-я дополнительной инициализации { ArrayInitialize(StD,0.0); ArrayInitialize(EMA,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; static int BarsPrev=0;} // стандартная девиация StD[i]=iStdDev(NULL,0,StDperiod,StDshift,StDmethod,PriceField,i); // предварительное сглаживание double MA0=EMA_FBA(StD[i],MA0prev,per0,0,i); // раздельное сглаживание (сигнальная) EMA[i]=EMA_FBA(MA0,EMA[i+1],per1,FBA,i); // синхронизация if(first || BarsPrev!=Bars) {BarsPrev=Bars; MA0prev=MA0;} } 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