Sei sulla pagina 1di 9

Free MetaTrader 4 Indicators Code - MetaTrader 4 Programming

Page 1 of 9

Writing Basic MetaTrader 4 Indicators - MetaTrader 4 Program

Writing Basic MetaTrader 4 (MT4) Indicators

Notice - This section is specific to MetaTrader 4 and its programming language, also
you have read and understood the principles of the previous lessons if you are new to
programming

Introduction to MetaTrader 4 Indicators

Indicators are different representations of the price data which removes noise and helps
make better decisions. What is important to remember is that the data we are talking abo
Open, High, Low, Close and Volume if available. A little like in chemistry nothing is lost, n
created, a Moving average of the Close is just another way to look at the data. So make s
understand what data is available to you and how you can use it. Also the representation o
indicator is made across a time line; there fore you will need to use a loop. Make sure to a
your loop properly and also make sure to use a FOR loop as much as possible.

First Step

Open the MetaEditor and click on File | New, select indicator in the popup window and click
In the name you would obviously enter the name of your MetaTrader indicator. For
enter: PRO3120 BI1 Enter the copyright info and website info if you choose to and then
Next and then click on finish.
So there you have a blank template to write your MetaTrader 4 indicator on. The
like this:
//+--------------+
//| PRO1030 - BI1.mq4|
//| Copyright 2007, Patrick Nouvion|
//| www.patricknouvion.com |
//+---------------+

These lines are preceded by // so these are comments and could be removed if you chose
update the info as you will and if you want to add a copyright/license statement I would su
add it here as well.
# Property - The next items you should see are:
#property copyright "Copyright 2007, Patrick Nouvion" #property link
www.patricknouvion.com

These were generated by the wizard when we created the new indicator and can also be u
needed. Items preceded by #property are controls for the indicators standard options/beh
have a quick review of the most common property settings available:
#property
#property
#property
#property
#property
#property
#property
#property
#property
#property
#property

indicator_chart_window
indicator_separate_window
indicator_color1 to #property indicator_color8
indicator_level1 to #property indicator_level8
indicator_style1 to #property indicator_style8
indicator_levelcolor
indicator_levelstyle
indicator_levelwidth
indicator_maximum
indicator_minimum
indicator_buffers

#property indicator_chart_window or #property indicator_separate_window Well this is pr


straight forward. Do you want your indicator to plot in the same window as the price chart
separate window?

For our indicator we will use the same window so here is what the top of our code looks lik

http://www.ibfx.com/ibfxu/catalog/programming/pro1030.aspx

31-08-2009

Free MetaTrader 4 Indicators Code - MetaTrader 4 Programming

Page 2 of 9

//+------------------------------------------------------------------+
//| PRO1030 - BI1.mq4 |
//| Copyright 2007, Patrick Nouvion |
//| www.patricknouvion.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2007, Patrick Nouvion"
#property link "www.patricknouvion.com"
#property indicator_chart_window

The color, level, style properties are used to define the style of the indicator
if you set these as properties then the user wont be able to change any of these settings w
usually a good idea. For example lets I wrote:
#property indicator_color1 Red

Well my MetaTrader indicator would be Red and that is it, the user wont be able to ever
another color even though the platform allows you to select from a wide panel of colors. S
width, style and levels So we will rarely use these but now you know what they are for a
wont use them. One last thing, as you can see you are limited to 8 But we will come ba
later.

#property indicator_maximum and #property indicator_minimum are used when you wan
an indicator in a separate window and you want to control the indicators window scale. For
the case of an oscillator you would want to fix the range from 0 to 100 and you would add
following lines to your indicator.
#property indicator_maximum 100.0
#property indicator_minimum 0.0

Here you can see I typed 100.0 and not 100 There is not really any difference but it is a
to enter double values as doubles just so that you recognize them right away. Often peopl
and declare variables as integer variables but use them as double variables. To
right form helps you spot these types of mistakes quickly.

Finally the #property indicator_buffers, simply put is the amount of lines your indicator w
We are limited to 8 output buffers, 8 lines. Now internally we could use as many buffers as
but we can only display 8 of them. What is a buffer? Well for now just think of it as a varia
Now I will write the following line:
#property indicator_buffers 1

However lets consider another example, lets say I wanted to create the MACD Traditional
which has 2 moving averages and 1 histogram then I would need to use:
#property indicator_buffers 3
If I dont set this to 3 then there is no way I will be able to display 3 items in my
point our MT4 indicator code looks like this:
//+------------------------------------------------------------------+
//| PRO1030 - BI1.mq4 |
//| Copyright 2007, Patrick Nouvion |
//| www.patricknouvion.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2007, Patrick Nouvion"
#property link "www.patricknouvion.com"
#property indicator_chart_window
#property indicator_buffers 1
The next step is to define the buffers. To do this I will write:
double OutPut[];

Just like a variable you need to define the type, here double. Then select a name here Out
the [] is to define it as an array. An array is a list if you will of values for a variables, it is
multidimensional variable. A basic example is when you try to bribe your kids into getting
grades. You will say if you get an A, I will give you $10. If you get a B then $5 etc
represent it with the following table:
A

http://www.ibfx.com/ibfxu/catalog/programming/pro1030.aspx

31-08-2009

Free MetaTrader 4 Indicators Code - MetaTrader 4 Programming

Page 3 of 9

$10 $5 $1 $0.25 $0
Using the above table I could say:
OutPut[A] = 10.0;
OutPut[B] = 5.0;
OutPut[C] = 1.0;
OutPut[D] = 0.0;
OutPut[E] = 0.25;
So why do we need an array? Well for each bar on our chart we need to OutPut
indicator and our table would be like this:
Bar0

Bar1

Bar2

Bar3

Bar4

Indicatorvalue0 Indicatorvalue1 Indicatorvalue2 Indicatorvalue3 Indicatorvalue4


We will come back to this more in details later.

Inputs:

In this language it is very easy to create inputs for the end user. You simply need to add e
before you variable declaration. Lets decide now to write a basic moving average indicator
the built-in iMA function ) so we need from the end user to know the number of periods.
integer so I will write:
extern int Periods = 10;
Just to confirm we could write:
extern bool IsItTrue = true;
extern double Value = 0.0;
extern string UserName = Patrick Nouvion;
MetaTraders language also has specific variable types such as color so I could also

extern color VarColor = Red;


But we will keep these for later. Make sure to use only inputs that are needed and if you h
inputs I think it is a good idea to separate them with dummy variables. Here is the
the Freedom Rocks expert advisor as an example:

extern bool CLOSE_ALL_ORDERS = false;


//extern bool AUTO_RENEW = false;
extern string INITIAL_ORDERS = "Initial Orders";
extern double EURUSD_LONG = 0.0; extern double GBPUSD_LONG = 0.0; extern double
USDCHF_LONG = 0.0; extern double USDJPY_LONG = 0.0;
extern string PENDING_ORDERS = "Pending Orders";
extern double EURUSD_LOTS_TO_TRADE = 0.0; extern double __EURUSD_BUY_RATE = 0
double __EURUSD_SELL_RATE = 0.0; extern double GBPUSD_LOTS_TO_TRADE =
extern double __GBPUSD_BUY_RATE = 0.0; extern double __GBPUSD_SELL_RATE
double USDCHF_LOTS_TO_TRADE = 0.0; extern double __USDCHF_BUY_RATE
extern double __USDCHF_SELL_RATE = 0.0; extern double USDJPY_LOTS_TO_TRADE = 0
double __USDJPY_BUY_RATE = 0.0; extern double __USDJPY_SELL_RATE = 0.0;
extern string OPTIONS = "Options";
extern double PROFIT_TARGET = 0; extern double TRAIL_START = 0; extern double TRAI
extern bool EMAIL_ALERTS = false;

You can see the string variables that will help separate all the different inputs and which w
used anywhere else in the code.
In any case, our code so far looks like this:
//+------------------------------------------------------------------+
//| PRO1030 - BI1.mq4 |
//| Copyright 2007, Patrick Nouvion |
//| www.patricknouvion.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2007, Patrick Nouvion"
#property link "www.patricknouvion.com"

http://www.ibfx.com/ibfxu/catalog/programming/pro1030.aspx

31-08-2009

Free MetaTrader 4 Indicators Code - MetaTrader 4 Programming

Page 4 of 9

#property indicator_chart_window
#property indicator_buffers 1
double OutPut[];
extern int Periods = 10;

Before we go on to the next step you need to look at the rest of the code that was automa
added. Hopefully it obvious that the indicator requires 3 sections Init (); Deinit(); and Star

If you learned from the previous classes you will remember that you can call functions and
can return a value. In the case of an indicator or expert advisor in MetaTrader
run 3 functions. Init(); Start(); Deinit(); in this order. It does not matter in which order th
because MetaTrader will call the function in the right order regardless. I could write Start()
Init(); or Init();Deinit();Start(); but MetaTrader expects to find the 3 functions and
function to return a value.

INIT ()
The code for init when you create a new MetaTrader indicator is:
int init()
{
return(0);
}

In essence this function must return an int and right now it returns 0.
To help you understand how functions are defined and what they are expected to do, here
examples:
bool ReturnZero () { return(true); }
double ReturnValue() { return(0.0);}
etc

Now we need to understand what return(0) means for MetaTrader. Well 0 means everythin
without error, and -1 means there was an error. So MetaTrader will first run through the in
if in the end init returns 0 the program will assume everything went fine and will then run
start function. If init returns -1 then MetaTrader will stop running the indicator and that wi
end of it. Init is always called first and to simplify we will assume that Init is called when y
indicator, update the inputs, change the periodicity of the chart or change the symbol of th
Init is only run one time and that is it.

So the code as is was fine, we could actually compile the code. If we remove all the comm
unnecessary characters the code could look like:
//+------------------------------------------------------------------+
//| PRO1030 - BI1.mq4 |
//| Copyright 2007, Patrick Nouvion |
//| www.patricknouvion.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2007, Patrick Nouvion"
#property link "www.patricknouvion.com"
#property indicator_chart_window
#property indicator_buffers 1
double OutPut[];
extern int Periods = 10;
int init() { return(0); }
int deinit() { return(0); }
int start() { return(0); }

However Init() is where we need to define a few things about our indicator such as color, s
like to do is add a few fail safes, copyright protection or expiration time here. In our exam
I could make sure people use positive Periods only, I could write:

http://www.ibfx.com/ibfxu/catalog/programming/pro1030.aspx

31-08-2009

Free MetaTrader 4 Indicators Code - MetaTrader 4 Programming

Page 5 of 9

Int init()
{
if( Periods <= 0 )
{
Alert(Invalid Periods);
return(-1);
}
return(0);
}

So Im saying if the input for the Periods is less than our equal to 0 return an error and st
the indicator. In more advance lessons we will work on more detailed Error Traps
I need to set my buffer index using SetIndexBuffer()
This is so that if your indicator uses multiple buffer, you have an index to know which one
and how to modify it.
SetIndexBuffer(0, OutPut);
If my buffer was called define as MyBuffer[], I would have then wrote:
SetIndexBuffer(0, MyBuffer);

Note that I dont type the [] Also note that all is zero based, my first buffer is 0, my sec
would be 1, etc This is very important to remember.

Now lets set a color and style using built in functions. Make sure to check the dictionary to
that is available to you. Here we will use the SetIndexStyle() function, the reason is again
this function in init versus using the property functions allows the end user to modify the
indicators using the built in setup of MetaTrader 4.
SetIndexStyle( 0, DRAW_LINE, STYLE_SOLID, 1, Red);
0 here represent our Buffer index, since I have only one buffer ( OutPut ) and that its
0 I entered 0.

1 is for the width, everything else is pretty self explanatory but again check your dictionar
options. DRAW_LINE could have been DRAW_HISTOGRAM for example. STYLE_SOLID cou
been STYLE_DOT or STYLE_DASH.

One last Item that is good to add is defined when the indicator starts to plot. In the case o
moving average, we wont get to plot any data until we have add at least our
If I entered periods = 10 then I would need 10 bars/records before I can calculate
first time. For this reason I will write the following line:
SetIndexDrawBegin(0, Periods );

Again 0 here refers to the buffer id. Periods is our external input
That is it for our init, of course more can be done here but that will be for a more advance
now this init is a good place to start for any new MetaTrader 4 indicator you want
hesitate to copy this and make your own template.
Here is what our code looks like now:
//+------------------------------------------------------------------+
//| PRO1030 - BI1.mq4 |
//| Copyright 2007, Patrick Nouvion |
//| www.patricknouvion.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2007, Patrick Nouvion"
#property link "www.patricknouvion.com"
#property indicator_chart_window
#property indicator_buffers 1
//---- BUFFER
double OutPut[];

http://www.ibfx.com/ibfxu/catalog/programming/pro1030.aspx

31-08-2009

Free MetaTrader 4 Indicators Code - MetaTrader 4 Programming

Page 6 of 9

//---- INPUT(S)
extern int Periods = 10;
//+------------------------------------------------------------------+
//+ INIT |
//+------------------------------------------------------------------+
int init()
{
//---- ERROR TRAPS
if( Periods <= 0 ) { Alert("Invalid Periods"); return(-1); }
//---- INDICATOR STYLE
SetIndexBuffer(0, OutPut);
SetIndexStyle( 0, DRAW_LINE, STYLE_SOLID, 1, Red);
SetIndexDrawBegin(0, Periods );
//---return(0);
}

deinit()

deinit() can be really useful and will be used with more advanced lessons For now to sim
demystify deinit(), lets just say it is used to tell the platform what to do when the MetaTra
indicator is removed. For example your created some objects on your chart during
the deinit() phase you would make sure to clean up these object and delete them.
For this lesson however our deinit code will only be:
int deinit() { return(0); }

start()

Previously I mentioned that we need to set an array and a for loop so that our MetaTrad
indicator would plot across the chart properly. So our first action is to prepare the
to do this we need to define how many bars/records we have on our chart. Here is a piece
use all the time.
For this lesson however our deinit code will only be:
int deinit() { return(0); }
//---- Find MaxRecords
int counted_bars=IndicatorCounted();
if(counted_bars<0) return(-1);
if(counted_bars>0) { counted_bars--; }
int MaxRecords = Bars-counted_bars;

MaxRecords is the accurate count of bars / records on a given chart. With this we can now
loop such as :
//---- Find MaxRecords
int counted_bars=IndicatorCounted();
if(counted_bars<0) return(-1);
if(counted_bars>0) { counted_bars--; }
int MaxRecords = Bars-counted_bars;

for( int i = 0; i < MaxRecords ; i++ )


{

}
//---return(0);
}

http://www.ibfx.com/ibfxu/catalog/programming/pro1030.aspx

31-08-2009

Free MetaTrader 4 Indicators Code - MetaTrader 4 Programming

Page 7 of 9

To check that everything is working you could OutPut the Close value for a test. Change y
this:
for( int i = 0; i < MaxRecords ; i++ )
{
OutPut[i] = Close[i];
}

Your code should look like:


//+------------------------------------------------------------------+
//| PRO1030 - BI1.mq4 |
//| Copyright 2007, Patrick Nouvion |
//| www.patricknouvion.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2007, Patrick Nouvion"
#property link "www.patricknouvion.com"
#property indicator_chart_window
#property indicator_buffers 1
//---- BUFFER
double OutPut[];
//---- INPUT(S)
extern int Periods = 10;
//+------------------------------------------------------------------+
//+ INIT |
//+------------------------------------------------------------------+
int init()
{
//---- ERROR TRAPS
if( Periods <= 0 ) { Alert("Invalid Periods"); return(-1); }
//---- INDICATOR STYLE
SetIndexBuffer(0, OutPut);
SetIndexStyle( 0, DRAW_LINE, STYLE_SOLID, 1, Red);
SetIndexDrawBegin(0, Periods );
//---return(0);
}
//+------------------------------------------------------------------+
//+ DEINIT |
//+------------------------------------------------------------------+
int deinit() { return(0); }
//+------------------------------------------------------------------+
//+ START |
//+------------------------------------------------------------------+
int start()
{
//---- Find MaxRecords
int counted_bars=IndicatorCounted();
if(counted_bars<0) return(-1);
if(counted_bars>0) { counted_bars--; }
int MaxRecords = Bars-counted_bars;
for( int i = 0; i < MaxRecords ; i++ )
{
OutPut[i] = Close[i];
}
//---return(0);
}

Compile your code and open the platform, now apply your indicator on a chart. It should p

http://www.ibfx.com/ibfxu/catalog/programming/pro1030.aspx

31-08-2009

Free MetaTrader 4 Indicators Code - MetaTrader 4 Programming

Page 8 of 9

close as a thin red line Now we know our loop is setup properly, our indicator parameter
we just need to work on programming the value it outputs.
So we wrote:
for( int i = 0; i < MaxRecords ; i++ )
{
OutPut[i] = Close[i];
}

Hopefully you remember the basic classes and you understand that i will start at 0 and
it reaches MaxRecords. On the first run i is equal to 0. 0 is the most current bar and our lo
OutPut[0] = Close[0];
Which means our most current OutPut value is equal to the Close most current value.

The next run i will be equal to 1. 1 is the bar before the most current bar and our loop will
OutPut[1] = Close[1];

I hope this concept is clear. Now our goal was not to display the close value but to calculat
moving average. A moving average of the close is the sum of the close for x periods divide
we first need to sum up the Close value and for this we need another loop inside our loop.
double Sum = 0.0;
for( int k = 0; k < Periods; k++ )
{
Sum += Close[i+k];
}

So I defined sum as a variable to store the total, then I run a loop using the Periods input
defined by the user. Hopefully you notice that I not only defined sum but also set it to 0.0,
resets it to 0.0 with each run.
A common mistake and something that is sometimes hard for people to understand is the

Because we are using a loop inside of another loop we need to add both iterators to get th
value. If I did not add i to k then our program would always use the most current values s
starts at 0
Alright now we need to divide Sum by periods and set out output.
OutPut[i] = Sum/Periods;

That is it; We now have our moving average indicator.


Here is the code we wrote, make sure to study it and understand how it works and its logi
fully understand this indicator then you will be able to write most indicators out
//+------------------------------------------------------------------+
//| PRO1030 - BI1.mq4 |
//| Copyright 2007, Patrick Nouvion |
//| www.patricknouvion.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2007, Patrick Nouvion"
#property link "www.patricknouvion.com"
#property indicator_chart_window
#property indicator_buffers 1
//---- BUFFER
double OutPut[];
//---- INPUT(S)
extern int Periods = 10;
//+------------------------------------------------------------------+
//+ INIT |

http://www.ibfx.com/ibfxu/catalog/programming/pro1030.aspx

31-08-2009

Free MetaTrader 4 Indicators Code - MetaTrader 4 Programming

Page 9 of 9

//+------------------------------------------------------------------+
int init()
{
//---- ERROR TRAPS
if( Periods <= 0 ) { Alert("Invalid Periods"); return(-1); }
//---- INDICATOR STYLE
SetIndexBuffer(0, OutPut);
SetIndexStyle( 0, DRAW_LINE, STYLE_SOLID, 1, Red);
SetIndexDrawBegin(0, Periods );
//---return(0);
}
//+------------------------------------------------------------------+
//+ DEINIT |
//+------------------------------------------------------------------+
int deinit() { return(0); }
//+------------------------------------------------------------------+
//+ START |
//+------------------------------------------------------------------+
int start()
{
//---- Find MaxRecords
int counted_bars=IndicatorCounted();
if(counted_bars<0) return(-1);
if(counted_bars>0) { counted_bars--; }
int MaxRecords = Bars-counted_bars;
for( int i = 0; i < MaxRecords ; i++ )
{
double Sum = 0.0;
for( int k = 0; k < Periods; k++ )
{
Sum += Close[i+k];
}
OutPut[i] = Sum/Periods ;
}
//---return(0);
}

http://www.ibfx.com/ibfxu/catalog/programming/pro1030.aspx

31-08-2009

Potrebbero piacerti anche