iCustom function mystery
Hi folks,
I have received a lot of questions in the forums about the iCustom function and
today I'll try to reveal the mystery behind the very important MQL4 function; iCustom.
There are two kinds of indicators you can use in your code (Expert advisors, Custom indicators and scripts):
Built-in indicators:
The MQL4 has a number of built-in indicators which you can use them in your code directly as a function for example:
double iMA( string symbol, int timeframe, int period, int ma_shift, int ma_method, int applied_price, int shift)
The above code calculates the moving average indicator and returns its value.
double iATR( string symbol, int timeframe, int period, int shift)
The above code calculates the average true range indicator and returns its value.
Any other indicator:
To use any other indicator in your code you have to duplicate the code of this indicator in your code (it the hell way) or you can use the iCustom function:
double iCustom( string symbol, int timeframe, string name, ... , int mode, int shift)
What's iCustom anyway?
iCustom is a MQL4 function enables you to use external indicators in your expert advisor or custom indicator code without re-writing the code from scratch.
If you didn't have the code of the external indicator you want to use in your code iCustom is the only way to use the indicator in your code because iCustom works with the already compiled indicator (.exe4 format).
How to use iCustom?
Let's assume that you have built your custom indicator in MQL4 and want to use it in your expert advisor code, and you are not interested in duplicating the indicator code in your expert advisor.
Your indicator draws only one line on the chart. This line is the EMA of the period the user enters (external variable). The code of you custom indicator will be something like that:
//+------------------------------------------------------------------+
//| Demo_Indicator.mq4 |
//| Codersguru |
//| http://www.metatrader.info |
//+------------------------------------------------------------------+
#property copyright "Codersguru"
#property link "http://www.metatrader.info" #property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- inputs
extern int UsePeriod = 13; //---- buffers
double ExtMapBuffer1[];//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,ExtMapBuffer1);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
if (counted_bars<0) return(-1);
//---- last counted bar will be recounted
if (counted_bars>0) counted_bars--;
int pos=Bars-counted_bars; //---- main calculation loop
while(pos>=0)
{
ExtMapBuffer1[pos]= iMA(NULL,0,UsePeriod,0,MODE_EMA,PRICE_CLOSE,pos);
pos--;
}
//----
return(0); }
//+------------------------------------------------------------------+
You've compiled the code above and loaded the indicator in MetaTrader terminal
and have got this result (Figure 1).
Figure 1 - Demo_Indicator
Just keep in your mind that.
1- Your indicator uses only one external variable; UsePeriod.
2- And draws only one line; ExtMapBuffer1
Now you want to write your expert advisor which uses the indicator above.
Let's assume that you want to use two of your Demo_Indicator.
The first one uses 13 UsePeriod as a parameter and the second one uses 20 UsePeriod as parameter.
At the crossing of the two indicators you will take a trade action (sell or buy).
Your code of the expert advisor will be something like that:
//+------------------------------------------------------------------+
//| Demo_EA.mq4 |
//| Codersguru |
//| http://www.metatrader.info |
//+------------------------------------------------------------------+
#property copyright "Codersguru"
#property link "http://www.metatrader.info"
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
int Crossed (double line1 , double line2)
{
static int last_direction = 0;
static int current_direction = 0;
if(line1>line2)current_direction = 1; //up
if(line1<line2)current_direction = 2; //down
if(current_direction != last_direction) //changed
{
last_direction = current_direction;
return (last_direction);
}
else
{
return (0);
}
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
int total;
double shortEma, longEma;
shortEma = iCustom(NULL,0,"Demo_Indicator",13,0,0);
longEma = iCustom(NULL,0,"Demo_Indicator",20,0,0);
Print("shortEma = " + shortEma + " : longEma = " + longEma);
int isCrossed = 0;
isCrossed = Crossed (shortEma,longEma);
total = OrdersTotal();
if(total < 1)
{
if(isCrossed == 1)
{
Alert("Take an action");
return(0);
}
if(isCrossed == 2)
{
Alert("Take an action");
return(0);
}
return(0);
}
return(0);
}
//+------------------------------------------------------------------+
Compile the above code and load the expert advisor in terminal then go to the Strategy Tester (press F6).
Test your expert advisor and notice the journal tab (Figure 2).
The lines:
Print("shortEma = " + shortEma + " : longEma = " + longEma);
And
Alert("Take an action");
Printed in the journal as you see in figure 2.
Figure 2 - Demo_EA
We have used the iCustom function in the above code to get the calculated value of our indicator,
let’s give iCustom an inside look.
iCustom syntax:
double iCustom( string symbol, int timeframe, string name, ... , int mode, int shift)
iCustom function takes these parameters:string symbol:
The symbol name of the currency pair you trading (Ex: EURUSD and USDJPY).
Use NULL for the current symbol.
ote: Use Symbol() function to get currently used symbol and OrderSymbol function to get the symbol of current selected order.
int timeframe:
The chart periodicity you want to use. It can be any of the following values:
Constant
Value
Description
PERIOD_M1
1
1 minute.
PERIOD_M5
5
5 minutes.
PERIOD_M15
15
15 minutes.
PERIOD_M30
30
30 minutes.
PERIOD_H1
60
1 hour.
PERIOD_H4
240
4 hour.
PERIOD_D1
1440
Daily.
PERIOD_W1
10080
Weekly.
PERIOD_MN1
43200
Monthly.
0 (zero)
0
The current Time frame used on the chart.
string name:
The exact name of the indicator you want to use. The indicator must be placed in the indicators folder and be compiled (you are loading the ex4 not the mql4 file, so you have to compile the indicator before loading it).
…:
The parameters set for the indicator you are calling. (…) means it the parameter can be any type and it can supply any count of parameters.
In our Demo Indicator we have only one parameter (External variable) UsePeriod – an integer type. We set its value here to 13 in the first iCustom call and to 20 in the second call.
int mode:
The index of the line you want to get its value. You know that any indicator can use up to 8 lines (buffers). The index of these lines starts at 0 and up to 7.
In our Demo Indicator we have only one line (buffer) ExtMapBuffer1. the index of this line is 0 (because it’s the first line and the only one too).
int shift:
The number of the shifts (backwards) from the current bar you want to calculate.
If you use 0 for the shift value it means you want to work with the current bar without shifting.
iCustom function returns double data type. It returns the calculation value of the passed parameters for the loaded indicator.
How did we use the iCustom function in our code?
double shortEma, longEma;
shortEma = iCustom(NULL,0,"Demo_Indicator",13,0,0);
longEma = iCustom(NULL,0,"Demo_Indicator",20,0,0);
In the first line we have declared two double variable (shortEma and longEma) which hold the returning value of iCustom.
Then we called iCustom in the second line with these parameters:
parmeter 1 :the symbol - NULL for current symbol.
parmeter 2 : time frame - 0 for current time frame.
parmeter 3 : indicator name - here it's " Demo_Indicator".
parmeter 4 : this is a setting for Demo_Indicator - UsePeriod = 13.
parmeter 5 : the line number (range from 0 to 7) - usually used 0.
parmeter 6 : the working bar - 0 for the current bar.
And in the third line we used iCustom again to get the second indicator value. These are the parameters we used:
parmeter 1 :the symbol - NULL for current symbol.
parmeter 2 : time frame - 0 for current time frame.
parmeter 3 : indicator name - here it's " Demo_Indicator".
parmeter 4 : this is a setting for Demo_Indicator - UsePeriod = 20.
parmeter 5 : the line number (range from 0 to 7) - usually used 0.
parmeter 6 : the working bar - 0 for the current bar.
Now we have the value of the indicator for the current bar, we can use it very like if we have the indicator in our program.
I hope it's clearer now and you can iCustom function without problems.
