help, drawing M5 trend in background on multiple timeframes

 

Hey,

I wanna visualize the M5 trend (sma 20 and sma 500) by drawing rectangles on the full chart height. This should be draw for example for the current week.

  • if M5 sma 20 is over sma 500, draw a green rectangle
  • if M5 sma 20 is under sma500, draw a rectangle in for example peach

This should work in M5, M15 and H1 timeframes. I coded the following indicator and it works in M5 timeframe perfectly. 

Problem:
When I change the timeframe for M15 or H1, it draws thousands of rectangles and is going into a stack overflow!

Thanks for suggestions to improve my indicator!

//+------------------------------------------------------------------+
//|                                                  M5TrendChange.mq4 |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "05.06.2020"
#property link      "https://www.mql5.com"
#property version   "1.0"
#property strict
#property indicator_chart_window
#property strict

#include <stderror.mqh>
#include <stdlib.mqh>

static int m5trendchange=0;// is the bar, where the M5 trend is changing from long to short and back
int rectanglecounter=0;// counts the number of rectangles drawn

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   DrawM5Trends();

//---
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {


   for(int i=0; i<=rectanglecounter; i++)
     {
      ObjectDelete("rectangle_"+(string)i);
     }
  }
//+------------------------------------------------------------------+
//| 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[])
  {

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DrawRectangle(const string Name, const datetime StartTime, const double StartPrice, const datetime EndTime, const double EndPrice, const string Tooltip, const color Color, const int hidden)
  {
   ObjectDelete(Name);
   ObjectCreate(0,Name,OBJ_RECTANGLE,0,StartTime,StartPrice,EndTime,EndPrice);
   ObjectSetString(0,Name,OBJPROP_TOOLTIP,Tooltip);
   ObjectSetInteger(0,Name,OBJPROP_COLOR,Color);
   ObjectSetInteger(0,Name,OBJPROP_STYLE,STYLE_SOLID);
   ObjectSetInteger(0,Name,OBJPROP_WIDTH,2);
   ObjectSetInteger(0,Name,OBJPROP_FILL,1);
   ObjectSetInteger(0,Name,OBJPROP_BACK,1);
   ObjectSetInteger(0,Name,OBJPROP_SELECTABLE,0);
   ObjectSetInteger(0,Name,OBJPROP_SELECTED,0);
   ObjectSetInteger(0,Name,OBJPROP_HIDDEN,hidden);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int ChartHeightInPixelsGet(const long chart_ID=0,const int sub_window=0)
  {
//--- prepare the variable to get the property value
   long result=-1;
//--- reset the error value
   ResetLastError();
//--- receive the property value
   if(!ChartGetInteger(chart_ID,CHART_HEIGHT_IN_PIXELS,sub_window,result))
     {
      //--- display the error message in Experts journal
      Print(__FUNCTION__+", Error Code = ",GetLastError());
     }
//--- return the value of the chart property
   return((int)result);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DrawM5Trends()
  {
   datetime startdrawing=iTime(NULL,PERIOD_W1,0)+60*60*24;//adding +60*60*24 because of sunday bar

   m5trendchange=iBarShift(NULL,PERIOD_M5,startdrawing,false);

//--- checking M5 trend at the specific start time and then start with long or short drawings
   datetime starttime=iTime(NULL,PERIOD_W1,0)+60*60*24;
   int startbar=iBarShift(NULL,PERIOD_M5,starttime,true);

   double sma20=iMA(NULL,PERIOD_M5,20,0,MODE_SMA,PRICE_CLOSE,0);
   double sma500=iMA(NULL,PERIOD_M5,500,0,MODE_SMA,PRICE_CLOSE,0);

   Print("|",__FUNCTION__,"|"," startdrawing: ",TimeToStr(startdrawing)," m5trendchange: ",(string)m5trendchange);

   if(sma20>sma500)
      DrawM5LongTrend();

   else
      DrawM5ShortTrend();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DrawM5ShortTrend()
  {
   datetime startdrawing=iTime(NULL,PERIOD_M5,m5trendchange);
   datetime enddrawing=0;
   color areacolor=clrPeachPuff;



   for(int i=m5trendchange; i>=0; i--)// M5 loop
     {
      double sma20=iMA(NULL,PERIOD_M5,20,0,MODE_SMA,PRICE_CLOSE,i);
      double sma500=iMA(NULL,PERIOD_M5,500,0,MODE_SMA,PRICE_CLOSE,i);

      if(sma20<sma500)
        {
         if(iTime(NULL,PERIOD_M5,i)>Time[i])
            continue;

         if(i==0)
           {
            enddrawing=iTime(NULL,PERIOD_M5,i);
            DrawRectangle("rectangle_"+(string)rectanglecounter,startdrawing,0,enddrawing,ChartHeightInPixelsGet(0,0),"\n",areacolor,0);
            m5trendchange=i;
            Print("|",__FUNCTION__,"|"," startdrawing: ",TimeToStr(startdrawing)," enddrawing: ",TimeToStr(enddrawing)," m5trendchange i: ",(string)m5trendchange, " rectanglecounter: ",rectanglecounter);
            rectanglecounter++;
            Print(__FUNCTION__," finish");
            return;
           }
        }

      else
        {
         enddrawing=iTime(NULL,PERIOD_M5,i);
         DrawRectangle("rectangle_"+(string)rectanglecounter,startdrawing,0,enddrawing,ChartHeightInPixelsGet(0,0),"\n",areacolor,0);
         m5trendchange=i;
         Print("|",__FUNCTION__,"|"," startdrawing: ",TimeToStr(startdrawing)," enddrawing: ",TimeToStr(enddrawing)," m5trendchange i: ",(string)m5trendchange, " rectanglecounter: ",rectanglecounter);
         rectanglecounter++;
         break;
        }
     }

   DrawM5LongTrend();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DrawM5LongTrend()
  {
   datetime startdrawing=iTime(NULL,PERIOD_M5,m5trendchange);
   datetime enddrawing=0;
   color areacolor=clrPaleGreen;

   for(int i=m5trendchange; i>=0; i--)// M5 loop
     {
      double sma20=iMA(NULL,PERIOD_M5,20,0,MODE_SMA,PRICE_CLOSE,i);
      double sma500=iMA(NULL,PERIOD_M5,500,0,MODE_SMA,PRICE_CLOSE,i);

      if(sma20>sma500)
        {
         if(iTime(NULL,PERIOD_M5,i)>Time[i])
            continue;

         if(i==0)
           {
            enddrawing=iTime(NULL,PERIOD_M5,i);
            DrawRectangle("rectangle_"+(string)rectanglecounter,startdrawing,0,enddrawing,ChartHeightInPixelsGet(0,0),"\n",areacolor,0);
            m5trendchange=i;
            Print("|",__FUNCTION__,"|"," stardrawing: ",TimeToStr(startdrawing)," enddrawing: ",TimeToStr(enddrawing)," m5trendchange i: ",(string)m5trendchange, " rectanglecounter: ",rectanglecounter);
            rectanglecounter++;
            Print(__FUNCTION__," finish");
            return;
           }
        }


      else
        {
         enddrawing=iTime(NULL,PERIOD_M5,i);
         DrawRectangle("rectangle_"+(string)rectanglecounter,startdrawing,0,enddrawing,ChartHeightInPixelsGet(0,0),"\n",areacolor,0);
         m5trendchange=i;
         Print("|",__FUNCTION__,"|"," stardrawing: ",TimeToStr(startdrawing)," enddrawing: ",TimeToStr(enddrawing)," m5trendchange i: ",(string)m5trendchange, " rectanglecounter: ",rectanglecounter);
         rectanglecounter++;
         break;
        }
     }

   DrawM5ShortTrend();
  }
//+------------------------------------------------------------------+