In the indicator test in the strategy tester, the test speed gradually decreases. Initial test rate cannot be maintained .

 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers     1
#property indicator_color1     clrLimeGreen
#property indicator_width1      2
#property indicator_minimum    -2
#property indicator_maximum    102
#property strict

extern ENUM_TIMEFRAMES    RSX_TimeFrame      =              0;  // Time frame
extern int                RSX_Length         =             14;  // RSX period
extern int                RSX_Vidya_Period   =             14;  // Vidya Smooth Period
extern int                RSX_Vidya_Smooth   =             14;  // Vidya period
extern double             RSX_LevelUp        =             99;
extern double             RSX_LevelDown      =              1;

double rsx[],wrkBuffer[][13];
string indicatorFileName;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {  
   IndicatorBuffers(1);
   SetIndexBuffer(0,rsx);  SetIndexLabel(0,"RSX");
   SetLevelValue(0,RSX_LevelUp);
   SetLevelValue(1,RSX_LevelDown);
   SetLevelStyle(STYLE_SOLID,1,clrWhite);
   
   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,r;
         
   int limit=MathMin(rates_total-prev_calculated+1,rates_total-1);
   
   if (ArrayRange(wrkBuffer,0) != Bars) ArrayResize(wrkBuffer,Bars);  //---- Array Size
   
   double Kg = (3.0)/(2.0+RSX_Length);
   double Hg = 1.0-Kg;
      
   for(i=limit, r=Bars-i-1; i>=0; i--, r++)
   {
      double price = open[i];
      
      wrkBuffer[r][12] = iVidya(price,price,RSX_Vidya_Period,RSX_Vidya_Smooth,i);

      if (i==(Bars-1)) for (int c=0; c<12; c++) wrkBuffer[r][c] = 0;
      
      double roc = (r>0) ? wrkBuffer[r][12]-wrkBuffer[r-1][12] : 0;
      double roa = MathAbs(roc);
      for (int k=0; k<3 && r>0; k++)
      {
         int kk = k*2;
            wrkBuffer[r][kk+0] = Kg*roc                + Hg*wrkBuffer[r-1][kk+0];
            wrkBuffer[r][kk+1] = Kg*wrkBuffer[r][kk+0] + Hg*wrkBuffer[r-1][kk+1]; roc = 1.5*wrkBuffer[r][kk+0] - 0.5 * wrkBuffer[r][kk+1];
            wrkBuffer[r][kk+6] = Kg*roa                + Hg*wrkBuffer[r-1][kk+6];
            wrkBuffer[r][kk+7] = Kg*wrkBuffer[r][kk+6] + Hg*wrkBuffer[r-1][kk+7]; roa = 1.5*wrkBuffer[r][kk+6] - 0.5 * wrkBuffer[r][kk+7];
      }
      rsx[i] = (roa != 0) ? fmax(fmin((roc/roa+1.0)*50.0,100.00),0.00) : 50; 
   }   
   return(rates_total);
}
//+------------------------------------------------------------------+
//| VİDYA                                                            |
//+------------------------------------------------------------------+
#define _vidyaInstances     1
#define _vidyaInstancesSize 3
double  vidya_work[][_vidyaInstances*_vidyaInstancesSize];
#define vidya_price 0
#define vidya_pricc 1
#define vidya_value 2

double iVidya(double price, double priceForCmo, int cmoPeriod, int smoothPeriod, int r, int instanceNo=0)
{
   if (ArrayRange(vidya_work,0)!=Bars) ArrayResize(vidya_work,Bars); r = Bars-r-1; int s = instanceNo*_vidyaInstancesSize;
   
   vidya_work[r][s+vidya_price] = price;
   vidya_work[r][s+vidya_pricc] = priceForCmo;
          double sumUp = 0, sumDo = 0;
          for (int k=0; k<cmoPeriod && (r-k-1)>=0; k++)
          {
               double diff = vidya_work[r-k][s+vidya_pricc]-vidya_work[r-k-1][s+vidya_pricc];
                  if (diff > 0)
                        sumUp += diff;
                  else  sumDo -= diff;
          }      
          vidya_work[r][s+vidya_value] = (r>0 && (sumDo+sumUp)!=0) ? vidya_work[r-1][s+vidya_value]+((((sumUp+sumDo)!=0) ? MathAbs((sumUp-sumDo)/(sumUp+sumDo)):1)*2.00/(1.00+MathMax(smoothPeriod,1)))*(vidya_work[r][s+vidya_price]-vidya_work[r-1][s+vidya_value]) : price;
   return(vidya_work[r][s+vidya_value]);
}

Hello . This code create by Mladen Rakic ​​.I adapted the indicator to the new event handler and removed everything unnecessary. In strategy tester, the first 3-4 months are tested very quickly in indicator testing. The longer the time, the longer the test time gets longer.In 5 years of testing it slows down drastically after 1 year.I want to learn if there is a way to maintain initial test speed (first 3-4 months).(Note:It is slow in the original version.original version is attached)

Files:
rsx_cvidyal.mq4  16 kb
 
Hello again . I call 2 indicators like this with icustom from expert advisor. The 10-year test takes 13 hours with the opo method (The 1-year expert advisor test takes 15 minutes. ) ... I'd be grateful if you could check it out when you're available. Maybe @Keith Watford , @William Roeder , @Mladen Rakic
 
Leonid Khrushchev # Maybe @Keith Watford , @William Roeder , @Mladen Rakic
  1. You have two arrays being resized on every new bar, that will slow things considerably. Change the two resizes to (arr, Bar, Bar)

  2.   int limit=MathMin(rates_total-prev_calculated+1,rates_total-1);

    This is recalculating bar one and bar zero each tick. Drop the plus one.

  3. Otherwise, changing the arrays to a circular queue, would be my only suggestion.


  4.       double price = open[i];

    In MT4, buffers and the predefined arrays are all ordered AsSeries. There is a difference between the arrays passed to OnCalculate (e.g. low[]) and the MT4 predefined variables (e.g. Low[].) The passed arrays have no default direction, just like MT5.

    To determine the indexing direction of time[], open[], high[], low[], close[], tick_volume[], volume[] and spread[], call ArrayGetAsSeries(). In order not to depend on default values, you should unconditionally call the ArraySetAsSeries() function for those arrays, which are expected to work with.
              Event Handling Functions - Functions - Language Basics - MQL4 Reference

 
William Roeder #:
  1. You have two arrays being resized on every new bar, that will slow things considerably. Change the two resizes to (arr, Bar, Bar)

  2. This is recalculating bar one and bar zero each tick. Drop the plus one.

  3. Otherwise, changing the arrays to a circular queue, would be my only suggestion.


  4. In MT4, buffers and the predefined arrays are all ordered AsSeries. There is a difference between the arrays passed to OnCalculate (e.g. low[]) and the MT4 predefined variables (e.g. Low[].) The passed arrays have no default direction, just like MT5.

Hİ @William Roeder. Thank you for your valuable ideas. Now I'm grappling with a code issue in expert advisor. I'll review it when I'm done. Thank you again sir.