//+------------------------------------------------------------------+ //| CompRSI.mq5 | //| Component Relative Strength Index | //| Copyright 2017, YUBA. | //| https://www.mql5.com/ru/users/yuba | //+------------------------------------------------------------------+ #property copyright "2017,YUBA" #property link "https://www.mql5.com/ru/users/yuba" #property description "Component Relative Strength Index" //--- indicator settings #property indicator_separate_window #property indicator_buffers 4 #property indicator_plots 2 #property indicator_type1 DRAW_LINE #property indicator_color1 Green #property indicator_width1 2 #property indicator_type2 DRAW_LINE #property indicator_color2 Red #property indicator_width2 2 //--- input parameters enum OnOff {Off=0,On=1}; input double InpT=40.0; //Period RSI input OnOff SmoothPRSI=On; //Smoothing RSI On/Off input double inpSmPeriodRSI = 8; //Smoothing RSI Period double T; double SmPeriodRSI=8; //--- indicator buffers double ExtPosBuffer[]; double ExtNegBuffer[]; double ExtPosBuffer2[]; double ExtNegBuffer2[]; //--- global variable int ExtPeriodRSI; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ void OnInit() { //--- check for input if(InpT<2) { T=2; Print("Incorrect value for input variable InpT =",InpT, "Indicator will use value =",T,"for calculations."); } else T=InpT; if( inpSmPeriodRSI<2) { T=SmPeriodRSI; Print("Incorrect value for input variable InpT =",inpSmPeriodRSI, "Indicator will use value =",SmPeriodRSI,"for calculations."); } else SmPeriodRSI=inpSmPeriodRSI; //--- indicator buffers mapping SetIndexBuffer(0,ExtPosBuffer,INDICATOR_DATA); SetIndexBuffer(1,ExtNegBuffer,INDICATOR_DATA); SetIndexBuffer(2,ExtPosBuffer2,INDICATOR_CALCULATIONS); SetIndexBuffer(3,ExtNegBuffer2,INDICATOR_CALCULATIONS); //--- set accuracy IndicatorSetInteger(INDICATOR_DIGITS,5); //--- sets first bar from what index will be drawn PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,(int)T+1); PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,(int)T+1); PlotIndexSetString(0,PLOT_LABEL,"Bulls"); PlotIndexSetString(1,PLOT_LABEL,"Bears"); //--- name for DataWindow and indicator subwindow label IndicatorSetString(INDICATOR_SHORTNAME,"CompRSI("+string(T)+")"); //--- initialization done } //+------------------------------------------------------------------+ //| component Relative Strength Index | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { int i; double diff; //--- check for rates count if(rates_total<=2.0*T) return(0); //--- preliminary calculations int pos=prev_calculated-1; if(pos<=0) { //--- first RSIPeriod values of the indicator are not calculated ExtPosBuffer[0]=0.0; ExtNegBuffer[0]=0.0; ExtPosBuffer2[0]=0.0; ExtNegBuffer2[0]=0.0; double SumP=0.0; double SumN=0.0; double SumP2=0.0; double SumN2=0.0; i=1; diff=close[i]-close[i-1]; SumP+=(diff>=0?diff:0); SumN+=(diff<=0?-diff:0); ExtPosBuffer[i]=SumP; ExtNegBuffer[i]=SumN; SumP2+=(diff>=0?diff:0); SumN2+=(diff<=0?-diff:0); ExtPosBuffer2[i]=SumP2; ExtNegBuffer2[i]=SumP2; //--------------------------------------------------------- //--- prepare the position value for main calculation pos=i+1; } //--- the main loop of calculations for(i=pos;i=0.0 ? diff:0; diffN=diff<=0.0 ? -diff:0; ExtPosBuffer2[i]= ema(diffP,ExtPosBuffer2[i-1]); ExtNegBuffer2[i]=ema(diffN,ExtNegBuffer2[i-1]); switch(SmoothPRSI) { case Off: { ExtPosBuffer[i]=ExtPosBuffer2[i]; ExtNegBuffer[i]=ExtNegBuffer2[i]; break; } case On: { ExtPosBuffer[i]=emaSP(ExtPosBuffer2[i],ExtPosBuffer[i-1]); ExtNegBuffer[i]=emaSP(ExtNegBuffer2[i],ExtNegBuffer[i-1]); } } } //--- OnCalculate done. Return new prev_calculated. return(rates_total); } //+------------------------------------------------------------------+ double ema(double x,double prevy) { return(x/T +(1.0-1.0/T)*prevy ); } double emaSP(double x,double prevy) { return(x/SmPeriodRSI +(1.0-1.0/SmPeriodRSI)*prevy ); }