Colored Moving Average

 

Hello, I have developed a Moving Average, which consists of two lines with different colors. However, I have the problem that when the color changes, there is a gap. Is there a way to fill this gap? Many thanks in advance.

//+------------------------------------------------------------------+
//|                                         ColoredMovingAverage.mq5 |
//|                                        Copyright 2019, Arthur S. |
//|                    https://www.mql5.com/en/users/michael12345678 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, Arthur S."
#property link      "https://www.mql5.com/en/users/michael12345678"
#property version   "1.00"

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 2

#property indicator_label1 "Up"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrBlue

#property indicator_label2 "Down"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed

int MovingAverage;

double MovingAverageBufferBlue[];
double MovingAverageBufferRed[];
double MovingAverageBuffer[];

input int Periode=14;
input ENUM_MA_METHOD Methode=MODE_EMA;
input ENUM_APPLIED_PRICE Preis=PRICE_CLOSE;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{ 
   SetIndexBuffer(0,MovingAverageBufferBlue,INDICATOR_DATA);
   SetIndexBuffer(1,MovingAverageBufferRed,INDICATOR_DATA);
   SetIndexBuffer(2,MovingAverageBuffer,INDICATOR_CALCULATIONS);
   
   MovingAverage=iMA(_Symbol,_Period,Periode,0,Methode,Preis);
   if(MovingAverage==INVALID_HANDLE)
   {
      Print("The iMA object was not created: Error ",GetLastError());
      return INIT_FAILED;
   }
   
   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[])
{
   ArraySetAsSeries(MovingAverageBuffer,true);
   ArraySetAsSeries(MovingAverageBufferBlue,true);
   ArraySetAsSeries(MovingAverageBufferRed,true);
   
   int copied=CopyBuffer(MovingAverage,0,0,rates_total,MovingAverageBuffer);
   int copied2=CopyBuffer(MovingAverage,0,0,rates_total,MovingAverageBufferBlue);
   int copied3=CopyBuffer(MovingAverage,0,0,rates_total,MovingAverageBufferRed);
   
   for(int i=0;i<rates_total-1;i++)
   {
      MovingAverageBufferBlue[i]=EMPTY_VALUE;
      MovingAverageBufferRed[i]=EMPTY_VALUE;
      
      if(MovingAverageBuffer[i]<MovingAverageBuffer[i+1])
      {
         MovingAverageBufferRed[i]=MovingAverageBuffer[i];
      }
      else if(MovingAverageBuffer[i]>MovingAverageBuffer[i+1])
      {
         MovingAverageBufferBlue[i]=MovingAverageBuffer[i];
      }
   }
   
   return(rates_total);
}
//+------------------------------------------------------------------+
 
 
Arthur Singer:

The gap represents the flat areas of moving average.

I don't know how to fill it though, maybe a coder can help.

 
The gaps arise because the buffer changes.
 

It's easier to use the DRAW_COLOR_LINE type.

Files:
 
Thank you, but I need two buffers to read it.
 
Arthur Singer:

Hello, I have developed a Moving Average, which consists of two lines with different colors. However, I have the problem that when the color changes, there is a gap. Is there a way to fill this gap? Many thanks in advance.


Copy the middle points into both buffers. You should add one more if statement to check if it's a middle point and copy the previous value of the MA to the current buffer.

 

Do you mean this?

      if(MovingAverageBuffer[i]<MovingAverageBuffer[i+1])
      {
         MovingAverageBufferRed[i]=MovingAverageBuffer[i];
         
         if(MovingAverageBufferBlue[i+1]>0)
         {
            MovingAverageBufferRed[i+1]=MovingAverageBuffer[i+1];
         }
      }
      else if(MovingAverageBuffer[i]>MovingAverageBuffer[i+1])
      {
         MovingAverageBufferBlue[i]=MovingAverageBuffer[i];
         
         if(MovingAverageBufferRed[i+1]>0)
         {
            MovingAverageBufferBlue[i+1]=MovingAverageBuffer[i+1];
         }
      }
 
Arthur Singer:

Do you mean this?

Don't. That will cause a classical repaint

If you want colors in separate buffers, then use the mode applied in mt4 nrp indicators - and then you shall need at least 3 buffers to make it non-repainting - but if you plan to use multiple buffers to check trend, then you are on a wrong path (it is much easier to only read a color buffer then to use multiple buffers to try to find out a "trend"/"slope")

 
What else?
 
Arthur Singer:

Do you mean this?

No, don't go to future data which causes the repainting problem. use i and i-1 data points to check if the previous state was a blue state or a red state to copy the middle point. 

Reason: