Display indicator on multiframes without changing original

 

My indicator draws up/ down arrows when MACD histogram change direction. I would like it to stay displayed on one timeframe and then be able to switch through timeframes without it changing arrows placement. 

 

E.g. arrows for 1hr remain in place on 5min 15min etc...

 

I tried changing  'NULL' of MACD to PERIOD_H1 but arrows placement on chart move around when I move between timeframes.. 

Anyone can tell me what I am doing wrong or how I can tackle this...

 

Thanks!   

//------------------------------------------------------------------
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 clrLawnGreen
#property indicator_color2 clrRed
#property strict
//------------------------------------------------------------------
extern int                Fast_EMA = 12;          // Fast ema period
extern int                Slow_EMA = 26;          // Slow ema period
extern ENUM_APPLIED_PRICE price    = PRICE_CLOSE; // Price


double CrossUp[],CrossDown[],direction[],macd[],MA1[];

int OnInit()
{
   IndicatorBuffers(5);
   SetIndexBuffer(0, CrossUp);   SetIndexStyle(0, DRAW_ARROW); SetIndexArrow(0, 225);
   SetIndexBuffer(1, CrossDown); SetIndexStyle(1, DRAW_ARROW); SetIndexArrow(1, 226);
   SetIndexBuffer(2, direction);
   SetIndexBuffer(3, macd);
   SetIndexBuffer(4, MA1);
  
   SetIndexShift(0,1);
   SetIndexShift(1,1);
  return(0);
}
int OnCalculate (const int       rates_total,
                 const int       prev_calculated,
                 const datetime& btime[],
                 const double&   open[],
                 const double&   high[],
                 const double&   low[],
                 const double&   close[],
                 const long&     tick_volume[],
                 const long&     volume[],
                 const int&      spread[] )
{
   int counted_bars = prev_calculated;
      if(counted_bars < 0) return(-1);
      if(counted_bars > 0) counted_bars--;
            int limit=MathMin(rates_total-counted_bars,rates_total-1);

      for(int i=limit; i>-0; i--)
      {
         macd[i]      = iMA(NULL,0,Fast_EMA,0,MODE_EMA,price,i)-iMA(NULL,0,Slow_EMA,0,MODE_EMA,price,i);
      
        
if(i<rates_total-1)
  {
   if((macd[i]>macd[i+1]) && (macd[i]<0))
     {
      direction[i]=1;
     }
   else if((macd[i]<macd[i+1])  && (macd[i]>0))
     {
      direction[i]=-1;
     }
   else
     {
      direction[i]=0;
     }
  }
else
  {
   direction[i]=0;
  }
        
//------------      
         CrossUp[i]   = EMPTY_VALUE;
         CrossDown[i] = EMPTY_VALUE;
         if (i<Bars-1 && direction[i]!=direction[i+1])
         {
               if (direction[i]== 1) CrossUp[i]   = Low[i]  - iATR(NULL,0,10,i);
               if (direction[i]==-1) CrossDown[i] = High[i] + iATR(NULL,0,10,i);
         }
  }
  return(rates_total);
}


 

   SetIndexShift(0,1);
   SetIndexShift(1,1);
Do you really want to hard code a shift?
int limit=MathMin(rates_total-counted_bars,rates_total-1);  //Change the -1 to -2

for(int i=limit; i>-0; i--)

As you are getting values for bar[i+1], when i=rates_total-1, i+1 will not exist and you will get an array out of range error. Then there is no need for this check
if(i<rates_total-1)
CrossUp[],CrossDown[]
You are looking for a change in direction, not a cross. Name your buffers to reflect what they do.
 
I am not completely sure what it is that you are trying to do. I'm assuming that you want an arrow at changes of direction, but only show up direction when the MACD is below zero and down arrows when it is above.

I would simplify the code and remove unnecessary buffers.

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color2 clrDodgerBlue
#property indicator_color3 clrRed
#property strict
//------------------------------------------------------------------
extern int                Fast_EMA = 12;          // Fast ema period
extern int                Slow_EMA = 26;          // Slow ema period
extern ENUM_APPLIED_PRICE price    = PRICE_CLOSE; // Price


double Up[],Down[],macd[];
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexBuffer(0,macd);
   SetIndexStyle(0,DRAW_NONE);
   SetIndexLabel(0,"MACD");
   SetIndexBuffer(1,Up);
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,225);
   SetIndexLabel(1,NULL);
   SetIndexBuffer(2,Down);
   SetIndexStyle(2,DRAW_ARROW);
   SetIndexArrow(2,226);
   SetIndexLabel(2,NULL);

   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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 counted_bars=prev_calculated;
   if(counted_bars < 0) return(-1);
   if(counted_bars>0) counted_bars--;
   int limit=MathMin(rates_total-counted_bars,rates_total-3);

   for(int i=limit; i>=0; i--)
     {
      macd[i]=iMA(NULL,0,Fast_EMA,0,MODE_EMA,price,i)-iMA(NULL,0,Slow_EMA,0,MODE_EMA,price,i);

      Up[i]   = EMPTY_VALUE;
      Down[i] = EMPTY_VALUE;
      if((macd[i]>macd[i+1] && macd[i+1]<macd[i+2]) && (macd[i]<0))
        {
         Up[i]=Low[i]-iATR(NULL,0,10,i);
        }
      else
      if((macd[i]<macd[i+1] && macd[i+1]>macd[i+2]) && (macd[i]>0))
        {
         Down[i]=High[i]+iATR(NULL,0,10,i);
        }

      //------------
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+



Then you can consider making it multi time-frame
Reason: