Indicators : Then and Now

February 28, 2010
By Bogdan Baltatu, MQLmagazine editor

[Versiunea romaneasca] [MQLmagazine.com in romana] [English edition]

One of the great changes brought by MetaQuotes in MQL5 is the different call of functions returning data about the values of the indicators. In this article I’ll present comparatively the differences between the two languages, MQL4 and MQL5, regarding the use of indicators.

To have a better understanding of this transition I’ll begin with a short description of the MQL4’s work fashion then I’ll present MQL5, outlining the modifications.

Let’s start from one of the most known indicators, meaningly the Moving Averages.

If we wanted to know a value of the moving we were using the iMA() function, having the following prototype:

1
2
double iMA( string symbol, int timeframe, int period, int ma_shift, int ma_method,
int applied_price, int shift)

I will not describe again each parameter because if you know what a mobile average is, it’s very easy to identify them by the name. I want however to specify that the index (shift) was saying for which bar of the chart we want to calculate the mobile average value, the numbering of the bars starting from the current bar towards the oldest bar in the chart. The horizontal shift (ma_shift) had a very thin usage ; usually it was set to 0. For the case it had a value, the values of the moving average were shifted towards right by ma_shift values. For instance, should we had wanted the value for the current bar, the shift would have been set to zero, and should we had wanted the value for the 5th bar behind, we would have used the value of 5. In both cases the ma_shift was supposed to be 0. Should we have set the ma_shift to 5, for the 0 we would have the value for the real 3rd, and for the shift 5 we would have value for real 8th bar.
The iMA() function was used especially when a small number of immediate values was of our interest, for instance values of the last bar or the first two bars to see if a moving average cross occured.

If we wanted to apply the moving average over other values, not necesarilly market data, we were using the iMAOnArray() function having the following prototype:

1
double iMAOnArray(double array[], int total, int period, int ma_shift, int ma_method, int shift)

To this function we were sending on the first position an array where the data was, and it was necessary to use the ArraySetAsSeries() function set the semnification of the shift, meaningly the beginning or the end of the array.

In MQL5 the things have changed. First there are no functions referring indicators ending in ‘OnArray’ having as purpose calculus of the indicator over an array, but the base function, in our case iMA(), has a different prototype:

1
2
3
4
5
6
7
8
int  iMA(
string               symbol,            
ENUM_TIMEFRAMES      period,
int                  ma_period,      
int                  ma_shift,        
ENUM_MA_METHOD       ma_method,     
ENUM_APPLIED_PRICE   applied_price     
);

The types have changed a bit, but essentially the syntax remained the same. What’s gone, is the shift.

This time the iMA() returns an integer handler (reference), number which is to reference to the very parameters of the moving average; this handler is then used in the program to extract the values of the moving average, for MT5 already knows its parameters, ever since the iMA() runs. As a result the indicators in MQL5 return handlers, used for future calculus, while in MQL4 the indicators return punctual indicator values.

In order to have in an array the results calculated by the moving average we have to use the CopyBuffer() function.

The BarsCalculated() function returns the number of bars calculated for the specified indicator, with other words it returns the number of elements from the array. This can be useful with the CopyBuffer() function.
The function prototype is:

1
2
3
int  BarsCalculated(
   int       indicator_handle     
);

The function has a single parameter and that is the indicator’s handle, handle which is being returned by iMA() , in our case.
The CopyBuffer() function extracts the calculated values for an indicator, knowing its parameters by the reference. The function has three prototypes, being able to copy the values in an array.
– a number of elements and a start position;
– a number of elements and a start date;
– a start and an end date.

Below I’ll refer to one prototype, the one that seems the most used, and it is:

1
2
3
4
5
6
7
int  CopyBuffer(
   int       indicator_handle,     
   int       buffer_num,           
   int       start_pos,           
   int       count,                
   double    buffer[]            
);

It can be observed that the second parameter, buffer_num, represents the number of the buffer which we want transcribed in the target array. In our case, iMA() , the function returns a single buffer and this has the number 0. The first buffer number is 0!! Do not mistake the buffer’s index with the buffer’s number. The buffer’s index is the position of the element (corresponding to the value of a bar), while the buffer’s number is the element set extracted. For instance, for Stochastic, the buffer number 0 is the Main Line, and the number 1 is the Signal Line. All the indicators having single dataset (like the moving averages) have a single buffer number, and that is 0.

Below is a code sample showing the three functions to fill an array with the values calculated for the moving averages.

1
2
3
4
5
double MA_array[];
int handle;
handle=iMA(NULL,PERIOD_CURRENT,13,0,MODE_SMA,PRICE_CLOSE);
int buffer_num=BarsCalculated(handle);
CopyBuffer(handle,0,0,buffer_num,MA_array);

The ArraySetAsSeries() function, taken from MQL4, sets the AS_SERIES flag as requested. The function has two parameters. The first is the array to be set up as series (or not) and the second indicates the ordering direction : true for reversed order (as series), from the last element, which becomes first (index 0), or false for the original order.

1
2
3
4
bool  ArraySetAsSeries(
void  array[],     
bool  set          
);

In MQL4 only some indicator functions could have been calculated on arrays:
iBandsOnArray() , iCCIOnArray() , iEnvelopesOnArray() , iMomentumOnArray() , iRSIOnArray() si iStdDevOnArray().

Due to the changes brought by MetaQuotes now any indicator can work as a “on array” indicator.

The conclusion would be that the new MQL5 language offers more advantages from the point of using and accessing indicators from EAs.

One Response to “ Indicators : Then and Now ”

  1. Nicolas Vitale on March 2, 2010 at 1:02 am

    Just a small remark. In mql5 we have access to the ma function on buffer thanks to this file
    terminal_directory/MQL5/Include/MovingAverages.mqh