Issue: Moving Average applied on a Custom Indicator

 

There may be a common bug in MQL5 indicator functions or I'm missing something. The problem arises when I try to apply any indicator on any custom indicator. For example, in MQL4, you calculate the moving average of any indicator by first filling an array with the indicator and then calling the function iMAOnArray(). In MQL5, there's no such function iMAOnArray(), but you put the handle of the indicator as the last parameter of the iMA function. This works well for standard indicators, but not for custom indicators.

Note the two lines with "
custom_indicator_handle = " in the code below. First, I try to assign it to a Moving Average and then I use it as the last parameter in another iMA function. This calculates the moving average of a moving average which works fine and the line is displayed on the chart.

Then I commented this line and I assigned it to a custom indicator instead. After that, no line is displayed on the chart and the indicator value is always "inf" in the Data Window.

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1

#property indicator_type1 DRAW_LINE
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
#property indicator_color1 Red

double Buffer1[];

int custom_indicator_handle;
double custom_indicator[];
int MA_handle;
double MA[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {   
   SetIndexBuffer(0, Buffer1);
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
 
   //custom_indicator_handle = iMA(NULL, PERIOD_CURRENT, 14, 0, MODE_SMA, PRICE_CLOSE); // THIS WORKS FINE
   custom_indicator_handle = iCustom(NULL, PERIOD_CURRENT, "custom_indicator"); // THIS DOESN'T DISPLAY ANYTHING (value in the Data Window is "inf" for all candles)

   if(custom_indicator_handle < 0)
     {
      Print("The creation of custom_indicator has failed: custom_indicator_handle=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   MA_handle = iMA(NULL, PERIOD_CURRENT, 14, 0, MODE_SMA, custom_indicator_handle);
   if(MA_handle < 0)
     {
      Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE);
      Print("Runtime 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[])
  {
   int limit = rates_total - prev_calculated;

   ArraySetAsSeries(Buffer1, true);

   if(prev_calculated < 1)
     {
      ArrayInitialize(Buffer1, EMPTY_VALUE);
     }
   else
      limit++;
   
   if(BarsCalculated(MA_handle) <= 0) 
      return(0);
   if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) <= 0) return(rates_total);
   ArraySetAsSeries(MA, true);

   for(int i = limit-1; i >= 0; i--)
     {
      Buffer1[i] = MA[i];
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+


Custom indicator code:

For demonstration, I created a basic custom indicator that just copies the Moving Average indicator, so the code above should calculate "moving average of a moving average", but here the moving average is a custom indicator.

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1

#property indicator_type1 DRAW_LINE
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
#property indicator_color1 Red

double Buffer1[];
int MA_handle;
double MA[];


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {   
   SetIndexBuffer(0, Buffer1);
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   MA_handle = iMA(NULL, PERIOD_CURRENT, 14, 0, MODE_SMA, PRICE_CLOSE);
   if(MA_handle < 0)
     {
      Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE);
      Print("Runtime 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[])
  {
   int limit = rates_total - prev_calculated;
   ArraySetAsSeries(Buffer1, true);
   if(prev_calculated < 1)
     {
      ArrayInitialize(Buffer1, EMPTY_VALUE);
     }
   else
      limit++;
   
   if(BarsCalculated(MA_handle) <= 0) 
      return(0);
    
   if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) <= 0) return(rates_total);
   ArraySetAsSeries(MA, true);
   for(int i = limit-1; i >= 0; i--)
     {
      Buffer1[i] = MA[i];
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

The custom indicator is correctly displayed as a line, so the buffer is filled and I see no reason why it can't be used as a handle of the iMA function.
I attach both codes as files.
 
Your topic has been moved to the section: Technical Indicators
Please consider which section is most appropriate — https://www.mql5.com/en/forum/172166/page6#comment_49114893
 
michal32:

There may be a common bug in MQL5 indicator functions or I'm missing something. The problem arises when I try to apply any indicator on any custom indicator. For example, in MQL4, you calculate the moving average of any indicator by first filling an array with the indicator and then calling the function iMAOnArray(). In MQL5, there's no such function iMAOnArray(), but you put the handle of the indicator as the last parameter of the iMA function. This works well for standard indicators, but not for custom indicators.

Note the two lines with "
custom_indicator_handle = " in the code below. First, I try to assign it to a Moving Average and then I use it as the last parameter in another iMA function. This calculates the moving average of a moving average which works fine and the line is displayed on the chart.

Then I commented this line and I assigned it to a custom indicator instead. After that, no line is displayed on the chart and the indicator value is always "inf" in the Data Window.


Custom indicator code:

For demonstration, I created a basic custom indicator that just copies the Moving Average indicator, so the code above should calculate "moving average of a moving average", but here the moving average is a custom indicator.


The custom indicator is correctly displayed as a line, so the buffer is filled and I see no reason why it can't be used as a handle of the iMA function.
I attach both codes as files.

There are no common bugs in the MQL5 indicator, that happened is because you don't know how to implement iMAOnArray() in MQL5.

To implement the custom indicator that you created, use include file:

#include <MovingAverages.mqh>

How to use it, please learn lots of examples in CodeBase, or the easiest way is to see it in the MACD indicator code.

 
I found a solution. You must set:

PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 15);
in the custom indicator, then my example works correctly.


I have another, somewhat related problem here:

https://www.mql5.com/en/forum/455375

Moving Average of Bollinger Bands
Moving Average of Bollinger Bands
  • 2023.10.08
  • www.mql5.com
How do you apply an indicator on a multi-buffered indicator in MQL5? For example, Moving Average applied on Bollinger Bands...
Reason: