Download MetaTrader 5
To add comments, please log in or register
One billion tasks have already been executed with MQL5 Cloud Network. Test trading robots even faster!
Felipe Villegas
31
Felipe Villegas 2014.08.11 22:36 

Hello,

I'm trying to make an indicator that takes 4 entry values (Stochastic Oscillator, Stochastic Oscillator Slow, RSI(9) and RSI(14)), powers them to some set weights (w11 to w14) and then multiplies the result to store it in a variable (S1). Then, this variable is multiplied by another set weight (c1) and adds it to the same calculation (S2) but with different weights (w21 to w24 & c2). The result of the sum is stored in the variable ExtOutput[]. If I draw ExtOutput[], the indicator works fine but the range of the result is meant to be between 0 and 100 (similar to the Stochastic Oscillator) but because of the calculations, it varies between 0.2 and 1.4. 

 

I've tried to normalize the results using a standard formula:

 

Buf_0[i] = (ExtOutput[] -  ExtOutput[ArrayMinimum(ExtOutput,WHOLE_ARRAY,0)])*100/(ExtOutput[ArrayMaximum(ExtOutput,WHOLE_ARRAY,0)] - ExtOutput[ArrayMinimum(ExtOutput,WHOLE_ARRAY,0)]);

 

When I enter this code, the indicator stops working and it does not draw. Trying to figure out the error, I found out that the maximum value I get with ArrayMaximum() is 2147483647 (EMPTY_VALUE) so the normalization formula gives values close to 0 due to the high number in the denominator. 

 

Does anyone know how to fix this issue?. I need the output of ExtOutput[] to be ranged from 0 to 100 so I can draw it in the chart. Code is down below, thanks in advance! 

 

//+------------------------------------------------------------------+
//|                                                    NEVOStoch.mq4 |
//|                               Escuela de Ingeniería de Antioquia |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Escuela de Ingeniería de Antioquia"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_minimum    0
#property indicator_maximum    100
#property indicator_buffers 2
#property indicator_color1 Green     
// Color of the 1st line
#property indicator_color2 White      
// Color of the 2nd line
#property indicator_level1     80
#property indicator_level2     20
#property indicator_levelcolor clrSilver
#property indicator_levelstyle STYLE_DOT

int Kperiod = 14; //Oscillator Period
int Ksuaviz = 3;  //SMA Period
int Dperiod = 3;  //Slowing Period  
int RSIPeriod14=14;  //RSI14 Period
int RSIPeriod9=9;    //RSI9 Period
double ExtRSIBuffer9[];   //Output of the RSI9
double ExtPosBuffer9[];
double ExtNegBuffer9[];
double ExtRSIBuffer14[];   //Output of the RSI14
double ExtPosBuffer14[];
double ExtNegBuffer14[];
double Main[], Signal[]; //Outputs of %K and %D
double CurrentH[], CurrentL[];   //Variables for calculating max and min   
double ExtOutput[];  //Output of the power process
double Buf_0[], Buf_1[];   //Indicator lines 
double SNorm[]; //Output of the normalization process
int Counted_bars;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
  string short_name;
//--- indicator buffers mapping
//Additional buffers------------------------------
   IndicatorBuffers(14);
   SetIndexBuffer(2,CurrentH);
   SetIndexBuffer(3,CurrentL);
   SetIndexBuffer(4,Main);
   SetIndexBuffer(5,Signal);
   SetIndexBuffer(6,ExtRSIBuffer9);
   SetIndexBuffer(7,ExtRSIBuffer14);
   SetIndexBuffer(8,ExtNegBuffer9);
   SetIndexBuffer(9,ExtNegBuffer14);
   SetIndexBuffer(10,ExtPosBuffer9);
   SetIndexBuffer(11,ExtPosBuffer14);
   SetIndexBuffer(12,SNorm);
   SetIndexBuffer(13,ExtOutput);
   
   
//-------------------------------------------------
   SetIndexBuffer(0,Buf_0);
   SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,1);
//-------------------------------------------------
   SetIndexBuffer(1,Buf_1);
   SetIndexStyle(1,DRAW_LINE,STYLE_DASH,1);
//-------------------------------------------------
//name for data window and subwindow---------------
   short_name = "NEVOStoch(FastK,SlowK,RSI9,RSI14)";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);
   SetIndexLabel(1,"NEVOStoch[SMA(3)]");



   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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, k, pos;
   double diff9,diff14;
   
   //---
   if(Bars<=RSIPeriod9)
      return(0);
   //---
   if(Bars<=RSIPeriod14)
      return(0);   
   //--- counting from 0 to rates_total
   ArraySetAsSeries(Main,false);
   ArraySetAsSeries(Signal,false);
   ArraySetAsSeries(CurrentH,false);
   ArraySetAsSeries(CurrentL,false);
   ArraySetAsSeries(Buf_0,false);
   ArraySetAsSeries(Buf_1,false);
   ArraySetAsSeries(ExtRSIBuffer9,false);
   ArraySetAsSeries(ExtPosBuffer9,false);
   ArraySetAsSeries(ExtNegBuffer9,false);
   ArraySetAsSeries(ExtRSIBuffer14,false);
   ArraySetAsSeries(ExtPosBuffer14,false);
   ArraySetAsSeries(ExtNegBuffer14,false);   
   ArraySetAsSeries(ExtOutput,false);
   ArraySetAsSeries(SNorm,false);
   ArraySetAsSeries(low,false);
   ArraySetAsSeries(high,false);
   ArraySetAsSeries(close,false);

   
 //--------------------------------------------
    pos=Kperiod-1; //definition of start position
   if(pos+1<prev_calculated)
      pos=prev_calculated-2;
   else
     {
      for(i=0; i<pos; i++)
        {
         CurrentH[i]=0.0;
         CurrentL[i]=0.0;
        }
     }

//-----------------------------------------------------------
//                      ENTRY VALUES 
//-----------------------------------------------------------
//max and min calculation
      for(i=pos; i<rates_total && !IsStopped(); i++)
      {
      double dmin=1000000.0;
      double dmax=-1000000.0;
      
      for (k=i-Kperiod+1; k<=i; k++)
      {
         if (dmin>low[k])
            dmin=low[k];
         if (dmax<high[k])
            dmax=high[k];   
      }
      CurrentH[i]=dmax;
      CurrentL[i]=dmin;
      }
 //--- %K line
   pos=Kperiod-1+Ksuaviz-1;
   if(pos+1<prev_calculated)
      pos=prev_calculated-2;
   else
     {
      for(i=0; i<pos; i++)
         Main[i]=0.0;
     }     
      
      
//calculation of %K-----------------KFast      
      for(i=pos; i<rates_total && !IsStopped(); i++)
      {
      double SumaNumerador = 0.0;
      double SumaDenominador = 0.0;
      for(k=(i-Ksuaviz+1); k<=i; k++)
        {
         SumaNumerador+=(close[k]-CurrentL[k]);
         SumaDenominador+=(CurrentH[k]-CurrentL[k]);
        }
      if(SumaDenominador==0.0)
         Main[i]=1.0;
      else
         Main[i]=SumaNumerador/SumaDenominador;
     }
//calculation of %D-----------------------------------------KSlow
      pos=Dperiod-1;
      if(pos+1<prev_calculated)
         pos=prev_calculated-2;
      else
      {
         for(i=0; i<pos; i++)
            Signal[i]=0.0;
      }
   for(i=pos; i<rates_total && !IsStopped(); i++)
     {
      double SumaD=0.0;
      for(k=0; k<Dperiod; k++)
         SumaD+=Main[i-k];
      Signal[i]=SumaD/Dperiod;
     }  
     
     
//calculation of RSI9-------------------------------------------RSI9
//--- preliminary calculations
      pos=prev_calculated-1;
      if(pos<=RSIPeriod9)
        {
         //--- first RSIPeriod values of the indicator are not calculated
         ExtRSIBuffer9[0]=0.0;
         ExtPosBuffer9[0]=0.0;
         ExtNegBuffer9[0]=0.0;
         double sump9=0.0;
         double sumn9=0.0;
         for(i=1; i<=RSIPeriod9; i++)
           {
            ExtRSIBuffer9[i]=0.0;
            ExtPosBuffer9[i]=0.0;
            ExtNegBuffer9[i]=0.0;
            diff9=close[i]-close[i-1];
            if(diff9>0)
               sump9+=diff9;
            else
               sumn9-=diff9;
           }     
           //--- calculate first visible value RSI 9
         ExtPosBuffer9[RSIPeriod9]=sump9/RSIPeriod9;
         ExtNegBuffer9[RSIPeriod9]=sumn9/RSIPeriod9;
         if(ExtNegBuffer9[RSIPeriod9]!=0.0)
            ExtRSIBuffer9[RSIPeriod9]=1-(1/(1.0+ExtPosBuffer9[RSIPeriod9]/ExtNegBuffer9[RSIPeriod9]));
         else
           {
            if(ExtPosBuffer9[RSIPeriod9]!=0.0)
               ExtRSIBuffer9[RSIPeriod9]=1.0;
            else
               ExtRSIBuffer9[RSIPeriod9]=0.5;
           }
         //--- prepare the position value for main calculation
         pos=RSIPeriod9+1;
        }
        //--- the main loop of calculations RSI9
      for(i=pos; i<rates_total && !IsStopped(); i++)
        {
         diff9=close[i]-close[i-1];
         ExtPosBuffer9[i]=(ExtPosBuffer9[i-1]*(RSIPeriod9-1)+(diff9>0.0?diff9:0.0))/RSIPeriod9;
         ExtNegBuffer9[i]=(ExtNegBuffer9[i-1]*(RSIPeriod9-1)+(diff9<0.0?-diff9:0.0))/RSIPeriod9;
         if(ExtNegBuffer9[i]!=0.0)
            ExtRSIBuffer9[i]=1.0-1.0/(1.0+ExtPosBuffer9[i]/ExtNegBuffer9[i]);
         else
           {
            if(ExtPosBuffer9[i]!=0.0)
               ExtRSIBuffer9[i]=1.0;
            else
               ExtRSIBuffer9[i]=0.5;
           }
        }
//----------------------------------------------


//calculation of RSI14-------------------------------------------RSI14
//--- preliminary calculations
      pos=prev_calculated-1;
      if(pos<=RSIPeriod14)
        {
         //--- first RSIPeriod values of the indicator are not calculated
         ExtRSIBuffer14[0]=0.0;
         ExtPosBuffer14[0]=0.0;
         ExtNegBuffer14[0]=0.0;
         double sump14=0.0;
         double sumn14=0.0;
         for(i=1; i<=RSIPeriod14; i++)
           {
            ExtRSIBuffer14[i]=0.0;
            ExtPosBuffer14[i]=0.0;
            ExtNegBuffer14[i]=0.0;
            diff14=close[i]-close[i-1];
            if(diff14>0)
               sump14+=diff14;
            else
               sumn14-=diff14;
           }     
           //--- calculate first visible value RSI 9
         ExtPosBuffer14[RSIPeriod14]=sump14/RSIPeriod14;
         ExtNegBuffer14[RSIPeriod14]=sumn14/RSIPeriod14;
         if(ExtNegBuffer14[RSIPeriod14]!=0.0)
            ExtRSIBuffer14[RSIPeriod14]=1.0-(1.0/(1.0+ExtPosBuffer14[RSIPeriod14]/ExtNegBuffer14[RSIPeriod14]));
         else
           {
            if(ExtPosBuffer14[RSIPeriod14]!=0.0)
               ExtRSIBuffer14[RSIPeriod14]=1.0;
            else
               ExtRSIBuffer14[RSIPeriod14]=0.5;
           }
         //--- prepare the position value for main calculation
         pos=RSIPeriod14+1;
        }
        //--- the main loop of calculations RSI9
      for(i=pos; i<rates_total && !IsStopped(); i++)
        {
         diff14=close[i]-close[i-1];
         ExtPosBuffer14[i]=(ExtPosBuffer14[i-1]*(RSIPeriod14-1)+(diff14>0.0?diff14:0.0))/RSIPeriod14;
         ExtNegBuffer14[i]=(ExtNegBuffer14[i-1]*(RSIPeriod14-1)+(diff14<0.0?-diff14:0.0))/RSIPeriod14;
         if(ExtNegBuffer14[i]!=0.0)
            ExtRSIBuffer14[i]=1.0-1.0/(1+ExtPosBuffer14[i]/ExtNegBuffer14[i]);
         else
           {
            if(ExtPosBuffer14[i]!=0.0)
               ExtRSIBuffer14[i]=1.0;
            else
               ExtRSIBuffer14[i]=0.5;
           }
        }
        
        
//----------------------------------------------------------------------           
//                       INDICATOR PROCESS     
//---------------------------------------------------------------------- 

    ObjectsDeleteAll();
 
    static double
         c1, c2, alfa;
         double er,
         ers,
         m1,
         S1, S2,
         w11,w12,w13,w14,w21,w22,w23,w24;
//------------------------------------------weight assignment
   
      c1 = 0.8931912;
      c2 = 1.004812;
      w11 = 0.0739533;
      w12 = 0.08844932;
      w13 = 0.1054527;
      w14 = 0.6439033;
      w21 = 1.033343;
      w22 = 0.2306542;
      w23 = 0.2306542;
      w24 = 0.784637;
      alfa = 0.001;
      m1=0;
      ers=0;         
         
//---------------------------------------------------calculation of the output

      pos=Kperiod-1+Ksuaviz-1;
      if(pos+1<prev_calculated)
         pos=prev_calculated-2;
      else
       {
         for(i=0; i<pos; i++)
         Buf_0[i] = 0.0;
         Buf_1[i]= 0.0;
       }  
    
    for(i=pos; i<rates_total && !IsStopped(); i++)
      {
   
      
      S1=MathPow((Main[i]+0.0001),w11)*MathPow((Signal[i]+0.0001),w12)*MathPow((ExtRSIBuffer9[i]+0.0001),w13)*MathPow((ExtRSIBuffer14[i]+0.0001),w14);
      S2=MathPow((Main[i]+0.0001),w21)*MathPow((Signal[i]+0.0001),w22)*MathPow((ExtRSIBuffer9[i]+0.0001),w23)*MathPow((ExtRSIBuffer14[i]+0.0001),w24); 
      
      ExtOutput[i]=c1*S1+c2*S2;
      
      Buf_0[i] = (ExtOutput[i]-ExtOutput[ArrayMinimum(ExtOutput,WHOLE_ARRAY,0)])*100/(ExtOutput[ArrayMaximum(ExtOutput,WHOLE_ARRAY,0)]-ExtOutput[ArrayMinimum(ExtOutput,WHOLE_ARRAY,0)]);
      
      Buf_0[i] = ExtOutput[i];
      
      
      
//-----------------------------------------calculation of trigger line for Buf_0      
      double Suma_Buf0 = 0.0;
      
      for (k=0; k<3; k++) {
         Suma_Buf0 += Buf_0[i-k];
         }
         
      Buf_1[i]=Suma_Buf0/3;   


 //---------------------------------------weight updating process  
    
      er=Main[i]-Buf_0[i];
      c1=c1+alfa*er*Main[i];
      c2=c2+alfa*er*Main[i];
      w11=w11+(c1*er*alfa*Main[i]);//*MathPow(Main[i],w11))*MathLog(Main[i]));
      w12=w12+(c2*er*alfa*Main[i]);//*MathPow(Main[i],w12))*MathLog(Main[i])); 
      
      }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
/
To add comments, please log in or register