Navigation:Home > Content >

StochAM_+_ema_deviations.mq4

Time: 2018-07-25 | Download file:StochAM_+_ema_deviations.mq4

/*
iCustom(NULL,0,"~StochAM",Kperiod,Dperiod,Slowing,PriceField, Source,SourcePeriod,Window,Sens,Power,Smooth,Signal,Fade, N,i);
где N:
0 - стохастик
1 - сигнальная %D
2 - рез-т нормирования
3 - сглаживание затухания
4 - буфер источника волатильности // не выводится
5 - сырое нормирование // не выводится
*/

#property indicator_separate_window // в окне индикатора
#property indicator_buffers 6
#property indicator_color1 Green // стохастик
#property indicator_color2 Red // сигнальная
#property indicator_maximum 100
#property indicator_minimum 0
#property indicator_level1 80
#property indicator_level2 20

// входные параметры
extern int Kperiod=5; // %K
extern int Dperiod=3; // %D: >0 SMA, <0 EMA
   double kDp; // коэфф.EMA для %D
   bool bDp;
extern int Slowing=3; // замедление
 int Method=0; // метод сглаживания %D
extern int PriceField=0; // 0- High/Low, 1- Close
extern int Source=2; // 0- объем, 1- ATR, 2- ст.дев., 3- Close
extern int SourcePeriod=5; // период источника, <0 EMA, >0 SMA
   double kSp; // коэфф.EMA для SourcePeriod
   bool bSp;
extern int Window=5; // окно нормирования в барах
extern double Sens=2; // порог чувствтительности в пп.или тиках (объем)
   double sens; // порог чувствтительности в ценах или тиках (объем)
extern double Power=2; // степень для передаточной функции
extern int Smooth=1; // сглаживание нормирования
   double kSm; // коэфф.EMA для Smooth
   bool bSl;
extern int Signal=1; // сигнальная
   double kSg; // коэфф.EMA для Signal
   bool bSg;
extern int Fade=12; // затухание сигнальной
   double kFd; // коэфф.EMA для Fade

 int History=0; // 0- все бары

// массивы инд.буферов
double  
   STH[], // стохастик
   SGN[], // сигнальная (%D) стохастика
   NRM[], // рез-т нормирования
   NEG[], // сглаживание затухания
   SRC[], // буфер источника волатильности // не выводится
   NR0[]; // сырое нормирование // не выводится

// общие (глобальные) переменные
bool first=1; // флаг первого запуска

// инициализация
int init()
  {
   first=1; // флаг первого запуска
   string _sth="Stoch("+Kperiod+","+Dperiod+","+Slowing+") ";
   if(Source>0) sens=Sens*Point; // приведение порога к ценам для ценовых источников
   else sens=Sens; 
   if(Sens>0) string _sn=DoubleToStr(Sens,1)+" ";
   // вычисление коэффициентов EMA
   if(Dperiod<0) {Dperiod=-Dperiod; kDp=2.0/(1+Dperiod); bDp=1;} else bDp=0;
   if(SourcePeriod<0) {SourcePeriod=-SourcePeriod; kSp=2.0/(1+SourcePeriod); bSp=1;} else bSp=0;
   if(Smooth<0) {Smooth=-Smooth; kSm=2.0/(1+Smooth); bSl=1;} else bSl=0;
   if(Signal<0) {Signal=-Signal; kSg=2.0/(1+Signal); bSg=1;} else bSg=0;
   kFd=2.0/(1+Fade);

   string _sgfd=" ("+Signal+","+Fade+")";
   
   switch(Source) {
      case 0: string _src=_src+"Volume"; break; // объем
      case 1: _src=_src+"ATR"; break; // ATR
      case 2: _src=_src+"StDev"; break; // ст.девиация
      case 3: _src=_src+"EmaDev"; break; // ст.девиация
      case 4: _src=_src+"Close"; break; // Close
      case 5: _src=_src+"H/L"; // High/Low
     }
   _src=_src+"("+SourcePeriod+")";
   string _nrm=" ["+Window+","+Smooth+"]";
   IndicatorShortName(_sth+_sn+_src+_nrm+_sgfd); 

   // инд.буферы
   SetIndexBuffer(0,STH);
   SetIndexStyle(0,DRAW_LINE);
   SetIndexLabel(0,_sth);

   SetIndexBuffer(1,SGN);
   SetIndexStyle(1,DRAW_LINE,2);
   SetIndexLabel(1,"Sgn("+Slowing+")");

   SetIndexBuffer(2,NRM);
   SetIndexStyle(2,DRAW_NONE);
   SetIndexLabel(2,_nrm);

   SetIndexBuffer(3,NEG);
   SetIndexStyle(3,DRAW_NONE,2);
   SetIndexLabel(3,"Neg"+_sgfd);

   SetIndexBuffer(4,SRC);
   SetIndexStyle(4,DRAW_NONE);
   SetIndexLabel(4,NULL);

   SetIndexBuffer(5,NR0);
   SetIndexStyle(5,DRAW_NONE);
   SetIndexLabel(5,NULL);

   return(0);
  }

// ф-я дополнительной инициализации
int reinit() 
  {
   ArrayInitialize(STH,0.0); // обнуление массива
   ArrayInitialize(SGN,0.0); // обнуление массива
   ArrayInitialize(NRM,0.0); // обнуление массива
   ArrayInitialize(NEG,0.0); // обнуление массива
   ArrayInitialize(SRC,0.0); // обнуление массива
   ArrayInitialize(NR0,0.0); // обнуление массива
   return(0);
  }

int start()
  {
   int ic=IndicatorCounted();
   if(!first && Bars-ic-1>1) ic=reinit(); // если есть пропущенные бары не на подключении - пересчет
   bool ic0=ic==0; // флаг пересчета
   int limit=Bars-ic-1; // кол-во пересчетов
   if(History!=0 && limit>History) limit=History-1; // кол-во пересчетов по истории

   for(int i=limit; i>=0; i--) { // цикл пересчета по ВСЕМ барам
      bool reset=i==limit && ic0; // сброс на первой итерации цикла пересчета
      if(reset) {
         static int BarsPrev=0; // пред. значение Bars
        }
      bool NewBar=(ic0 && i>0) || BarsPrev!=Bars; // первый тик нового бара
//=========================================
      // источник
      int sh=i+SourcePeriod;
      switch(Source) {
         case 0: // объем
            if(bSp) SRC[i]=kSp*Volume[i]+(1-kSp)*SRC[i+1]; // ЕМА
            else { // SMA
               double ma=SRC[i+1]*SourcePeriod-Volume[sh];
               SRC[i]=(ma+Volume[i])/SourcePeriod;
              }
           break; 
         case 1: SRC[i]=iATR(NULL,0,SourcePeriod, i); break; // ATR
         case 2: SRC[i]=iStdDev(NULL,0,SourcePeriod,0,bSp,0, i) ; break; // ст.девиация
         case 3: SRC[i]=iEDev(iMA(NULL,0,1,0,MODE_SMA,PRICE_CLOSE,i),SourcePeriod,i) ; break; // ema.девиация
         case 4: // Close
            if(bSp) SRC[i]=kSp*Close[i]+(1-kSp)*SRC[i+1]; // ЕМА
            else { // SMA
               ma=SRC[i+1]*SourcePeriod-Close[sh];
               SRC[i]=(ma+Close[i])/SourcePeriod;
              }
            break; 
        }
//=========================================
      // нормирование
         // экстремумы
      double max=SRC[ArrayMaximum(SRC,Window,i)];
      double min=SRC[ArrayMinimum(SRC,Window,i)];
      double c=SRC[i];
         // шумоподавление
      double delta=max-min; // размах
      double diff=sens-delta; // разница между порогом чувств. и размахом
      if(diff>0) { // если разница >0 (размах меньше порога), то
         delta=sens; // размах = порогу,
         min-=diff/2; // новое значение минимума
        }
         // нормирование
      if(delta!=0) NR0[i]=MathPow((c-min)/delta,Power);
//==
      // замедление
      if(bSl) NRM[i]=kSm*NR0[i]+(1-kSm)*NRM[i+1]; // EMA
      else { // SMA
         sh=i+Smooth;
         ma=NRM[i+1]*Smooth-NR0[sh];
         NRM[i]=(ma+NR0[i])/Smooth;
        }
//==
      // сигнальная
      if(reset) {static double sgnPrev=0;}
      if(bSg) double sgn=kSg*NRM[i]+(1-kSg)*sgnPrev; // EMA
      else { // SMA
         sh=i+Signal;
         ma=sgnPrev*Signal-NRM[sh];
         sgn=(ma+NRM[i])/Signal;
        }
//==      
      // затухание сигнальной
         // по затуханию
      NEG[i]=kFd*sgn+(1-kFd)*NEG[i+1];
      if(sgn>NEG[i+1]) NEG[i]=sgn;

//=========================================
      // стохастик
      double sth=iStochastic(NULL,0,Kperiod,1,Slowing,0,PriceField,0, i)-50;
      STH[i]=NEG[i]*sth+50; // модуляция номированной волатильностью
         // сигнальная %D
      if(bDp) SGN[i]=kDp*STH[i]+(1-kDp)*SGN[i+1]; // EMA
      else { // SMA
         sh=i+Dperiod;
         ma=SGN[i+1]*Dperiod-STH[sh];
         SGN[i]=(ma+STH[i])/Dperiod;
        }
//=========================================
      // синхронизация
      if(NewBar) {sgnPrev=sgn; BarsPrev=Bars;}
     }   
   first=0; // сброс флага первого цикла
   return(0);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

double edevWork[][2];
double iEDev(double price,double period, int i)
{
   if (ArrayRange(edevWork,0)!=Bars) ArrayResize(edevWork,Bars);
   
   int    r     = Bars-i-1;
   double alpha = 2.0/(1.0+period);
      
      edevWork[r][0] = edevWork[r-1][0]+alpha*(price      -edevWork[r-1][0]);
      edevWork[r][1] = edevWork[r-1][1]+alpha*(price*price-edevWork[r-1][1]);
         
   return(MathSqrt(period*(edevWork[r][1]-edevWork[r][0]*edevWork[r][0])/(period-1.0)));
}

Recommend