EMA & Hull MA indicator display problem

 

Hi there, i'm currently learning MQL5 language. I've just write a indicator program about EMA and Hull MA crossover and stuck on a problem

The Hull MA doesn't update the value when a new bar appears. I am not sure why the indicator is behaving in this manner. Here is my code.

#property indicator_buffers 4
#property indicator_plots 2
#property indicator_chart_window
#property strict

//--- MA Fast
#property indicator_type1 DRAW_LINE
#property indicator_label1 "MA Fast"
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2

//--- MA Slow
#property indicator_type2 DRAW_LINE
#property indicator_label2 "MA Slow"
#property indicator_color2 clrFireBrick
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2

//+------------------------------------------------------------------+
//| Inputs & Variables                                               |
//+------------------------------------------------------------------+
//--- Variables
int LongestPeriod;
double BufferMA2[];
double BufferMA1[];

//--- for Hull -------
int rates;
int HandleLWMA1;
int HandleLWMA2;
double BufferLWMA1[];
double BufferLWMA2[];
double BufferLWMA3[];
//--------------------

int HandleMA1;
int HandleMA2;


//--- Inputs
input int MA1_Period          = 10;          // EMA Period
input int MA2_Period          = 30;          // Hull MA Period
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {
   LongestPeriod = (int) MathMax(MA1_Period, MA2_Period);
   MAInit();
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
   IndicatorRelease(HandleMA1);
   IndicatorRelease(HandleMA2);
   ArrayFree(BufferMA1);
   ArrayFree(BufferMA2);
}
//+------------------------------------------------------------------+
//| 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[]) {
   if(rates_total < LongestPeriod) return (0);
   int copyBars = 0;
   
   // Calculation of the starting number first for the bar recalculation loop
   if(prev_calculated > rates_total || prev_calculated <= 0) {
     copyBars = rates_total - LongestPeriod;
   } else {
     copyBars = rates_total - prev_calculated;
     if(prev_calculated > 0) copyBars++;
   }
   
   //--- MA1 ----------------------------------
   CopyBuffer(HandleMA1, 0, 0, copyBars, BufferMA1);

   //--- MA2 ----------------------------------
   rates = rates_total;
   HullMACalculate(open, BufferMA2, copyBars, MA2_Period);

   return(rates_total);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|  MA Init                                                         |
//+------------------------------------------------------------------+
void MAInit() {
//--- EMA
   SetIndexBuffer(0, BufferMA1, INDICATOR_DATA);
   ArraySetAsSeries(BufferMA1, true);
   PlotIndexGetInteger(0, PLOT_DRAW_BEGIN, LongestPeriod); 
   HandleMA1 = iMA(Symbol(), 0, MA1_Period, 0, MODE_EMA, PRICE_CLOSE);

//--- Hull MA
   SetIndexBuffer(1, BufferMA2, INDICATOR_DATA);
   ArraySetAsSeries(BufferMA2, true);
   PlotIndexGetInteger(1, PLOT_DRAW_BEGIN, LongestPeriod); 

   SetIndexBuffer(2, BufferLWMA1, INDICATOR_CALCULATIONS);
   ArraySetAsSeries(BufferLWMA1, true);
   HandleLWMA1 = iMA(Symbol(), PERIOD_CURRENT, MA2_Period, 0, MODE_LWMA, PRICE_CLOSE);

   SetIndexBuffer(3, BufferLWMA2, INDICATOR_CALCULATIONS);
   ArraySetAsSeries(BufferLWMA2, true);
   HandleLWMA2 = iMA(Symbol(), PERIOD_CURRENT, MA2_Period/2, 0, MODE_LWMA, PRICE_CLOSE);
}

//+------------------------------------------------------------------+
//|  Hull MA                                                         |
//+------------------------------------------------------------------+
//--- Hull MA Data Calculate
void HullMACalculate(const double& open[], double& DataMA[], int copyBars, int period) {  
   CopyBuffer(HandleLWMA1, 0, 0, copyBars, BufferLWMA1);
   CopyBuffer(HandleLWMA2, 0, 0, copyBars, BufferLWMA2);
   
   ArrayResize(BufferLWMA3, rates);
   ArrayInitialize(BufferLWMA3, 0);
   ArraySetAsSeries(BufferLWMA3, true);
   
   for(int i = 0; i < copyBars; i++) {
      BufferLWMA3[i] = 2.0 * BufferLWMA2[i] - BufferLWMA1[i];
   }
   
   for(int i = 0; i < copyBars; i++) {
      DataMA[i] = LWMACalculate(BufferLWMA3, (int) sqrt(period), i);
   }
}

//+------------------------------------------------------------------+
//| Linear Weighted Moving Average                                   |
//+------------------------------------------------------------------+
double LWMACalculate(double& price[], int period, int index) {
   double sum = 0.0;
   double weight = 0.0;

   for(int i = index; i < (index + period); i++) {
      weight += (period - i);
      sum += price[i] * (period - i);
   }
   return(sum / weight);
}
Can someone enlighten me on why this problem occurred as I am trying to find a solution for it? I am grateful!
 
#property indicator_buffers 5
#property indicator_plots 2
if(rates_total < LongestPeriod) return (0);
   int limit, copyBars = 0;

// Calculation of the starting number first for the bar recalculation loop
   if(prev_calculated > rates_total || prev_calculated <= 0)
   {
      copyBars = rates_total; // - LongestPeriod;
      limit = rates_total - LongestPeriod;
   }
   else
   {
      copyBars = rates_total - prev_calculated;
      if(prev_calculated > 0) copyBars++;
      limit = copyBars;
   }

//--- MA1 ----------------------------------
   CopyBuffer(HandleMA1, 0, 0, copyBars, BufferMA1);

//--- MA2 ----------------------------------
   //rates = rates_total;
   HullMACalculate(limit, BufferMA2, copyBars, MA2_Period);
SetIndexBuffer(4, BufferLWMA3, INDICATOR_CALCULATIONS);
ArraySetAsSeries(BufferLWMA3, true);
void HullMACalculate(int limit, double& DataMA[], int copyBars, int period)
{
   CopyBuffer(HandleLWMA1, 0, 0, copyBars, BufferLWMA1);
   CopyBuffer(HandleLWMA2, 0, 0, copyBars, BufferLWMA2);

   //ArrayResize(BufferLWMA3, rates);
   //ArrayInitialize(BufferLWMA3, 0);
   //ArraySetAsSeries(BufferLWMA3, true);

   for(int i = 0; i <= limit; i++)
   {
      BufferLWMA3[i] = 2.0 * BufferLWMA2[i] - BufferLWMA1[i];
   }

   for(int i = 0; i <= limit; i++)
   {
      DataMA[i] = LWMACalculate(BufferLWMA3, (int) sqrt(period), i);
   }
}

//+------------------------------------------------------------------+
//| Linear Weighted Moving Average                                   |
//+------------------------------------------------------------------+
double LWMACalculate(double& price[], int period, int index)
{
   double sum = 0.0;
   double weight = 0.0;

   for(int i = index; i < (index + period); i++)
   {
      weight += (period - (i - index));
      sum += price[i] * (period - (i - index));
   }
   return(sum / weight);
}

In this way, BufferLWMA1 and BufferLWMA2 can be omitted.

void HullMACalculate(int limit, double& DataMA[], int copyBars, int period)
{
   //CopyBuffer(HandleLWMA1, 0, 0, copyBars, BufferLWMA1);
   //CopyBuffer(HandleLWMA2, 0, 0, copyBars, BufferLWMA2);

   double LWMA1[1], LWMA2[1];
        
   for(int i = 0; i <= limit; i++)
   {
        CopyBuffer(HandleLWMA1, 0, i, 1, LWMA1);
        CopyBuffer(HandleLWMA2, 0, i, 1, LWMA2);
        BufferLWMA3[i] = 2.0 * LWMA2[0] - LWMA1[0];
   }

   for(int i = 0; i <= limit; i++)
   {
      DataMA[i] = LWMACalculate(BufferLWMA3, (int) sqrt(period), i);
   }
}
 
Nagisa Unada #:

In this way, BufferLWMA1 and BufferLWMA2 can be omitted.

I am greatly appreciative of your assistance, it functions exceptionally well. 

I have one more inquiry, when I write a custom indicator like a custom Moving Average, should I also look back like the "limit" variable you have implemented?

Hope you have a wonderful day ahead!

Reason: