How to define limit value of this indicator in order to reduce cpu usage?

 

The problem is that this indicator is working properly by itself, but when i call it from a script for multiple symbols, after script ended cpu usage keeps high around 95% so that I should restart Terminal to run MT5 again.

I have used profiling and found that there should be something wrong about this indicator. specifically i think the "limit" value.

So, please tell me how should I change the coding to stop calculating excessively.

#property copyright "Copyright 2020"
#property link      ""
#property strict


//---- indicator settings
#property indicator_maximum +2
#property indicator_minimum -2
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2

#property indicator_type1   DRAW_ARROW
#property indicator_type2   DRAW_ARROW

#property indicator_color1  clrBlue
#property indicator_color2  clrRed


#property indicator_label1  "Up"
#property indicator_label2  "Down"



double ExtTrendBuffer[];
double ExtTrendColor[];
double ExtSupResBuffer[];
double ExtSupResColor[];
double ExtVolumeBuffer[];
double ExtVolumeColor[];
double ExtUIBuffer[];
double ExtUIColor[];
double ExtReversalBuffer[];
double ExtReversalColor[];
double Up[];
double Down[];

bool doPrint=false;

int    ExtArrowShift=-20;
//--- indicator buffer
double   iMABuffer[],iSUPP[],iRES[],iRSIBuffer[],iAOBuffer[],iVolumeBuffer[],iSTDBuffer[],iMAonVolume[],iUIBuffer1[],iUIBuffer2[];



int    handle[4];
int    bars_calculated=0;
int values_to_copy[5];
int SignalType=0;
string Shortname;
int iPeriod=100;
bool xcheck;
uint historysize=600;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
string Terminal_DiskName="";
string DiskSerial="";

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnInit()
  {



   SetIndexBuffer(0,Up,INDICATOR_DATA);
   PlotIndexSetInteger(0,PLOT_ARROW,110);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
   SetIndexBuffer(1,Down,INDICATOR_DATA);
   PlotIndexSetInteger(1,PLOT_ARROW,110);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);
  


   ArrayInitialize(values_to_copy,0);
   ArrayInitialize(Down,EMPTY_VALUE);
   ArrayInitialize(Up,EMPTY_VALUE);
   handle[0]=iCustom(Symbol(),PERIOD_CURRENT,"MACD-Classic",12,26,9,PRICE_CLOSE);

   handle[1]=iCustom(Symbol(),PERIOD_CURRENT,"spx",false);
   handle[2]=iVolumes(Symbol(),PERIOD_CURRENT,VOLUME_REAL);
   handle[3]=iMA(Symbol(),0,1,0,MODE_SMA,PRICE_CLOSE);


  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
 
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void IndicatorText(string name,double level)
  {
   ObjectCreate(0,name,OBJ_TEXT,ChartWindowFind(0,Shortname),iTime(NULL,0,0)+10*PeriodSeconds(PERIOD_CURRENT),level);
   ObjectSetString(0,name,OBJPROP_TEXT,name);

  }
//+------------------------------------------------------------------+
//|  Accelerator/Decelerator Oscillator                              |
//+------------------------------------------------------------------+
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,limit;
   MqlRates price_array[];
// MqlDateTime date_str;


   int calculated[4];
   for(int j=0; j<4; j++)//values_to_copy for each indicator
     {
      calculated[j]=BarsCalculated(handle[j]);

      if(prev_calculated==0 || calculated[j]!=bars_calculated || rates_total>prev_calculated+1)
        {
         if(calculated[j]>rates_total)
            values_to_copy[j]=rates_total;
         else
            values_to_copy[j]=calculated[j];
        }
      else
        {

         values_to_copy[j]=(rates_total-prev_calculated)+1;

        }

     }//end loop
//---
   if(rates_total<5)
      return(0);
//---
   if(!FillArrayFromBuffer(iUIBuffer1,1,handle[0],values_to_copy[0]))
      return(0);
   if(!FillArrayFromBuffer(iUIBuffer2,2,handle[0],values_to_copy[0]))
      return(0);
   if(!FillArrayFromBuffer(iRES,0,handle[1],values_to_copy[1]))
      return(0);
   if(!FillArrayFromBuffer(iSUPP,1,handle[1],values_to_copy[1]))
      return(0);
   if(!FillArrayFromBuffer(iVolumeBuffer,0,handle[2],values_to_copy[2]))
      return(0);
   if(!FillArrayFromBuffer(iMABuffer,0,handle[3],values_to_copy[3]))
      return(0);
   if(prev_calculated==0)
     {
      limit=iPeriod;
      //--- clean up arrays
      //ArrayInitialize(ExtCombinedBuffer,EMPTY_VALUE);


     }
   else
      limit=iPeriod;


   ArrayResize(iMAonVolume,rates_total+1,rates_total+1);
   ArrayResize(ExtSupResBuffer,rates_total+1,rates_total+1);
   ArrayResize(ExtVolumeBuffer,rates_total+1,rates_total+1);
   ArrayResize(ExtTrendBuffer,rates_total+1,rates_total+1);
   ArrayResize(ExtReversalBuffer,rates_total+1,rates_total+1);
   ArrayResize(ExtUIBuffer,rates_total+1,rates_total+1);

   ArrayResize(ExtVolumeColor,rates_total+1,rates_total+1);
   ArrayResize(ExtUIColor,rates_total+1,rates_total+1);
   ArrayResize(ExtTrendColor,rates_total+1,rates_total+1);
   ArrayResize(ExtSupResColor,rates_total+1,rates_total+1);
   ArrayResize(ExtReversalColor,rates_total+1,rates_total+1);

   for(i=limit; i<rates_total; i++)
     {

      ArrayResize(ExtSupResBuffer,i+1,rates_total+1);
      ArrayResize(ExtVolumeBuffer,i+1,rates_total+1);
      ArrayResize(ExtTrendBuffer,i+1,rates_total+1);
      ArrayResize(ExtReversalBuffer,i+1,rates_total+1);
      ArrayResize(ExtSupResColor,i+1,rates_total+1);
      ArrayResize(ExtVolumeColor,i+1,rates_total+1);
      ArrayResize(ExtUIColor,i+1,rates_total+1);
      ArrayResize(ExtTrendColor,i+1,rates_total+1);
      ArrayResize(ExtUIBuffer,i+1,rates_total+1);
      ArrayResize(ExtReversalColor,i+1,rates_total+1);
      ExtSupResBuffer[i]=+2;
      ExtSupResColor[i]=+2;
      if(i<0 || i>=ArraySize(iRES))
         Print("i= ",i," ,ArraySize(iRES)= ",ArraySize(iRES));
      if(iRES[i]!=EMPTY_VALUE)
         ExtSupResColor[i]=0;
      if(iSUPP[i]!=EMPTY_VALUE)
         ExtSupResColor[i]=+1;
      ArrayResize(iMAonVolume,i+1,rates_total+1);

      iMAonVolume[i]=Average(iVolumeBuffer,i-iPeriod,i);
      ExtVolumeColor[i]=2;
      ExtVolumeBuffer[i]=-2;

      if(iVolumeBuffer[i]>iMAonVolume[i] && close[i]>close[i-1])
         ExtVolumeColor[i]=0;
      if(iVolumeBuffer[i]>iMAonVolume[i] && close[i]<close[i-1])
         ExtVolumeColor[i]=1;
      if(iVolumeBuffer[i]<=iMAonVolume[i])
         ExtVolumeColor[i]=ExtVolumeColor[i-1];

      ExtUIBuffer[i]=+3;
      if(iUIBuffer1[i]>iUIBuffer2[i])
         ExtUIColor[i]=0;
      else
         ExtUIColor[i]=1;

      //+------------------------------------------------------------------+
      //|        entry conditions                                          |
      //+------------------------------------------------------------------+

      ExtTrendColor[i]=2;
      ExtTrendBuffer[i]=0;
      if(ExtVolumeColor[i]==1 && ExtSupResColor[i]==1)
        {
         ExtTrendColor[i]=+1;
        }

      if(ExtVolumeColor[i]==0 && ExtSupResColor[i]==0)
        {
         ExtTrendColor[i]=0;
        }

      //+------------------------------------------------------------------+
      //|          Reversal condiions                                      |
      //+------------------------------------------------------------------+
      ExtReversalBuffer[i]=1;
      ExtReversalColor[i]=2;
      Up[i]=EMPTY_VALUE;
      Down[i]=EMPTY_VALUE;
      if(ExtUIColor[i]==0 && ExtVolumeColor[i]==0)
        {
         ExtReversalColor[i]=0;
         Up[i]=+1;       
        }

      if(ExtUIColor[i]==1 && ExtVolumeColor[i]==1)
        {
         ExtReversalColor[i]=1;
         Down[i]=-1;
        }

     }//Main end loop


//--- OnCalculate done. Return new prev_calculated.
//   }//end of security check
   return(rates_total);
  }

//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &buffer[],  // indicator buffer values
                         int buffer_num,
                         int ind_handle,        // handle of the  indicator
                         int amount             // number of copied values
                        )
  {
//--- reset error code
   ResetLastError();

   if(CopyBuffer(ind_handle,buffer_num,0,amount,buffer)<0)
     {

      PrintFormat((string)ind_handle, " ,Failed to copy data from the indicator, error code %d",GetLastError());


      return(false);
     }

//--- everything is fine
   return(true);
  }
//+------------------------------------------------------------------+
double Average(double &array[],int from,int to)
  {
   ResetLastError();
   int n=to-from+1;
   double sum=0;
   for(int k=from; k<=to; k++)
     {

      if(k<0 || k>=ArraySize(array))
         Print(k," ArraySize: ",ArraySize(array));

      sum=sum+(double)array[k];
     }
   return(sum/n);
  }
//+------------------------------------------------------------------+

 

Your code is broken: You haven't declared all arrays.

You do a terrible thing -

   ArrayResize(iMAonVolume,rates_total+1,rates_total+1);
   ArrayResize(ExtSupResBuffer,rates_total+1,rates_total+1);
   ArrayResize(ExtVolumeBuffer,rates_total+1,rates_total+1);
   ArrayResize(ExtTrendBuffer,rates_total+1,rates_total+1);
   ArrayResize(ExtReversalBuffer,rates_total+1,rates_total+1);
   ArrayResize(ExtUIBuffer,rates_total+1,rates_total+1);

   ArrayResize(ExtVolumeColor,rates_total+1,rates_total+1);
   ArrayResize(ExtUIColor,rates_total+1,rates_total+1);
   ArrayResize(ExtTrendColor,rates_total+1,rates_total+1);
   ArrayResize(ExtSupResColor,rates_total+1,rates_total+1);
   ArrayResize(ExtReversalColor,rates_total+1,rates_total+1);

   for(i=limit; i<rates_total; i++)
     {

      ArrayResize(ExtSupResBuffer,i+1,rates_total+1);
      ArrayResize(ExtVolumeBuffer,i+1,rates_total+1);
      ArrayResize(ExtTrendBuffer,i+1,rates_total+1);
      ArrayResize(ExtReversalBuffer,i+1,rates_total+1);
      ArrayResize(ExtSupResColor,i+1,rates_total+1);
      ArrayResize(ExtVolumeColor,i+1,rates_total+1);
      ArrayResize(ExtUIColor,i+1,rates_total+1);
      ArrayResize(ExtTrendColor,i+1,rates_total+1);
      ArrayResize(ExtUIBuffer,i+1,rates_total+1);
      ArrayResize(ExtReversalColor,i+1,rates_total+1);


In general, a tip: throw out this code. Take the MQL Wizard and create a template. Then start filling in the code carefully.

Reason: