Mql - Metatrader Development Course http://www.metatrader.

info/book/print/34
1 of 258 6/14/2006 5:36 PM
Mql - Metatrader Development Course
Welcome to MQL4 course!
Welcome to the MQL4 course.
In this series, I will try to strip the mystique and confusion from MQL4 by giving you comprehensive tutorials
with a straight forward example.
In this series of lessons, I will show you how to use the MQL4 for building your own Expert Advisors, Custom
Indicators and Scripts.
If you are programming in C (or its superset C++) then you know a lot of MQL4 before even I start my lessons, if
you didn’t write in any programming language before, no problem, I’ll guide you to understand the concept of
programming in general as well.
So, let’s start from the beginning.
MQL4? What, Why and Where?
MQL4 stands for MetaQuotes Language 4.
MetaQuotes is the company who built the MetaTrader Trading Platform.
And to make it stronger than the other trading platforms the company extended it by a built-in programming
language that enables the user (you) to write his own trading strategies.
The language enables you to create one of the following:
1- Expert Advisors.
2- Custom Indicators.
3- Scripts.
• Expert Advisor is a program which can automate trading deals for you. For example it can automate your
market orders, stops orders automatically, cancels/replaces orders and takes your profit.
• Custom Indicator is a program which enables you to use the functions of the technical indicators and it cannot
automate your deals.
• Script is a program designed for single function execution. Unlike the Advisor, scripts are being held only once
(on demand), and not by ticks. And of course has no access to indicator functions.
These were “What” MQL4 is? “Why” to use MQL4?
Now, “Where” do I write MQL4?
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
2 of 258 6/14/2006 5:36 PM
To write your MQL4 code and as anything else in world, you can choose one of two ways, the hard way and the
easy way.
1- The hard way:
The hard way is using your favorite text editor and the command prompt to compile your program.
Notepad is not bad choice, but do not forget two things:
1- To save the file you have created in plain text format.
2- To save the file as .mp4 (that’s to be easy to reopen it with MetaEditor), but you can save it as any extension
you prefer.
After saving your program there is an extra step to make your code comes out to the light.
It’s the Compiling step.
Compiling means to convert the human readable script that you have just wrote to the machine language that
your computer understands.
MetaTrader has been shipped with its own compiler (the program which will convert your script to the machine
language) called MetaLang.exe.
Metalang.exe is a console program which takes two parameters and output an .ex4 file (the file which Metatrader
understands).
The first parameter is “options” parameter and the only option available is –q quit
The second parameter is the full path to your .mql file.
The syntax will be in this format.
metalang [options…] filename
Example:
1- Find your metalang.exe path, it will be the same path of MetaTrader (here my path is D:\Program
Files\MetaTrader 4).
2- Create a batch file and name it compile.bat (or any name you prefer).
3- Write these lines into the bat file then save it:
cd D:\Program Files\MetaTrader 4
metalang -q "D:\Program Files\MetaTrader 4\my_first_mql4_script.mq4"
(Don’t forget to change the path to you MetaTrader installed path).
4- Run the batch file and if you are lucky person like me you will get a screen like figure 1.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
3 of 258 6/14/2006 5:36 PM

Figure 1 Metalang compiler
As you see you will get the output file “my_first_mql4_script.ex4”
2-The easy way:
Metatrader has been shipped with a good IDE (integrated development editor) called MetaEditor which has these
features:
1- A text editor has the feature of highlighting different constructions of MQL4 language while you are
writing/reading code.
2- Easy to compile your program, just click F5 and the MetaEditor will make all the hard work for you and
produces the “ex4” file.
Besides it’s easy to see what the wrong in your program is (in the Error Tab – see figure 2).
3- Built-in a dictionary book which you can access by highlight the keyword you want to know further about it
then press F1.

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
4 of 258 6/14/2006 5:36 PM
Figure 2 MetaEditor 4
In the coming lessons we will know more about MetaEditor.
Today I just came to say hello, tomorrow we will start the real works and will study the Syntax of MQL4.
I welcome very much the questions and the suggestions.
See you
Coders’ Guru
Note: MetaTrader, the MetaTrader logo and MetaEditor are trademarks or registered trademarks of MetaQuotes
Software Crop.
Lesson 2 - SYNTAX
Hi folks,
We are talking today about the SYNTAX rules of MQL4.
And as I told you before, If you are programming in C (or its superset C++) then you know a lot of MQL4
before even I start my lessons.
That’s because the syntax of MQL4 is very like of the syntax of C.

The dictionary means of the word SYNTAX of a programming language is:
“The set of allowed reserved words and their parameters and the correct word order in the expression is called
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
5 of 258 6/14/2006 5:36 PM
the syntax of language”. “Wikipedia”

So, when we are studying the syntax of the language we are studying its grammar and writing rules which consist
of:
· Format
· Comments
· Identifiers
· Reserved words

Let’s slice the cake.




1- Format:

When you write your code, you can freely use any set of spaces, tabs and empty lines you want to separate your
code and your line of code to make them readable and eyes pleasing.

For example all of these lines are valid in MQL4:

double MacdCurrent, MacdPrevious, SignalCurrent;

double
MacdCurrent,
MacdPrevious,
SignalCurrent;

double MacdCurrent, MacdPrevious, SignalCurrent;
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
6 of 258 6/14/2006 5:36 PM

But, as you see, the first line is more readable and easy to understand.

And as everything in the world there are exceptions to the rule:

1- You can’t use new line in the “Controlling compilation”
You will know more about “Controlling compilation” in next lesson but just remember this is an exception.

For example the next line of code is invalid and the MQL4 compiler will complain:

#property
copyright "Copyright © 2004, MetaQuotes Software Corp."

This is the valid “Controlling compilation”:

#property copyright "Copyright © 2004, MetaQuotes Software Corp."


2- You can’t use new line or space in the middle of Constant values, Identifiers or Keywords.

For example this line is valid:

extern int MA_Period=13;

“extren” and “int” here are Keywords , “MA_Period” is an Identifier and “13” is a Constant value..
You will know more in the next lessons.

For example the next lines are invalids:

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
7 of 258 6/14/2006 5:36 PM
extern int MA_Period=1
3;


extern int MA_Period=1 3;

Notice the tab between 1 and 3.

ex
tern int MA_Period=13;



2- Comments:

To make the programming world easier, any programming language has its style of writing comments.
You use Comments to write lines in your code which the compiler will ignore then but it clears your code and
makes it understandable.
Assume that you write a program in the summer and in the winter you want to read it. Without comments -even
you are the code’s creator- you can’t understand all these puzzled lines.

MQL4 (& C/C++) uses two kinds of comments styles:

1- Single line comments

The Single line comment starts with “//” and ends with the new line.
For example:

//This is a comment
extern int MA_Period=13;
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
8 of 258 6/14/2006 5:36 PM

extern int MA_Period=13; //This is another comment




2- Multi-line comments

The multi-line comment start with “/*” and ends with “*/”.
And you can comment more than line or more by putting “/*” at the start of the first line, and “*/” at the end of
the last line.
For example:

/* this
is
multi
line
comment*/


You can also nest single line comment inside multi lines comment like that:

/* this
is
multi //another comment nested here.
line
comment*/


This is a valid comment too:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
9 of 258 6/14/2006 5:36 PM

extern int /*HELLO! I’m a comment*/ MA_Period=13;

But this is invalid comment:

extern int //test MA_Period=13;




3- Identifiers:

An identifier is the name you choose to your variables, constants and functions.

For example MA_Period here is an identifier:

extern int MA_Period=13;




There are few rules and restrictions for choosing those names:

1- The length of the Identifier must not exceed 31 characters.

2- The Identifier must begin with a letter (capital or small) or the underlining symbol _.
So, it can’t be started with a number or another symbol except the underlining symbol.

3- You can’t use any reserved words as an Identifier.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
10 of 258 6/14/2006 5:36 PM
You will see the list of the reserved words too soon.

4- The identifiers’ names are case sensitive.
So, MA_PERIOD not the same as ma_period or MA_Period

Let’s take some examples:

Name1 Valid
_Name1 Valid
1Name Invalid (don’t start with number)
~Name1 Invalid (you can only use underline symbol)
N~ame1 Invalid (you can only use underline symbol)
i_love_my_country_and_my_country_loves_all_the_world
Invalid (you can’t exceed the 31 characters length)
Color Valid
color Invalid (you can’t use reversed word, and color is one of them)


4- Reserved words:

There are “words” which the language uses them for specific actions.
So, they are reserved to the language usage and you can’t use them as an identifier name or for any other
purpose.

This is the list of the reserved words (from the MQL4 guide):

Data types Memory classes Operators Other
bool extern Break false
color static Case true
datetime continue
double Default
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
11 of 258 6/14/2006 5:36 PM
int Else
string For
void If
Return
Switch
While

For example the next lines of code are invalid:

extern int datetime =13;
int extern =20;
double continue = 0;
Lesson 3 - MQL4 Data types
What’s the Data type mean?

Any programming language has a set of names of the memory representation of the data.
For example if the memory holds numbers between -2147483648 to 2147483647, the most of the programming
languages will name this data as “Integer” data type.

Variables?
Variables are the names that refer to sections of memory into which data can be stored.
To help you think of this as a picture, imagine that memory is a series of different size boxes. The box size is
memory storage area required in bytes.
In order to use a box to store data, the box must be given a name; this process is known as declaration.
In the declaration process you use a word tell the computer what’s the kind and size of the box you want to
use, this word known as keyword.
It helps if you give a box a meaningful name that relates to the type of information which make it easier to
find the data, this name is the variable constant.
Data is placed into a box by assigning the data to the box.
When we set the value of the box you have created in the same line you declared the variable; this process
is known as initialization.
When we create a variable we are telling the computer that we want him to assign a specified memory length (in
bytes) to our variable, since storing a simple number, a letter or a large number is not going to occupy the same
space in memory, so the computer will ask us what’s the kind of data and how much the length of the data? That
is the Data type for.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
12 of 258 6/14/2006 5:36 PM

For example if we said this line of code to the computer:

int MyVaraible=0;

That’s mean we are asking the computer to set a block of 4 bytes length to our variable named “MyVaraiable”.

In the previous example we have used:
int ß Keyword
int ß Integer data type.
int ß Declaration
MyVaraible ß Variable’s constant.
=0 ß Initialization

We will know more about variables in a coming lesson.

In MQL4, these are the kinds of Data types:
Integer (int)
Boolean (bool)
Character (char)
String (string)
Floating-point number (double)
Color (color)
Datetime (datetime)

1- Integer
An integer, is a number that can start with a + or a - sign and is made of digits. And its range value is between
-2147483648 to 2147483647.
MQL4 presents the integer in decimal or hexadecimal format.

For example the next numbers are Integers:

12, 3, 2134, 0, -230
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
13 of 258 6/14/2006 5:36 PM
0x0A, 0x12, 0X12, 0x2f, 0xA3, 0Xa3, 0X7C7

We use the keyword int to create an integer variable.

For example:

int intInteger = 0;
int intAnotherIntger = -100;
int intHexIntger=0x12;


Decimal and Hexadecimal:

Decimal notation is the writing of numbers in the base of 10, and uses digits (0, 1, 2, 3, 4, 5, 6, 7, 8 and 9) to
represent numbers. These digits are frequently used with a decimal point which indicates the start of a fractional
part, and with one of the sign symbols + (plus) or − (minus) to indicate sign.

Hexadecimal is a numeral system with a base of 16 usually written using the symbols 0–9 and A–F or a–f.
For example, the decimal numeral 79 can be written as 4F in hexadecimal.


2- Boolean

Boolean variable is a data type which can hold only two values, true and false (or their numeric representation, 0
and 1). And it occupies 1 bit of the memory.
In MQL4, false,FALSE,False,true,TRUE and True are equals.

Boolean named like this in the honor of the great mathematician Boole George.

We use the keyword bool to create a boolean variable.

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
14 of 258 6/14/2006 5:36 PM
For example:

bool I = true;
bool bFlag = 1;
bool bBool=FALSE;

3- Character
MQL4 names this Data type “Literal”.
A character is one of 256 defined alphabetic, numeric, and special key elements
defined in the ASCII (American Standard Code for Information Interchange) set.
Characters have integer values corresponding to location in the ASCII set.
You write the character constant by using single quotes (') surrounding the character.

For example:

'a' , '$' , 'Z'


We use the keyword int to create a character variable.

For example:

int chrA = 'A';
int chrB = '$';

Some characters called Special Characters can’t present directly inside the single quotes because they have a
reserved meanings in MQL4 language.
Here we use something called Escape Sequence to present those special characters,
And that by prefixing the character with the backslash character (\).

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
15 of 258 6/14/2006 5:36 PM
For example:

int chrA = '\\'; //slash character
int chrB = '\n'; //new line


This is the list of Escape Sequence characters used in MQL4.

carriage return \r
new line \n
horizontal tab \t
reverse slash \\
single quote \'
double quote \"
hexadecimal ASCII-code \xhh
4- String
The string data type is an array of characters enclosed in double quote (").
The array of characters is an array which holds one character after another, starting at index 0. After the
last character of data, a NULL character is placed in the next array location. It does not matter if there
are unused array locations after that.
A NULL character is a special character (represented by the ASCII code 0) used to mark the end of this
type of string.
See figure 1 for a simple representation of the string constant “hello” in the characters array.
Figure 1 – Characters array
MQL4 limits the size of the string variable to 255 characters and any character above 255 characters will
generate this error: (too long string (255 characters maximum)).
You can use any special character -mentioned above- in your string constant by prefixing it with the
backslash (\).
We use the keyword string to create a string variable.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
16 of 258 6/14/2006 5:36 PM
For example:
string str1 = "Hello world1, with you coders guru”;
string str2 = "Copyright © 2005, \"Forex-tsd forum\"."; //Notice the use of (") character.
string str3 = "1234567890";

5- Floating-point number (double)
Floating point number is the Real Number (that is, a number that can contain a fractional part beside the
integer part separated with (.) dot).Ex: 3.0,-115.5, 15 and 0.0001.
And its range value is between 2.2e-308 to 1.8e308.
We use the keyword double to create a floating-point variable.
For example:
double dblNumber1 = 1000000000000000;
double dblNumber3 = 1/4;
double dblNumber3 = 5.75;



6- Color
Color data type is a special MQL4 data type, which holds a color appears on the MetaTrader chart when
you create your own Expert Advisor or Custom Indictor and the user can change it from the property tab
of your Expert Advisor or Custom Indictor.
You can set the Color variable constant in three ways:
1- By the color name: For the well know colors (called Web Colors Set) you can assign the name of the
color to the color variable, see the list of the Web Colors Set.
2- By Character representation (MQL4 named it this name): In this method you use the keyword (C)
followed by two signal quotations ('). Between the two signal quotations you set the value of the red, green
and blue (know as RGB value of the color). These values have to be between: 0 to 255. And you can write
these values in decimal or hexadecimal format.
3- By the integer value: Every color in the Web Colors Set has its integer value which you can write it in
decimal or hexadecimal format. And you can assign the Integer value of the color to the color variable.
The hexadecimal color format looks like this: 0xBBGGRR where BB is the blue value, GG is green value
and RR is the red value.
For example:
// symbol constants
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
17 of 258 6/14/2006 5:36 PM
C'128,128,128' // gray
C'0x00,0x00,0xFF' // blue
// named color
Red
Yellow
Black
// integer-valued representation
0xFFFFFF // white
16777215 // white
0x008000 // green
32768 // green

We use the keyword color to create a color variable.

For example:

color clr1= Red;
color clr1= C'128,128,128' ;
color clr1=32768;


Web Colors Set
Black DarkGreen DarkSlateGray Olive Green Teal
Maroon Indigo MidnightBlue DarkBlue DarkOliveGreen SaddleBrown
SeaGreen DarkGoldenrod DarkSlateBlue Sienna MediumBlue Brown DarkTurquoise
LightSeaGreen DarkViolet FireBrick MediumVioletRed MediumSeaGreen Chocolate
Goldenrod MediumSpringGreen LawnGreen CadetBlue DarkOrchid YellowGreen
DarkOrange Orange Gold Yellow Chartreuse Lime
DeepSkyBlue Blue Magenta Red Gray SlateGray
LightSlateGray DeepPink MediumTurquoise DodgerBlue Turquoise RoyalBlue
IndianRed MediumOrchid GreenYellow MediumAquamarine DarkSeaGreen Tomato
MediumPurple PaleVioletRed Coral CornflowerBlue DarkGray SandyBrown MediumSlateBlue
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
18 of 258 6/14/2006 5:36 PM
DarkSalmon BurlyWood HotPink Salmon Violet LightCoral
Plum Khaki LightGreen Aquamarine Silver LightSkyBlue LightSteelBlue
PaleGreen Thistle PowderBlue PaleGoldenrod PaleTurquoise LightGrey
Moccasin LightPink Gainsboro PeachPuff Pink Bisque LightGoldenRod
LemonChiffon Beige AntiqueWhite PapayaWhip Cornsilk LightYellow
Lavender MistyRose OldLace WhiteSmoke Seashell Ivory
LavenderBlush MintCream Snow White

7- Datetime
Datetime data type is a special MQL4 data type, which holds a date and time data. You set the Datetime
variable by using the keyword (D) followed by two signal quotations ('). Between the two signal quotations
you write a character line consisting of 6 parts for value of year, month, date, hour, minutes, and seconds.
Datetime constant can vary from Jan 1, 1970 to Dec 31, 2037.
For example:
D'2004.01.01 00:00' // New Year
D'1980.07.19 12:30:27'
D'19.07.1980 12:30:27'
D'19.07.1980 12' //equal to D'1980.07.19 12:00:00'
D'01.01.2004' //equal to D'01.01.2004 00:00:00'

We use the keyword datetime to create a datetime variable.

For example:
datetime dtMyBirthDay= D'1972.10.19 12:00:00';
datetime dt1= D'2005.10.22 04:30:00';






Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
19 of 258 6/14/2006 5:36 PM
Lesson 4 - MQL4 Operations & Expressions
What’s the meaning of Operations & Expressions?

You know the operations very well. If I told you that (+,-,*, /) are the basic arithmetical operators, you will
remember very fast what’s the operator means.

I hear you saying “OK, I know the operations; could you tell me what’s the meaning of the expression?”
Identifiers (do you remember them? If not, Review the SYNTAX lesson) together with the Operations
produce the Expressions.
Puzzled? Let’s illustrate it in an example:

x = (y*z)/w;

x,y,z and w, here are identifiers.
=,* and / are the operators.
The whole line is an expression.

When the expressions combined together it makes a statement.
And when the statements combined together it makes a function and when the functions combined together it
makes a program.



In the remaining of this lesson we are going to talk about the kinds operators used in MQL4.

So, let’s start with the basic arithmetical operators:


1- Arithmetical operators:

In MQL4 there are 9 Arithmetical operations
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
20 of 258 6/14/2006 5:36 PM
This is the list of them with the usage of each:

Operator Name Example Description
+ Addition operator A = B + C; Add A to B and assign the result to C.
- Subtraction operator A = B - C;
Subtract C from B and assign the result to
C.
+ - Sign changer operators A = -A;
Change the sign of A from positive to
negative.
* Multiplication operator A = B * C; Multiply B and C and assign the result to A.
/ Division operator A = B / C; Divide B on C and assign the result to A.
% Modulus operator A =A % C;
A is the reminder of division of B on C.
(ex: 10%2 will produce 0, 10%3 will
produce 1).
++ Increment operator A++; Increase A by 1 (ex: if A =1 make it 2).
-- Decrement operator A--; Decrease 1 from A (ex: if A =2 make it 1).

Note: You can’t combine the increment and decrement operator with other expressions.
For example you can’t say:

A=(B++)*5;

But you can write it like that:

A++;
B=A*5;


2- Assignment operators:

The purpose of any expression is producing a result and the assignment operators setting the left operand
with this result.

For example:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
21 of 258 6/14/2006 5:36 PM

A = B * C;

Here we multiply B and C and assign the result to A.
(=) here is the assignment operator.

In MQL4 there are 11 assignments operations
This is the list of them with the usage of each:

Operator Name Example Description
= Assignment operator A = B; Assign B to A.
+=
Additive Assignment
operator
A += B;
It’s equal to: A = A + B; Add B to A and
assign the result to A.
-=
Subtractive Assignment
operators
A -= B;
It’s equal to: A = A - B; Subtract B from A
and assign the result to A.
*=
Multiplicative Assignment
operator
A *= B;
It’s equal to: A = A * B; Multiply A and B
and assign the result to A.
/=
Divisional Assignment
operator
A /= B;
It’s equal to: A = A / B; Divide A on B and
assign the result to A.
%=
Modulating Assignment
operator
A %= B;
It’s equal to: A = A % B; Get the reminder
of division of A on B and assign the result
to A.
>>=
Left Shift Assignment
operator
A >>= B;
It shifts the bits of A left by the number of
bits specified in B.
<<=
Right Shift Assignment
operator
A <<= B;
It shifts the bits of A right by the number of
bits specified in B.
&= AND Assignment operator A &= B;
Looks at the binary representation of the
values of A and B and does a bitwise AND
operation on them.
|= OR Assignment operator A |= B;
Looks at the binary representation of the
values of A and B and does a bitwise OR
operation on them.
^= XOR Assignment operator A ^= B;
Looks at the binary representation of the
values of two A and B and does a bitwise
exclusive OR (XOR) operation on them.


Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
22 of 258 6/14/2006 5:36 PM
3- Relational operators:
The relational operators compare two values (operands) and result false or true only.
It’s is like the question “Is John taller than Alfred? Yes / no?”
The result will be false only if the expression produce zero and true if it produces any number differing
from zero;

For example:

4 == 4; //true
4 < 4; //false
4 <= 4 //true;

In MQL4 there are 6 Relational operations
This is the list of them with the usage of each:

Operator Name Example Description
== Equal operator A == Bi; True if A equals B else False.
!= Not Equal operator A != B; True if A does not equal B else False.
< Less Than operators A < B; True if A is less than B else False.
> Greater Than operator A > B; True if A is greater than B else False.
<= Less Than or Equal operator A <= B;
True if A is less than or equals B else
False.
>=
Greater Than or Equal
operator
A >= B;
True if A is greater than or equals B else
False.



4- Logical operators:

Logical operators are generally derived from Boolean algebra, which is a mathematical way of
manipulating the truth values of concepts in an abstract way without bothering about what the concepts
actually mean. The truth value of a concept in Boolean value can have just one of two possible values: true
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
23 of 258 6/14/2006 5:36 PM
or false.
MQL4 names the Logical operators as Boolean operators

MQL4 uses the most important 3 logical operators.
This is the list of them with the usage of each:

Operator Name Example Description
&& AND operator A && B;
If either of the values are zero the value of
the expression is zero, otherwise the value
of the expression is 1. If the left hand value
is zero, then the right hand value is not
considered.
|| OR operator A || B;
If both of the values are zero then the value
of the expression is 0 otherwise the value
of the expression is 1. If the left hand value
is non-zero, then the right hand value is not
considered.
! NOT operator !A;
Not operator is applied to a non-zero value
then the value is zero, if it is applied to a
zero value, the value is 1.



5- Bitwise operators:
The bitwise operators are similar to the logical operators, except that they work on a smaller scale --
binary representations of data.
The following operators are available in MQL4:
Operator Name Example Description
& AND operator A & B;
Compares two bits and generates a result of
1 if both bits are 1; otherwise, it returns 0.
| OR operator A | B;
Compares two bits and generates a result of
1 if the bits are complementary; otherwise,
it returns 0.
^ EXCLUSIVE-OR operator A ^ B;
Compares two bits and generates a result of
1 if either or both bits are 1; otherwise, it
returns 0.
~ COMPLEMENT operator ~A; Used to invert all of the bits of the operand.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
24 of 258 6/14/2006 5:36 PM
>> The SHIFT RIGHT operator A >> B;
Moves the bits to the right, discards the far
right bit, and assigns the leftmost bit a
value of 0. Each move to the right
effectively divides op1 in half.
<< The SHIFT LEFT operator A << B;
Moves the bits to the left, discards the far
left bit, and assigns the rightmost bit a
value of 0. Each move to the left
effectively multiplies op1 by 2.

Note Both operands associated with the bitwise operator must be integers.

6- Other operators:

There are some operators which used in MQL4 and don’t belong to one of the previous categories:

1- The array indexing operator ([]).
2- The function call operator (());
3- The function arguments separator operator -comma (,)

We will know more about the Arrays and Functions in the next lessons, so just remember these 3
operators as “Other operators”.



Operators Precedence:

If you don't explicitly indicate the order in which you want the operations in a compound expression to be
performed, the order is determined by the precedence assigned to the operators in use within the
expression. Operators with a higher precedence get evaluated first. For example, the division operator has
a higher precedence than does the addition operator. Thus, the two following statements are equivalent:

x + y / 100
x + (y / 100) //unambiguous, recommended
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
25 of 258 6/14/2006 5:36 PM


When writing compound expressions, you should be explicit and indicate with parentheses () which
operators should be evaluated first. This practice will make your code easier to read and to maintain.
The following table shows the precedence assigned to the operators in the MQL4. The operators in this
table are listed in precedence order: The higher in the table an operator appears, the higher its
precedence. Operators with higher precedence are evaluated before operators with a relatively lower
precedence. Operators on the same group have equal precedence. When operators of equal precedence
appear in the same expression, a rule must govern which is evaluated first. All binary operators except for
the assignment operators are evaluated from left to right. Assignment operators are evaluated right to left.
() Function call From left to right
[] Array element selection

! Negation From left to right
~ Bitwise negation
- Sign changing operation

* Multiplication From left to right
/ Division
% Module division

+ Addition From left to right
- Subtraction

<< Left shift From left to right
>> Right shift

< Less than From left to right
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
26 of 258 6/14/2006 5:36 PM
<= Less than or equals
> Greater than
>= Greater than or equals

== Equals From left to right
!= Not equal

& Bitwise AND operation From left to right

^ Bitwise exclusive OR From left to right

&& Logical AND From left to right

|| Logical OR From left to right

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
27 of 258 6/14/2006 5:36 PM
= Assignment From right to left
+= Assignment addition
-= Assignment subtraction
*= Assignment multiplication
/= Assignment division
%= Assignment module
>>= Assignment right shift
<<= Assignment left shift
&= Assignment bitwise AND
|= Assignment bitwise OR
^= Assignment exclusive OR

, Comma From left to right


Lesson 5 - Loops & Decisions (Part1)
Welcome to the fifth lesson in my course about MQL4.

The normal flow control of the program you write in MQL4 (And in others languages as well) executes
from top to bottom, A statement by a statement.

A statement is a line of code telling the computer to do something.
For example:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
28 of 258 6/14/2006 5:36 PM
Print("Hello World");
return 0;
A semicolon at end of the statement is a crucial part of the syntax but usually easy to forget, and that's make
it the source of 90% of errors.

But the top bottom execution is not the only case and it has two exceptions,
They are the loops and the decisions.

The programs you write like -the human- decides what to do in response of circumstances changing. In
these cases the flow of control jumps from one part of the program to another.
Statements cause such jumps is called Control Statements.
Such controls consist of Loops and Decisions.


LOOPS
-----------------

Loops causing a section of your program to be repeated a certain number of times.
And this repetition continues while some condition is true and ends when it becomes false.
When the loop end it passes the control to next statement follow the loop section.

In MQL4 there are two kinds of loops:



The for Loop
--------------------------

The for loop considered the easiest loop because all of its control elements are gathered in one place.
The for loop executes a section of code a fixed number of times.

For example:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
29 of 258 6/14/2006 5:36 PM

int j;
for(j=0; j<15; j++)
Print(j);

How does this work?

The for statement consists of for keyword, followed by parentheses that contain three expressions
separated by semicolons:

for(j=0; j<15; j++)

These three expressions are the initialization expression, the test expression and the increment expression:

j=0 ß initialization expression
j<15 ß test expression
J++ ß increment expression

The body of the loop is the code to be executed the fixed number of the loop:

Print(j);

This executes the body of the loop in our example for 15 times.

Note: the for statement in not followed by a semicolon. That's because the for statement and the loop body
are together considered to be a program statement.

The initialization expression:

The initialization expression is executed only once, when the loop first starts. And its purpose to give the
loop variable an initial value (0 in our example).

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
30 of 258 6/14/2006 5:36 PM
You can declare the loop variable outside (before) the loop like our example:

int j;

Or you can make the declaration inside the loop parentheses like this:

for(int j=0; j<15; j++)


The previous two lines of code are equal, except the Scope of each variable (you will know more about the
variable declaration and scopes in the Variables lesson).
The outside declaration method makes every line in the code block to know about the variable, while the
inside declaration makes only the for loop to know about the variable.

You can use more that one initialization expression in for loop by separating them with comma (,) like
this:

int i;
int j;
for(i=0 ,j=0;i<15;i++)
Print(i);


The Test expression:

The test expression always a relational expression that uses relational operators (please refer to relational
operators in the previous lesson).

It evaluated by the loop every time the loop executed to determine if the loop will continue or will stop. It
will continue if the result of the expression is true and will stop if it false.

In our example the body loop will continue printing i (Print(i)) while the case j<15 is true. For example the
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
31 of 258 6/14/2006 5:36 PM
j = 0,1,2,3,4,5,6,7,8,9,10,11,12,13 and 14.
And when j reaches 15 the loop will stops and the control passes to the statement following the loop.


The Increment expression:

The increment expression changes the value of the loop variable (j in our example) by increase it value by
1.
It executed as the last step in the loop steps, after initializing the loop variable, testing the test expression
and executing the body of the loop.

Figure 1 shows a flow chart of the for loop.

Figure 1 - Flow chart of the for loop


Like the initialization expression, in the increment expression you can use more than one increment
expression in the for loop by separating them with comma (,) like this:

int i;
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
32 of 258 6/14/2006 5:36 PM
int j;
for(i=0 ,j=0;i<15,i<;i++,j++)
Print(i);

But you can only use one test expression.

Another notice about the increment expression, it’s not only can increase the variable of the loop, but it
can perform and operation it like for example decrements the loop variable like this:

int i;
for(i=15;i>0,i<;i--)
Print(i);

The above example will initialize the i to 15 and start the loop, every time it decreases i by 1 and check the
test expression (i>0).
The program will produce these results: 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1.

Multi statement in the loop body:

In our previous examples, we used only one statement in the body of the loop, this is not always the case.
You can use multi statements in the loop body delimited by braces like this:

for(int i=1;i<=15;i++)
{
Print(i);
PlaySound("alert.wav");
}

In the above code the body of the loop contains two statements, the program will execute the first
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
33 of 258 6/14/2006 5:36 PM
statement then the second one every time the loop executed.
Don’t forget to put a semicolon at the end of every statement.

The Break Statement:

When the keyword presents in the for loop (and in while loop and switch statement as well) the execution
of the loop will terminate and the control passes to the statement followed the loop section.

For example:

for(int i=0;i<15;i++)
{
if((i==10)
break;
Print(i);
}

The above example will execute the loop until i reaches 10, in that case the break keyword will terminate
the loop. The code will produce these values: 0,1,2,3,4,5,6,7,8,9.

The Continue Statement:

The break statement takes you out the loop, while the continue statement will get you back to the top of
the loop (parentheses).
For example:

for(int i=0;i<15; i++)
{
if(i==10) continue;
Print(i)
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
34 of 258 6/14/2006 5:36 PM
}

The above example will execute the loop until i reaches 10, in that case the continue keyword will get the
loop back to the top of the loop without printing i the tenth time. The code will produce these values:
0,1,2,3,4,5,6,7,8,9,11,12,13,14.

Latest note:

You can leave out some or all of the expressions in for loop if you want, for example:
for(;;)
This loop is like while loop with a test expression always set to true.
We will introduce the while loop to you right now.



The while Loop
---------------------

The for loop usually used in the case you know how many times the loop will be executed. What happen if
you don’t know how many times you want to execute the loop?
This the while loop is for.

The while loop like the for loop has a Test expression. But it hasn’t Initialization or Increment expressions.

This is an example:

int i=0;
while(i<15)
{
Print(i);
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
35 of 258 6/14/2006 5:36 PM
i++;
}

In the example you will notice the followings:

The loop variable had declared and initialized before the loop, you can not declare or initialize it
inside the parentheses of the while loop like the for loop.
The i++ statement here is not the increment expression as you may think, but the body of the loop
must contain some statement that changes the loop variable, otherwise the loop would never end.

How the above example does work?

The while statement contains only the Test expression, and it will examine it every loop, if it’s true the
loop will continue, if it’s false the loop will end and the control passes to the statement followed the loop
section.

In the example the loop will execute till i reaches 16 in this case i<15=false and the loop ends.


Figure 2 shows a flow chart of the while loop.


Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
36 of 258 6/14/2006 5:36 PM
Figure 2 - Flow chart of the while loop


I told you before that the while loop is like the for loop, these are the similar aspects:

You can use break statement and continue in both of them. 1.
You can single or multi statements in the body of the loop in both of them, in the case of using multi
statements you have to delimit them by braces.
2.
The similar copy of for(;;) is while(true) 3.
Lesson 6 - Loops & Decisions (Part2)
Welcome to the sixth lesson in my course about MQL4.
I hope you enjoyed the previous lessons.

In the previous lesson, we have talked about the Loops.
And we have seen that the Loops are one of two ways we use to change the normal flow of the program
execution -from top to bottom. The second way is the Decisions.

Decisions in a program cause a one-time jump to a different part of the program, depending on the value
of an expression.
These are the kinds of decisions statements available in MQL4:



The if Statement
--------------------------------

The if statement is the simplest decision statement, here’s an example:

if( x < 100 )
Print("hi");

Here the if keyword has followed by parentheses, inside the parentheses the Test expression ( x < 100),
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
37 of 258 6/14/2006 5:36 PM
when the result of test expression is true the body of the if will execute (Print("hi");) ,and if it is false, the
control passes to the statement follows the if block.

Figure 1 shows the flow chart of the if statement:


Figure 1 - Flow chart of the if statement

Multi Statements in the if Body:

Like the loops, the body of if can consist of more than statement delimited by braces.

For example:

if(current_price==stop_lose)
{
Print("you have to close the order");
PlaySound("warning.wav");
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
38 of 258 6/14/2006 5:36 PM
}


Notice the symbol == in the Test expression; it's one of the Relational Operators you have studied in the
lesson 4, operations & expressions.
This is a source of a lot of errors, when you forget and use the assignment operator =.

Nesting:

The loops and decision structures can be basted inside one another; you can nest ifs inside loops, loops
inside ifs, ifs inside ifs, and so on.

Here's an example:

for(int i=2 ; i<10 ; i++)
if(i%2==0)
{
Print("It's not a prime nomber");
PlaySound("warning.wav");
}



In the previous example the if structure nested inside the for loop.

Notice: you will notice that there are no braces around the loop body, this is because the if statement and the
statements inside its body, are considered to be a single statement.


The if...else Statement
------------------------------------------
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
39 of 258 6/14/2006 5:36 PM

The if statement let's you to do something if a condition is true, suppose we want to do another thing if it's
false. That's the if...else statement comes in.
It consist of if statement followed by statement or a block of statements, then the else keyword followed by
another statement or a block of statements.

Like this example:

if(current_price>stop_lose)
Print("It’s too late to stop, please stop!");
else
Print("you playing well today!");

If the test expression in the if statement is true, the program one message, if it isn’t true, it prints the
other.

Figure 2 shows the flow chart of the if…else statement:

Figure 2 - Flow chart of the if..else statement
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
40 of 258 6/14/2006 5:36 PM

Nested if…else Statements

You can nest if…else statement in ifs statements, you can nest if…else statement in if…else statement, and
so on.

Like this:


if(current_price>stop_lose)
Print("It’s too late to stop, please stop!");
if(current_price==stop_lose)
Print("It’s time to stop!");
else
Print("you playing well today!");

There’s a potential problem in nested if…else statements, you can inadvertently match an else with the
wrong if.

To solve this case you can do one of two things:

1- you can delimited the if…else pairs with braces like this:

if(current_price>stop_lose)
{
Print("It’s too late to stop, please stop!");
if(current_price==stop_lose)
Print("It’s time to stop!");
else
Print("you playing well today!");
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
41 of 258 6/14/2006 5:36 PM
}


2- If you can’t do the first solution (in the case of a lot of if…else statements or you are lazy to do it) take it
as rule.
Match else with the nearest if. (Here it’s the line if(current_price==stop_lose)).


The switch Statement
------------------------------------------

If you have a large decision tree, and all the decisions depend on the value of the same variable, you can
use a switch statement here.
Here’s an example:

switch(x)
{
case 'A':
Print("CASE A");
break;
case 'B':
case 'C':
Print("CASE B or C");
break;
default:
Print("NOT A, B or C");
break;
}

In the above example the switch keyword is followed by parentheses, inside the parentheses you’ll find the
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
42 of 258 6/14/2006 5:36 PM
switch constant, this constant can be an integer, a character constant or a constant expression. The
constant expression mustn’t include variable for example:
case X+Y: is invalid switch constant.

How the above example works?

The switch statement matches the constant x with one of the cases constants.
In the case x=='A' the program will print "CASE A" and the break statement will take you the control out
of the switch block.

In the cases x=='B' or x=='C', the program will print "CASE B or C". That’s because there’s no break
statement after case 'B':.

In the case that x != any of the cases constants the switch statement will execute the default case and print
"NOT A, B or C".

Figure 3 shows the flow chart of the switch statement
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
43 of 258 6/14/2006 5:36 PM

Figure 3 - Flow chart of the switch statement
Lesson 7 - Functions
Welcome to the world of MQL4 Functions.
The functions in any language take two phases:
Learning them which sometimes a boring thing.
Using them which always a lifeboat.

Let’s start the seventh lesson.

What’s the meaning of functions?

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
44 of 258 6/14/2006 5:36 PM
The function is very like the sausage machine, you input the meat and the spices and it outs the sausage.
The meat and the spices are the function parameters; the sausage is the function return value. The
machine itself is the function body.
There’s only one difference between the functions and your sausage machine, some of the functions will
return nothing (nothing in MQL4 called void).

Let’s take some examples:

double // type of the sausage – return value
my_func (double a, double b, double c) // function name and parameters list (meat & spices)
{
return (a*b + c); // sausage outs - returned value
}


As you see above, the function starts with the type of the returned value “double” followed by the function
name which followed by parentheses.
Inside the parentheses you put the meat and spices, sorry, you put the parameters of the function.
Here we have put three parameters double a, double b, double c.
Then the function body starts and ends with braces. In our example the function body will produce the
operation (a*b + c).
The return keyword is responsible about returning the final result.


Return keyword:

The return keyword terminate the function (like the break keyword does in the loop), and it gives the
control to the function caller (we will know it soon).
The return keyword can include an expression inside its parentheses like the above example return (a*b +
c); and this means to terminate the function and return the result of the expression.
And it can be without expression and its only job in this case is to terminate the function.

Notice: Not all the functions use the return keyword, especially if there’s no return value. Like the next
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
45 of 258 6/14/2006 5:36 PM
example:

void // void mean there’s no sausage – returned value.
my_func (string s) // function name and parameters list (meat & spices)
{
Print(s);
}

The function above will not return value, but it will print the parameter s you provided. When the
function has no return value you use “void” as the funciotn returns type.
These kinds of functions in some programming language called “Methods”, but MQL4 calling them
functions.

Function call:

We know very well now what the function is (I hope)? How to use the functions in your MQL4?
There’s an extra steps after writing your function to use the function in you program.
This step is calling it (using it).

Assume you have a function which collects the summation of two integers.
This is the function:

int collect (int first_number, int second_number)
{
return(first_number+ second_number);
}

You know how the previous function works, but you want to use it.

You use it like this:

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
46 of 258 6/14/2006 5:36 PM
int a = 10;
int b = 15;
int sum = collect(a,b);
Print (sum);

The example above will print 25 (is it a magic). But how did it know?
The magic line is int sum = collect(a,b); here you declared a variable (sum) to hold the function return
value and gave the function its two parameters (a,b).
You basically called the function.
MQL4 when see your function name, it will take you parameters and go to the function and it will return
–soon- with the result and place them in same line.
It’s very like copying all the lines of the function instead of the place you called the function in, easy right?

Nesting functions inside function:

You can nest function (or more) inside the body of another function. That’s because the caller line is
treated like any normal statement (it’s actually a statement).

For example:

We will use the collect function described above inside another new function which its job is printing the
result of the collection:

void print_collection (int first_number, int second_number)
{
int sum = collect(first_number, second_number);
Print(sum);
}

Here we called the collect function inside the print_collection function body and printed the result. void
means there’s no return vale (do you still remember?).

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
47 of 258 6/14/2006 5:36 PM
MQL4 Special functions init(), deinit() and start():
In MQL4, every program begins with the function “init()” (initialize) and it occurs when you attach your
program(Expert advisor or Custom indicator) to the MetaTrader charts or in the case you change the
financial symbol or the chart periodicity. And its job is initializing the main variables of your program
(you will know about the variables initialization in the next lesson).
When your program finishes its job or you close the chart window or change the financial symbol or the
chart periodicity or shutdown MetaTrader terminal, the function "deinit()" (de-initialize) will occur.
The third function (which is the most important one) “start()” will occur every time new quotations are
received , you spend 90 of your programming life inside this function.
We will know a lot about these functions in our real world lessons when we write our own Expert advisor
and Custom Indictor.
Lesson 8 - Variables in MQL4
What are the variables mean?

As I told you the secret before, the variables are the names that refer to sections of memory into which
data can be stored.
To help you think of this as a picture, imagine that memory is a series of different size boxes. The box size
is memory storage area required in bytes.
In order to use a box to store data, the box must be given a name; this process is known as
declaration.
In the declaration process you use a word tell the computer what’s the kind and size of the box you
want to use, this word known as keyword.
It helps if you give a box a meaningful name that relates to the type of information which make it
easier to find the data, this name is the variable constant.
Data is placed into a box by assigning the data to the box.
When we set the value of the box you have created in the same line you declared the variable; this
process is known as initialization.
When we create a variable we are telling the computer that we want him to assign a specified memory
length (in bytes) to our variable, since storing a simple number, a letter or a large number is not going to
occupy the same space in memory, so the computer will ask us what’s the kind of data and how much the
length of the data? That is the Data type for.

For example if we said this line of code to the computer:

int MyVaraible=0;

That’s mean we are asking the computer to set a block of 4 bytes length to our variable named
“MyVaraiable”.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
48 of 258 6/14/2006 5:36 PM

In the previous example we have used:
int ß Keyword
int ß Integer data type.
int ß Declaration
MyVaraible ß Variable’s constant.
=0 ß Initialization

We will know more about variables in a coming lesson.

In MQL4, these are the kinds of Data types:
Integer (int)
Boolean (bool)
Character (char)
String (string)
Floating-point number (double)
Color (color)
Datetime (datetime)

I’ve copied the previous few lines from the DATA TYPES lesson for you. To know what’s the variable,
now how do to declare the variables:
Declaration:
Declaring a variable means to introduce it to the world and specify its type. By using the keywords you
have learned in the DATA TYPES lesson (int, double, char, bool, string, color and datetime) with the
name you chose to the variable.
For example:
int MyVaraible;

Here you declared a variable named MyVaraible which is an integer type. And before the declaration you
can’t use the MyVariable in your code. If you used it without declaration the MQL4 compiler will
complain and will tell you something like this:'MyVaraible' - variable not defined. 1 error(s), 0 warning(s).
Initialization:
Initializing the variable means to assign a value to it, for example MyVaraible=0; You can initialize the
variable at the same line of the declaration like the example: int MyVaraible=0;
And you can declare the variable in one place and initialize it in another place like this:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
49 of 258 6/14/2006 5:36 PM
int MyVaraible;


MyVaraible=5;
But keep in your mind this fact: the declaration must be before the initialization.
Scopes of variables:
There are two scopes of the variables, Local and Global.
Scope means, which part of code will know about the variable and can use it.
Local variable means they are not seen to outside world where they had declared. For example the
variables declared inside function are local to the function block of code, and the variables declared inside
the loop or decisions block of code are local to those blocks and can be seen or used outside them.
For example:
double my_func (double a, double b, double c)
{
int d ;
return (a*b + c);
}

In the above example the variables a,b,c and d are local variables, which can be used only inside the
function block of code ( any thing beside the braces) and can’t be used by outside code. So we can’t write a
line after the function above saying for example: d=10; because d is not seen to the next line of the function
because it’s outside it.
The second kind of the scopes is the Global variables, and they are the variables which had declared
outside any block of code and can be seen from any part of your code.
For example:
int Global_Variable;
double my_func (double a, double b, double c)
{
return (a*b + c + Global_Variable);
}

Here the variable Global_Variable declared outside the function (function level declaration) so, it can be
seen by all the functions in you program.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
50 of 258 6/14/2006 5:36 PM
The Global variables will automatically set to zero if you didn’t initialize them.
Extern variables:
The keyword “extern” used to declare a special kind of variables; those kinds of variables are used to
define input date of the program, which you can set them form the property of your Expert advisor or
Custom indicator.
For example:
extern color Indicator_color = C'0x00,0x00,0xFF'; // blue
int init()
{
...
}

Here the variable Indicator_color had defined as an extern variable which you will see it the first time you
attach your indicator (or EA) to the MetaTrader chart and which you can change it from the properties
sheet windows. Look at Figure 1.

Figure 1: Property sheet of MA indicator
Here the variables Period, Shift, MA_method, Apply_to and Style are variables defined using the “extern”
keyword so they appear in the property sheet.
Any variable you want the user of your program be able to change and set, make it extern variable.
Lesson 9 - Preprocessors
What are the Preprocessors mean?

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
51 of 258 6/14/2006 5:36 PM
Preprocessors are the instructions you give to the compiler to carry them out before starting (processing)
your code.
For example if you used the preprocessor directive #include <win32.h> that’s mean you telling the
compiler to include the content of the file “win32.h” in the place you wrote the include keyword before
processing your code.

In MQL4 there are four of preprocessors directives:

1- define directive:

define directive used to generate a constant.
The constant is very like the variable with only one different, you set its value only once and you can not
change its value in your code like the variable.

For example:

#define my_constant 100

As you can notice in the above example there’s no assignment symbol (=) but only space between the
constant name (my_constant ) and its value (100).
And you can notice too that the line didn’t end with semi-colon but it ended with a carriage-return
character (new line).

The name of constant obeys the same rules you had learnt about choosing the identifier names (lesson 2
SYNTAX), for example you can’t start the constant name with a number or exceeds 31 characters.

The value of the content can be any type you want.

The compiler will replace each occurrence of constant name in your source code with the corresponding
value.
So you can use the above constant in your code like that:

sum = constant1 * 10;

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
52 of 258 6/14/2006 5:36 PM

2- property directive:

There are predefined constants called “Controlling Compilation” included in the MQL4 language, which
you can set them in your program.
They are the properties of your program which you can set them using the compiler directive “property”
and the compiler will write them in the settings of your executable program (ex4 file).

For example:

#property link "http://www.forex-tsd.com"
#property copyright "Anyone wants to use"

This is the list of the MQL4 predefined constants:


Constant Type Description
link string a link to the company website
copyright string the company name
stacksize int stack size
indicator_chart_window void show the indicator in the chart window
indicator_separate_window void show the indicator in a separate window
indicator_buffers int the number of buffers for calculation, up to 8
indicator_minimum int the bottom border for the chart
indicator_maximum int the top border for the chart
indicator_colorN color
the color for displaying line N, where N lies between 1
and 8
indicator_levelN double
predefined level N for separate window custom
indicator, where N lies between 1 and 8
show_confirm void before script run message box with confirmation appears
show_inputs void
before script run its property sheet appears; disables
show_confirm property


Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
53 of 258 6/14/2006 5:36 PM
3- include directive:

When you asking the compiler to include a file name with the “include” directive, it’s very like when you
copy the entire file content and paste it in the place of the line you write include.

For example:

#include <win32.h>

In the above example you telling the compiler to open the file “win32.h” and reads all of its content and
copy them in the same place of the include statement.

Note: in the above example you enclosed the file name with Angle brackets () and that’s mean you telling
the compiler to use the default directory (usually, terminal_directory\experts\include) to search for the file
win32.h and don’t search the current directory.
If the file you want to include located at the same path of your code, you have to use quotes instead of
angle brackets like this:

#include “mylib.h”

In the both cases if the file can’t be found you will get an error message.

You can use include at anywhere you want but it usually used at the beginning of the source code.

Tip: It’s a good programming practice to write the frequently used code in a separate file and use include
directive to put it in your code when you need (just an advice).

4- import directive:

It’s like include directive in the aspect of using outside file in your program.
But there are differences between them.
You use import only with MQL4 executables files (.ex4) or library files (.dll) to import their functions to
your program.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
54 of 258 6/14/2006 5:36 PM

For example:

#import "user32.dll"
int MessageBoxA(int hWnd,string lpText,string lpCaption,
int uType);
int MessageBoxExA(int hWnd,string lpText,string lpCaption,
int uType,int wLanguageId);
#import "melib.ex4"
#import "gdi32.dll"
int GetDC(int hWnd);
int ReleaseDC(int hWnd,int hDC);
#import

When you import functions from “ex4” file you haven’t to declare their functions to be ready for use.
While importing the functions from a “.dll” file requires you to declare the functions you want to use like
this:

int MessageBoxA(int hWnd,string lpText,string lpCaption,
int uType);

And only the functions you has declared you can use in your code.
You must end the import directives with a blank import line #import (without parameters).
Lesson 12 - Your First Indicator (Part3)
Welcome to the third part of “Your First Indicator” lesson.
In the previous lesson we studied the code of our first indicator line by line and we
reached the function dinit().
I hope you’ve came from the previous lessons with a clear idea about what we have done.
Today we are going to study start() function and its content. And –finally- we will
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
55 of 258 6/14/2006 5:36 PM
compile and run our first Indicator.
Are you ready? Let’s hack the code line by line:
Our Code:
//+------------------------------------------------------------------+
//| My_First_Indicator.mq4 |
//| Codersguru |
//| http://www.forex-tsd.com |
//+------------------------------------------------------------------+
#property copyright "Codersguru"
#property link "http://www.forex-tsd.com"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- buffers
double ExtMapBuffer1[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,ExtMapBuffer1);
string short_name = "Your first indicator is running!";
IndicatorShortName(short_name);
//----
return(1);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
56 of 258 6/14/2006 5:36 PM
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
//---- check for possible errors
if (counted_bars<0) return(-1);
//---- last counted bar will be recounted
if (counted_bars>0) counted_bars--;
int pos=Bars-counted_bars;
double dHigh , dLow , dResult;
Comment("Hi! I'm here on the main chart windows!");
//---- main calculation loop
while(pos>=0)
{
dHigh = High[pos];
dLow = Low[pos];
dResult = dHigh - dLow;
ExtMapBuffer1[pos]= dResult ;
pos--;
}
//----
return(0);
}
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
57 of 258 6/14/2006 5:36 PM
//+------------------------------------------------------------------+
int start()
{...
return(0);
}
As I told you before, we will spend 90% of programming life inside the braces of start()
function. That’s because it’s the most important MQL4 Special functions.
On the contrary of the init() and deinit function, start() will not be called (by the
terminal client) only one time, But every time a new quotation arrives to MetaTrader
terminal client, every time the start() function has been called.
start() function returns an integer value like all of the MQL4 special function, where 0
means no error and any number else means an error has been occurred.
int counted_bars=IndicatorCounted();
_
Here, we have defined the variable counted_bars as an integer type, and we have
assigned to it the returned value of the function IndicatorCounted().
int IndicatorCounted()
This function will return an integer type value holds the count of the bars which our
indicator has been calculated them.
In the first launch of your indicator this count will be 0 because the indicator didn’t
calculate any bars yet. And after that it will be the count of total bars on the chart -1.
(Please see the function Bars below).
__
if (counted_bars<0) return(-1);
We have got the number of counted_bars in the previous line of code by using
IndicatorCounted() function.
This number must be 0 or greater if there’s no errors have been occurred. If it’s less than
0 that’s means we have an error and we have to terminate the start() function using the
return statement.
__
if (counted_bars>0) counted_bars--;
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
58 of 258 6/14/2006 5:36 PM
_
We are checking here if the counted_bars are greater than 0.
If that’s true we decrease this number by subtracting 1 from it.
That’s because we want to recount the last bar again.
We use the decrement operator (please review Lesson 4 - Operations & Expressions) for
decreasing the value of counted_bars by 1.
Note: We can write the expression counted_bars-- like this:
_
_ _ _ _ _ _ _ _ _ __ __ _ _ _ _ _ _ _ _ __ _ _
_
int pos=Bars-counted_bars;
_
Here, we are declaring the variable pos to hold the number of times our calculation loop
will work (see while loop later in this lesson). That’s by subtracting the counted_bars
from the count of total bars on the chart, we get the total bars count using Bars()
function.
It’s a good time to discuss Bars() function and its brother.
Pre-defined MQL4 variables:
Ask, Bid, Bars, Close, Open, High, Low, Time and Volume are functions although
MQL4 called them Pre-defined variables. And I’ll proof to you why they are functions.
Variable means a space in memory and data type you specify.
Function means do something and return some value, For example Bars collects and
returns the number of the bars in chart. So, is it a variable?
Another example will proof for you that they are not variables:
If you type and compile this line of code:
Bars=1;_
You will get this error: 'Bars' - unexpected token
That’s because they are not variables hence you can’t assign a value to them.
Another proof, the next line of code is a valid line and will not generate and error in
compiling:
Alert(Bars(1));_
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
59 of 258 6/14/2006 5:36 PM
You can’t pass parameter to a variable, parameters passed only to the functions.
I’m so sorry for the lengthiness, let’s discuss every function.
int Bars
This function returns an integer type value holds count of the total bars on the current
chart.
double Ask
This function (used in your Expert Advisors) returns a double type value holds the
buyer’s price of the currency pair.
double Bid
This function (used in your Expert Advisor) returns a double type value holds the seller’s
price of the currency pair.
Note: For example, USD/JPY = 133.27/133.32 the left part is called the bid price (that is
a price at which the trader sells), the second (the right part) is called the ask price (the
price at which the trader buys the currency).
double Open[]
This function returns a double type value holds the opening price of the referenced bar.
Where opening price is the price at the beginning of a trade period (year, month, day,
week, hour etc)
For example: Open[0] will return the opening price of the current bar.
double Close[]
This function returns a double type value holds the closing price of the referenced bar.
Where closing price is the price at the end of a trade period
For example: Close[0] will return the closing price of the current bar.
double High[]
This function returns a double type value holds the highest price of the referenced bar.
Where it’s the highest price from prices observed during a trade period.
For example: High [0] will return the highest price of the current bar.
double Low[]
This function returns a double type value holds the lowest price of the referenced bar.
Where it’s the lowest price from prices observed during a trade period.
For example: Low [0] will return the lowest price of the current bar.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
60 of 258 6/14/2006 5:36 PM
double Volume[]
This function returns a double type value holds the average of the total amount of
currency traded within a period of time, usually one day.
For example: Volume [0] will return this average for the current bar.
int Digits
This function returns an integer value holds number of digits after the decimal point
(usually 4).
double Point
This function returns a double value holds point value of the current bar (usually 0.0001.
datetime Time[]
This function returns a datetime type value holds the open time of the referenced bar.
For example: Time [0] will return the open time of the current bar.
double dHigh , dLow , dResult;
We declared three double type variables which we will use them later. Notice the way we
used to declare the three of them at the same line by separating them by coma.
Comment("Hi! I'm here on the main chart windows!");
This line of code uses the Comment function to print the text “Hi! I'm here on the main
chart windows!” on the left top corner of the main chart (figure1).
There are two similar functions:
void Comment( ... )
This function takes the values passed to it (they can be any type) and print them on the
left top corner of the chart (figure 1).
void Print ( ... )
This function takes the values passed to it (they can be any type) and print them to the
expert log (figure 2).
void Alert( ... )
This function takes the values passed to it (they can be any type) and display them in a
dialog box (figure 3)
Figure 1 – Comment
Figure 2- Expert log
Figure 3 - Alerts
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
61 of 258 6/14/2006 5:36 PM
while(pos>=0)
{
dHigh = High[pos];
dLow = Low[pos];
dResult = dHigh - dLow;
ExtMapBuffer1[pos]= dResult ;
pos--;
}
Now, it’s the time to enter the loop for calculating our indicator points to draw them.
Any value we assign to the array ExtMapBuffer1[] will be drawn on the chart (because
we have assign this array to the drawn buffer using SetIndexBuffer function).
Before we enter the loop we have got the number of times the loop will work by
subtracting the counted_bars from the total count of the bars on chart.
The number of times the loop will work called Loop variable which it’s pos variable in
our example.
We use the loop variable as a current bar of the calculation for example High[pos] will
return the highest price of the pos bar.
In the loop body we assign to the variable dHigh the value of the highest price of the
current loop variable.
And assign to the variable dLow the value of the lowest price of the current loop
variable.
The result of subtracting dLow from dHigh will be assigned to the variable dResult.
Then we using the dResult to draw or indicator line, by assigning it to the drawn buffer
array ExtMapBuffer1[].
The last line of the loop is a decrement expression which will decrease the loop variable
pos by 1 every time the loop runs. And when this variable reaches -1 the loop will be
terminated.
Finally, we can compile our indicator. Press F5 or choose Compile from file menu.
That will generate the executable file “My_First_indicator.ex4” which you can load in
your terminal client.
To load your indicator click F4 to bring the terminal client. Then From the Navigator
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
62 of 258 6/14/2006 5:36 PM
window find the My_First_indicator and attach it to the chart (figure4).
Note: The indicator will not do much, but it believed that the subtraction of the highest
and lowest of the price gives us the market's volatility.
Figure 4 – My_First_Indicator
I hope you enjoyed your first indicator. And be prepared to your first Expert Advisor in
the next lesson(s).
I welcome very much your questions and suggestions.
Coders’ Guru
Lesson 13 - Your First Expert Advisor (Part 1)
In the previous lesson we created our first indicator. Although this indicator wasn’t
useful for us as trader, but it was very useful for us as programmers.
The indicators –in general- are very important for the technical analysis of the market in
trying to predict the future prices.
But with the indicators we observe the chart then use our hands to sell, buy and modify
our orders manually. You have to set in front of your terminal, and keep your eyes widely
open.
If you get tired, want to drink a cup of tea or even take a short vacation. You have to
consider one of these solutions:
You may rent someone to observe the terminal for you and calling your mobile phone
every five minutes to tell you what’s going on. If this employee is an expert, he will cost
you the pips you earn. And if he is novice one, he will cost you your capital.
The second solution is using a program to automate your trades.
That’s what the Expert Advisor is for.
The Expert advisor is a program wrote in MQL4 (we are studying MQL4 huh?) uses your
favorite indicators and trade methods to automate your orders.
It can buy, sell and modify the orders for you. It enables you to drink a cup of tea and
save the salary you gave out to your employee or the bunch of flowers you bring to your
assistant wife.
Today we are going to create our first expert advisor so let’s go.
First two steps:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
63 of 258 6/14/2006 5:36 PM
Step1:
If you didn’t open your MetaEditor yet, I think it’s the time to run it.
From the MetaEditor File menu click New (you can use CTRL+N hotkey or click the
New icon in the standard toolbar). That will pop up the new program wizard which you
have seen when you created your first indicator (Figure 1).
This time we will choose the first option “Expert Advisor program” then click Next
button.
Figure 1 – the first step wizard
Step2:
When you clicked Next, you have got the general properties wizard (Figure 2).
This wizard enables you to set the properties of your expert advisor and to set the external
variables you will use in your expert advisor.
In this step you can set these properties:
1- Name of your expert advisor, in our sample we will use My_First_EA.
2- Author name of the program, type your name (I typed mine in the sample).
3- Link to your web site.
4- External variables list:
This is the list of the external variables you allow the user of your expert advisor to
change them from the Expert properties window.
To add a new variable you click the Add button, clicking it will add a new record to
the external variables list. Every record has three fields:
Name: double click this field to set the name (identifier) of the variable.
Type: double click this field to set the data type of the variable.
Initial value: double click this field to give your variable initialization value.
This field is optional which means you can leave it without setting
In our sample we have added three variables:
Varaible _ Type _ initial value
---------------------------------------
TakeProfit _ double _ 350
Lots _ double _ 0.1
TrailingStop _ double _ 35
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
64 of 258 6/14/2006 5:36 PM
Figure 2 – the second step wizard
Now click the Finish button to close the wizard, and MetaEditor will bring to you the
code created by the wizard and saves the file My_First_EA.mq4 in the MetaTrader 4
\experts path.
Note: you have to put the expert advisors in MetaTrader 4\experts path and the
indicators in MetaTrader 4\experts\indicators path, otherwise they will not work.
This is the code we have got from the wizard:
//+------------------------------------------------------------------+
//| My_First_EA.mq4 |
//| Coders Guru |
//| http://www.forex-tsd.com |
//+------------------------------------------------------------------+
#property copyright "Coders Guru"
#property link "http://www.forex-tsd.com"
//---- input parameters
extern double TakeProfit=250.0;
extern double Lots=0.1;
extern double TrailingStop=35.0;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
65 of 258 6/14/2006 5:36 PM
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
As you see above, the code generated by the wizard is a template for you to add your code without
bothering you by typing the main functions from scratch.
Now let’s add our own code:
//+------------------------------------------------------------------+
//| My_First_EA.mq4 |
//| Coders Guru |
//| http://www.forex-tsd.com |
//+------------------------------------------------------------------+
#property copyright "Coders Guru"
#property link "http://www.forex-tsd.com"
//---- input parameters
extern double TakeProfit=250.0;
extern double Lots=0.1;
extern double TrailingStop=35.0;
//+------------------------------------------------------------------+
//| expert initialization function |
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
66 of 258 6/14/2006 5:36 PM
//+------------------------------------------------------------------+
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_dirction = 0;
if(line1>line2)current_dirction = 1; //up
if(line1<line2)current_dirction = 2; //down
if(current_dirction != last_direction) //changed
{
last_direction = current_dirction;
return (last_direction);
}
else
{
return (0);
}
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
67 of 258 6/14/2006 5:36 PM
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
int cnt, ticket, total;
double shortEma, longEma;
if(Bars<100)
{
Print("bars less than 100");
return(0);
}
if(TakeProfit<10)
{
Print("TakeProfit less than 10");
return(0); // check TakeProfit
}
shortEma = iMA(NULL,0,8,0,MODE_EMA,PRICE_CLOSE,0);
longEma = iMA(NULL,0,13,0,MODE_EMA,PRICE_CLOSE,0);
int isCrossed = Crossed (shortEma,longEma);
total = OrdersTotal();
if(total < 1)
{
if(isCrossed == 1)
{
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,
"My EA",12345,0,Green);
if(ticket>0)
{
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
68 of 258 6/14/2006 5:36 PM
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Print("BUY order opened : ",OrderOpenPrice());
}
else Print("Error opening BUY order : ",GetLastError());
return(0);
}
if(isCrossed == 2)
{
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,
Bid-TakeProfit*Point,"My EA",12345,0,Red);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Print("SELL order opened : ",OrderOpenPrice());
}
else Print("Error opening SELL order : ",GetLastError());
return(0);
}
return(0);
}
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()<=OP_SELL && OrderSymbol()==Symbol())
{
if(OrderType()==OP_BUY) // long position is opened
{
// should it be closed?
if(isCrossed == 2)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet);
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
69 of 258 6/14/2006 5:36 PM
// close position
return(0); // exit
}
// check for trailing stop
if(TrailingStop>0)
{
if(Bid-OrderOpenPrice()>Point*TrailingStop)
{
if(OrderStopLoss()<Bid-Point*TrailingStop)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-
Point*TrailingStop,OrderTakeProfit(),0,Green);
return(0);
}
}
}
}
else // go to short position
{
// should it be closed?
if(isCrossed == 1)
{
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet);
// close position
return(0); // exit
}
// check for trailing stop
if(TrailingStop>0)
{
if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
{
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
70 of 258 6/14/2006 5:36 PM
if((OrderStopLoss()>(Ask+Point*TrailingStop)) ||
(OrderStopLoss()==0))
{
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,
OrderTakeProfit(),0,Red);
return(0);
}
}
}
}
}
}
return(0);
}
//+------------------------------------------------------------------+
Note: don’t copy and paste the code above because it warped and will not work for you,
use the code provided with lesson in www.forex-tsd.com .
Scared?
Don’t be scared of the 160 lines you have seen above, we will know everything about this
code line by line, I promise it’s an easy task.
Test the Expert Advisor:
Before studying our expert advisor code we have to be check is it profitable one or not.
Note: Our expert advisor will work with EURUSD pairs in 4 Hours timeframe.
So compile the expert advisor by pressing F5 and load it in MetaTrader.
You can test your expert advisor using two methods:
1- Live trading
In live trading testing the results are more accurate but you have to spend days (and
maybe months) to know is the expert advisor profitable or not.
You have to enable the expert advisor to automate your trades.
To enable it click Tools _ Option menu (or use CTRL+O hotkey), that’s will bring
the Options windows (figure 3), click Expert Advisors tab and enable these options:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
71 of 258 6/14/2006 5:36 PM
Enable Expert Advisors
Allow live trading
And click Ok button
Figure 3 – Enabling expert advisor auto trade
You will see the Smile symbol beside the expert advisor name which means your expert
advisor is working and ready to trade for you (Figure 4).
Figure 4 – Expert advisor is enabled
2- Strategy Tester:
The second method of testing your expert advisor which is less accurate but will not take
time is the Strategy tester. We will know everything about Strategy tester later, let’s now
bring its window by pressing F6 (Figure 5).
When you get the window enter these options:
Symbol: EURUSD.
Period: H4 (4 Hours).
Model: Open price only.
Figure 5 – Strategy tester window
Now click Start button to start testing the expert advisor.
You will see a progress bar and the two tabs (Settings and Journal) became five tabs.
We interested in Report tab (Figure 6); click it to see your profit.
We have a lot to say and to do in the next lesson; I hope you are ready for the challenge.
I welcome very much the questions and the suggestions._
See you
Coders’ Guru
Lesson 14 - Your First Expert Advisor (Part 2)
Welcome to the second part of creating Your First Expert Advisor lesson.
In the previous part we have taken the code generated by the new program wizard and
added our own code which we are going to crack it today line by line.
Did you wear your coding gloves? Let’s crack.
Note: I have to repeat that our expert advisor is for educational purpose only and will
not (or aimed to) make profits.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
72 of 258 6/14/2006 5:36 PM
The code we have:
//+------------------------------------------------------------------+
//| My_First_EA.mq4 |
//| Coders Guru |
//| http://www.forex-tsd.com |
//+------------------------------------------------------------------+
#property copyright "Coders Guru"
#property link "http://www.forex-tsd.com"
//---- input parameters
extern double TakeProfit=250.0;
extern double Lots=0.1;
extern double TrailingStop=35.0;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
int Crossed (double line1 , double line2)
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
73 of 258 6/14/2006 5:36 PM
{
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 cnt, ticket, total;
double shortEma, longEma;
if(Bars<100)
{
Print("bars less than 100");
return(0);
}
if(TakeProfit<10)
{
Print("TakeProfit less than 10");
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
74 of 258 6/14/2006 5:36 PM
return(0); // check TakeProfit
}
shortEma = iMA(NULL,0,8,0,MODE_EMA,PRICE_CLOSE,0);
longEma = iMA(NULL,0,13,0,MODE_EMA,PRICE_CLOSE,0);
int isCrossed = Crossed (shortEma,longEma);
total = OrdersTotal();
if(total < 1)
{
if(isCrossed == 1)
{
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,
"My EA",12345,0,Green);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Print("BUY order opened : ",OrderOpenPrice());
}
else Print("Error opening BUY order : ",GetLastError());
return(0);
}
if(isCrossed == 2)
{
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,
Bid-TakeProfit*Point,"My EA",12345,0,Red);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Print("SELL order opened : ",OrderOpenPrice());
}
else Print("Error opening SELL order : ",GetLastError());
return(0);
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
75 of 258 6/14/2006 5:36 PM
}
return(0);
}
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()<=OP_SELL && OrderSymbol()==Symbol())
{
if(OrderType()==OP_BUY) // long position is opened
{
// should it be closed?
if(isCrossed == 2)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet);
// close position
return(0); // exit
}
// check for trailing stop
if(TrailingStop>0)
{
if(Bid-OrderOpenPrice()>Point*TrailingStop)
{
if(OrderStopLoss()<Bid-Point*TrailingStop)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-
Point*TrailingStop,OrderTakeProfit(),0,Green);
return(0);
}
}
}
}
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
76 of 258 6/14/2006 5:36 PM
else // go to short position
{
// should it be closed?
if(isCrossed == 1)
{
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet);
// close position
return(0); // exit
}
// check for trailing stop
if(TrailingStop>0)
{
if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
{
if((OrderStopLoss()>(Ask+Point*TrailingStop)) ||
(OrderStopLoss()==0))
{
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,
OrderTakeProfit(),0,Red);
return(0);
}
}
}
}
}
}
return(0);
}
//+------------------------------------------------------------------+
The idea behind our expert advisor.
Before digging into cracking our code we have to explain the idea behind our expert
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
77 of 258 6/14/2006 5:36 PM
advisor. Any expert advisor has to decide when to enter the market and when to exit.
And the idea behind any expert advisor is what the entering and exiting conditions are?
Our expert advisor is a simple one and the idea behind it is a simple too, let’s see it.
We use two EMA indicators, the first one is the EMA of 8 days (sort EMA) and the
second one is the EMA of 13 days (long EMA).
Note: using those EMAs or any thought in this lesson is not a recommendation of mine,
they are for educational purpose only.
Entering (Open):
Our expert advisor will enter the market when the short EMA line crosses the long
EMA line, the direction of each lines will determine the order type:
If the short EMA is above the long EMA will buy (long).
If the short EMA is below the long EMA we will sell (short).
We will open only one order at the same time.
Exiting (Close):
Our expert advisor will close the buy order when the short EMA crosses the long EMA
and the short EMA is below the long EMA.
And will close the sell order when the short EMA crosses the long EMA and the short
EMA is above the long EMA.
Our order (buy or sell) will automatically be closed too when the Take profit or the Stop
loss points are reached.
Modifying:
Beside entering (opening) and exiting (closing) the market (positions) our expert advisor
has the ability to modify existing positions based on the idea of Trailing stop point.
We will know how we implemented the idea of Trialing stop later in this lesson.
Now let’s resume our code cracking.
//---- input parameters
extern double TakeProfit=250.0;
extern double Lots=0.1;
extern double TrailingStop=35.0;
In the above lines we have asked the wizard to declare three external variables (which
the user can set them from the properties window of our expert advisor).
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
78 of 258 6/14/2006 5:36 PM
The three variables are double data type. We have initialized them to default values (the
user can change these values from the properties window, but it recommended to leave
the defaults).
I have to pause again to tell you a little story about those variables.
Stop loss:
It’s a limit point you set to your order when reached the order will be closed, this is
useful to minimize your lose when the market going against you.
Stop losses points are always set below the current asking price on a buy or above the
current bid price on a sell.
Trailing Stop
It’s a kind of stop loss order that is set at a percentage level below (for a long position) or
above (for a short position) the market price. The price is adjusted as the price fluctuates.
We will talk about this very important concept later in this lesson.
Take profit:
It’s similar to stop lose in that it’s a limit point you set to your order when reached the
order will be closed
There are, however, two differences:
_ There is no “trailing” point.
_ The exit point must be set above the current market price, instead of below.
Figure 1 – Setting Stop loss and Take profit points
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);
}
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
79 of 258 6/14/2006 5:36 PM
else
{
return (0);
}
}
As I told you before, the idea behind our expert advisor is monitor the crossing of the
short EMA and the long EMA lines. And getting the direction of the crossing (which line
is above and which line is below) which will determine the type of the order (buy, sell,
buy-close and sell-close).
For this goal we have created the Crossed function.
The Crossed function takes two double values as parameters and returns an integer.
The first parameter is the value of the first line we want to monitor (the short EMA in our
case) and the second parameter is the value of the second we want to (the long EMA).
The function will monitor the two lines every time we call it by saving the direction of
the two lines in static variables to remember their state between the repeated calls.
_ It will return 0 if there’s no change happened in the last directions saved.
_ It will return 1 if the direction has changed (the lines crossed each others) and the
first line is above the second line.
_ It will return 2 if the direction has changed (the lines crossed each others) and the
first line is below the second line.
Note: You can use this function in your coming expert advisor to monitor any two lines
and get the crossing direction.
Let’s see how did we write it?
int Crossed (double line1 , double line2)
The above line is the function declaration, it means we want to create Crossed function
which takes two double data type parameters and returns an integer.
When you call this function you have to pass to it two double parameters and it will
return an integer to you.
You have to declare the function before using (calling) it. The place of the function
doesn't matter, I placed it above start() function, but you can place it anywhere else.
static int last_direction = 0;
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
80 of 258 6/14/2006 5:36 PM
static int current_direction = 0;
Here we declared two static integers to hold the current and the last direction of the two
lines. We are going to use these variables (they are static variables which means they
save their value between the repeated calls) to check if there’s a change in the direction of
the lines or not.
we have initialized them to 0 because we don’t want them to work in the first call to the
function (if they worked in the first call the expert advisor will open an order as soon as
we load it in the terminal).
if(current_direction != last_direction) //changed
In this line we compare the two static variables to check for changes between the last call
of our function and the current call.
If last_direction not equal current_direction that’s mean there’s a change happened in the
direction.
last_direction = current_direction;
return (last_direction);
In this case (last_direction not equal current_direction) we have to reset our
last_direction by assigning to it the value of the current_direction.
And we will return the value of the last_direction. This value will be 1 if the first line is
above the second line and 2 if the first line is below the second line.
else
{
return (0);
}
Else (last_direction is equal current_direction) there’s no change in the lines direction
and we have to return 0.
Our program will call this function in its start() function body and use the returned value
to determine the appropriate action.
In the coming part of this lesson we will know how did we call the function, and we will
know a lot about the very important trading functions.
To that day I hope you the best luck.
I welcome very much the questions and the suggestions._
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
81 of 258 6/14/2006 5:36 PM
See you
Coders’ Guru
Lesson 15 - Your First Expert Advisor (Part 3)
In the previous two parts of this lesson, we have introduced our expert advisor and knew
the idea behind it.
And in the Appendix 2 we have studied the Trading Functions which we will use some of
them today in our expert advisor.
Today we will continue cracking the remaining code of the expert advisor.
I hope you have cleared your mind for our discovering mission.
The code we have:
//+------------------------------------------------------------------+
//| My_First_EA.mq4 |
//| Coders Guru |
//| http://www.forex-tsd.com |
//+------------------------------------------------------------------+
#property copyright "Coders Guru"
#property link "http://www.forex-tsd.com"
//---- input parameters
extern double TakeProfit=250.0;
extern double Lots=0.1;
extern double TrailingStop=35.0;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
//----
return(0);
}
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
82 of 258 6/14/2006 5:36 PM
//+------------------------------------------------------------------+
//| 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()
{
//----
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
83 of 258 6/14/2006 5:36 PM
int cnt, ticket, total;
double shortEma, longEma;
if(Bars<100)
{
Print("bars less than 100");
return(0);
}
if(TakeProfit<10)
{
Print("TakeProfit less than 10");
return(0); // check TakeProfit
}
shortEma = iMA(NULL,0,8,0,MODE_EMA,PRICE_CLOSE,0);
longEma = iMA(NULL,0,13,0,MODE_EMA,PRICE_CLOSE,0);
int isCrossed = Crossed (shortEma,longEma);
total = OrdersTotal();
if(total < 1)
{
if(isCrossed == 1)
{
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,
"My EA",12345,0,Green);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Print("BUY order opened : ",OrderOpenPrice());
}
else Print("Error opening BUY order : ",GetLastError());
return(0);
}
if(isCrossed == 2)
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
84 of 258 6/14/2006 5:36 PM
{
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,
Bid-TakeProfit*Point,"My EA",12345,0,Red);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Print("SELL order opened : ",OrderOpenPrice());
}
else Print("Error opening SELL order : ",GetLastError());
return(0);
}
return(0);
}
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()<=OP_SELL && OrderSymbol()==Symbol())
{
if(OrderType()==OP_BUY) // long position is opened
{
// should it be closed?
if(isCrossed == 2)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet);
// close position
return(0); // exit
}
// check for trailing stop
if(TrailingStop>0)
{
if(Bid-OrderOpenPrice()>Point*TrailingStop)
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
85 of 258 6/14/2006 5:36 PM
{
if(OrderStopLoss()<Bid-Point*TrailingStop)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-
Point*TrailingStop,OrderTakeProfit(),0,Green);
return(0);
}
}
}
}
else // go to short position
{
// should it be closed?
if(isCrossed == 1)
{
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet);
// close position
return(0); // exit
}
// check for trailing stop
if(TrailingStop>0)
{
if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
{
if((OrderStopLoss()>(Ask+Point*TrailingStop)) ||
(OrderStopLoss()==0))
{
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,
OrderTakeProfit(),0,Red);
return(0);
}
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
86 of 258 6/14/2006 5:36 PM
}
}
}
}
}
return(0);
}
//+------------------------------------------------------------------+
int cnt, ticket, total;
In this line we declared three integer type variables.
We used one line to declare the three of them because they are the same type (You can’t
use a single line declaration with dissimilar data types).
Note: To declare multi variables in a single line you start the line with the declaration
keyword which indicates the type of the variables then separate the variables identifiers
(names) with comma.
You can divide the above line into three lines like that
int cnt;
int ticket;
int total;
We will use the cnt variable as a counter in our “opened orders checking loop”.
We will use the ticket variable to hold the ticket number returned by OrderSend function.
And we will use the total variable to hold the number of already opened orders.
double shortEma, longEma;
Again, we used a single line to declare two double variables.
We will use these variables to hold the value of short EMA and long EMA.
As you remember (I hope) from the previous part we uses the Crossing of short and long
EMAs as buying and selling conditions and as closing conditions too.
if(Bars<100)
{
Print("bars less than 100");
return(0);
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
87 of 258 6/14/2006 5:36 PM
}
We want to work with a normal chart and we assume that the normal chart must have
more than 100 bars. That’s because the insufficient numbers of bars will not enable or
EMA indicators to work right.
We have got the number of bars on the chart using the Bars function and checked this
number to find is it less than 100 or not. If it’s less than 100 we will do two things:
We will tell the user what’s the wrong by writing this message to the Experts log "bars
less than 100" (Figure 1).
Then we will terminate the start function by the line retrun(0);
That’s the way we refuse to work with less than 100 bars on the chart.
Figure 1 – Experts log
if(TakeProfit<10)
{
Print("TakeProfit less than 10");
return(0); // check TakeProfit
}
We don’t want too to work with insufficient value of TakeProfit.
The TakeProfit variable is an external variable and that’s mean the user can change its
default value from the expert advisor properties windows.
We want to protect the user of our expert advisor from his bad choices.
We assume that any value less than 10 for the TakeProfi variable will be bad choice and
for that we have checked the TakeProfit value the user set to find is it less than 10 or not.
If it’s less than 10 we will inform the user what’s the wrong by printing him the message
"TakeProfit less than 10", and we will terminate the start function by return(0) statement.
shortEma = iMA(NULL,0,8,0,MODE_EMA,PRICE_CLOSE,0);
longEma = iMA(NULL,0,13,0,MODE_EMA,PRICE_CLOSE,0);
Well, everything is OK, the bars on the chart were more than 100 bars and the value of
TakeProfit the user supplied was more than 10.
We want now to calculate the short and long EMAs of the current bar.
We use the MQL4 built-in technical indicator function iMA which calculates the moving
average indicator.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
88 of 258 6/14/2006 5:36 PM
I have to pause here for a couple of minutes to tell you more details about iMA function.
iMA:
Syntax:
double iMA( string symbol, int timeframe, int period, int ma_shift, int ma_method, int
applied_price, int shift)
Description:
The iMA function calculates the moving average indicator and returns its value (double
data type).
Note: A moving average is an average price of a certain currency over a certain time interval
(in days, hours, minutes etc) during an observation period divided by these time intervals.
Parameters:
This function takes 7 parameters:
string symbol:
The symbol name of the currency pair you trading (Ex: EURUSD and USDJPY).
If you want to use the current symbol use NULL as a parameter.
int timeframe:
The time frame you want to use for the moving average calculation.
You can use one of these time frame 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 Time frame used on the chart.
If you want to use the current timeframe, use 0 as a parameter.
Note: You can use the integer representation of the period or its constant name.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
89 of 258 6/14/2006 5:36 PM
For example, the line:
iMA(NULL, PERIOD_H4,8,0,MODE_EMA,PRICE_CLOSE,0);
is equal to
iMA(NULL,240,8,0,MODE_EMA,PRICE_CLOSE,0);
But it's recommended to use the constant name to make your code clearer.
int period:
The number of days you want to use for the moving average calculation.
int ma_shift:
The number of the bars you want to shift the moving average line relative to beginning of
the chart:
0 means no shift (Figure 2)
A positive value shifts the line to right (Figure 3)
A negative value shifts the line to left (Figure 4)
int ma_method:
The moving average method you want to use for the moving average calculation,
It can be one of these values:
Constant Value Description
MODE_SMA 0 Simple moving average.
MODE_EMA 1 Exponential moving average.
MODE_SMMA 2 Smoothed moving average.
MODE_LWMA 3 Linear weighted moving average.
int applied_price:
The price you want to use for the moving average calculation,
It can be one of these values:
Constant Value Description
PRICE_CLOSE 0 Close price.
PRICE_OPEN 1 Open price.
PRICE_HIGH 2 High price.
PRICE_LOW 3 Low price.
PRICE_MEDIAN 4 Median price, (high+low)/2.
PRICE_TYPICAL 5 Typical price, (high+low+close)/3.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
90 of 258 6/14/2006 5:36 PM
PRICE_WEIGHTED 6 Weighted close price, (high+low+close+close)/4.
int shift:
The number of bars (relative to the current bar) you want to use for the moving average
calculation. Use 0 for the current bar.
Figure 2 : ma_ shift = 0
Figure 3: ma_shift = 10
Figure 4: ma_shift = -10
shortEma = iMA(NULL,0,8,0,MODE_EMA,PRICE_CLOSE,0);
longEma = iMA(NULL,0,13,0,MODE_EMA,PRICE_CLOSE,0);
Now you know what the above lines means.
We assigned to the variable shortEma the value of:
8 days closing price based exponential moving average of the current bar.
Which we can briefly call it 8EMA
And assigned to the variable longEma the value of:
13 days closing price based exponential moving average of the current bar.
Which we can briefly call it 13EMA
int isCrossed = Crossed (shortEma,longEma);
Note: The Crossed function takes two double values as parameters and returns an integer.
The first parameter is the value of the first line we want to monitor (the short EMA in our
case) and the second parameter is the value of the second we want to (the long EMA).
The function will monitor the two lines every time we call it by saving the direction of
the two lines in static variables to remember their state between the repeated calls.
It will return 0 if there’s no change happened in the last directions saved.
It will return 1 if the direction has changed (the lines crossed each others) and the
first line is above the second line.
It will return 2 if the direction has changed (the lines crossed each others) and the
first line is below the second line.
Here we declared an integer variable isCrossed to hold the return value of the function
Corssed. We will use this value to open and close orders.
total = OrdersTotal();
if(total < 1)
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
91 of 258 6/14/2006 5:36 PM
{
…….
}
We assigned the OrdersTotal return value to the variable total.
Note: The OrdersTotal function returns the number of opened and pending orders. If this
number is 0 that means there are no orders (market or pending ones) has been opened.
Please review appendix 2
Then we checked this number (total) to find if there was already opened orders or not. The if
block of code will work only if the total value is lesser than 1 which means there's no already
opened order.
if(isCrossed == 1)
{
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,
"My EA",12345,0,Green);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Print("BUY order opened : ",OrderOpenPrice());
}
else Print("Error opening BUY order : ",GetLastError());
return(0);
}
In the case the shortEma crossed the longEma and the shortEma is above the longEma
we will buy now.
We are using the OrderSend function to open a buy order.
Note: The OrderSend function used to open a sell/buy order or to set a pending order.
It returns the ticket number of the order if succeeded and -1 in failure.
Syntax:
int OrderSend( string symbol, int cmd, double volume, double price, int slippage,
double stoploss, double takeprofit, string comment=NULL, int magic=0, datetime
expiration=0, color arrow_color=CLR_NONE)
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
92 of 258 6/14/2006 5:36 PM
Please review appendix 2
These are the parameters we used with our OrderSend function:
symbol:
We used the Sybmol function to get the symbol name of the current currency and passed
it to the OrderSend function.
cmd:
We used OP_BUY because we want to open a Buy position.
volume:
We used the Lots value that the use has been supplied.
price:
We used the Ask function to get the current ask price and passed it to the OrderSend
function.
slippage:
We used 3 for the slippage value.
stoploss:
We used 0 for stoploss which mean there's no stoploss for that order.
takeprofit:
We multiplied the TakeProfit value the user has been supplied by the return value of the
Point function and added the result to the Ask price.
Note: Point function returns the point size of the current currency symbol.
For example: if you trade EURUSD the point value = .0001 and if you trade EURJPY the
point value should be .01
So, you have to convert your stoploss and takeprofit values to points before using them
with OrderSend or OrderModify functions.
comment:
We used "My EA" string for the comment
magic:
We used the number 12345 for the order magic number.
expiration:
We didn't set an expiration date to our order, so we used 0.
arrow_color:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
93 of 258 6/14/2006 5:36 PM
We set the color of opening arrow to Green (Because we like the money and the money
is green)
The OrderSend function will return the ticket number of the order if succeeded, so we
check it with this line:
if(ticket>0)
We used the OrderSelect function to select the order by its ticket number that's before we
used the OrderOpenPrice function which returns the open price of the selected order.
Everything is OK, the OrderSend returned a proper ticket number (greater than 0) and the
OrderSelect successfully selected the order. It's the good time to tell the user this good
new by printing to him the message "BUY order opened : " plus the opened price of the
order.
Note: For more details about OrderSelect and OrderOpenPrice, please review appendix 2
Else, if the OrderSend function returned -1 which means there was an error opening the
order, we have to tell the user this bad news by printing him the message: "Error opening
BUY order : ", plus the error number returned by the function GetLastError.
And in this case we have to terminate the start function by using return(0).
if(isCrossed == 2)
{
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,
Bid-TakeProfit*Point,"My EA",12345,0,Red);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Print("SELL order opened : ",OrderOpenPrice());
}
else Print("Error opening SELL order : ",GetLastError());
return(0);
}
Here, the opposite scenario, the shortEma crossed the longEma and the shortEma is
below the longEma we will sell now.
We use the OrderSend function to open a Sell order. Can you guess what the differences
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
94 of 258 6/14/2006 5:36 PM
between the Buy parameters and Sell parameters in OrderSend are? Right! You deserve 100
pips as a gift.
These parameters haven't been changed:
symbol is the same.
volume is the same.
slippage is the same.
stoploss is the same.
comment is the same.
magic is the same.
expiration is the same.
These parameters have been changed (that's why you've got the gift):
cmd:
We used OP_SELL because we want to open a Sell position.
price:
We used the Bid function to get the current bid price and passed it to the OrderSend
function.
takeprofit:
We multiplied the TakeProfit value the user has been supplied by the return value of the
Point function and subtracted the result from the Bid price.
arrow_color:
We set the color of opening arrow to Red (Because we like the money and the money is
green but we want a different color for selling position).
We can briefly repeat what will happen after calling the OrderSend with the above
parameters:
The OrderSend returns the ticket number if succeeded.
We check this number to find is it greater than 0 which means no errors.
We used the OrderSelect to select the order before using OrderOpenPrice.
Everything is OK, we tell the user this good news by printing to him the message "Sell
order opened : " plus the opened price of the order.
Else, if the OrderSend function returned -1 we tell the user this bad news by printing him the
message: "Error opening SELL order : ", plus the error number and terminate the start
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
95 of 258 6/14/2006 5:36 PM
function by using return(0).
- Wait a minute! (You said).
- I've noticed that there's a line after the last if block of code you have just explained above.
- Where? (I'm saying).
- Here it's:
return(0);
Yes! Great but I have no pips to gift you this time.
Look carefully to these blocks (braces):
if(total < 1)
{
if(isCrossed == 1)
{
.....
}
if(isCrossed == 2)
{
.....
}
return(0); _ Right!
}
If the shorEma crossed the longEma upward we open Buy order.
If the shorEma crossed the longEma downward we open Sell order.
What if they haven't been crossed yet? That's the job of this line.
We terminate the start function if there was no crossing.
(In the case that isCrossed not equal 1 or 2).
Now we are ready to open Buy and Sell positions.
In the coming part we will crack the remaining of the code and will discuss in details the
MetaTrader Strategy Tester.
I hope you enjoyed the lesson.
I welcome very much your questions and suggestions.
Coders’ Guru
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
96 of 258 6/14/2006 5:36 PM
Account Information functions
Hi folks,

Regardless the type of your account, demo account or a real one; it's very important to have a set of
functions to access this account information, for example the current account balance, the current account
margin value and the current account total profit.
The account information functions are very useful for applying Money Management techniques by
calculating the state of your account balance and margin etc.
Let's study these functions in details.
AccountBalance
Syntax:
double AccountBalance()
Description:
The AccountBalance function returns the balance amount (how much money) of the current account. The
calculation of the balance amount is the calculation of the starting capital + profit or - loss (of closed
trades). The profit are loss are calculated only for the closed trades, so the floating profit/loss is not
calculated within the balance!
Note: All of the Account Information function don't take parameters, see the examples!
Example:
Print("Account balance = ", AccountBalance());

AccountCredit
Syntax:
double AccountCredit()
Description:
The AccountCredit function returns the credit value of the current account
Example:
Print("Account number ", AccountCredit());

AccountCompany
Syntax:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
97 of 258 6/14/2006 5:36 PM
string AccountCompany()
Description:
The AccountCompany function returns the brokerage company name you opened your current account
with, the same as the name you find in the About dialog which you can open from Help menu.
Example:
Print("Account company name ", AccountCompany());

AccountCurrency
Syntax:
string AccountCurrency()
Description:
The AccountCurrency function returns the name of the currency you used to open your account with the
brokerage company, for example USD if you paid your account in US dollars.
Example:
Print("account currency is ", AccountCurrency());

AccountEquity
Syntax:
double AccountEquity()
Description:
The AccountEquity function returns the equity amount of the current account. The calculation of the
balance equity is the calculation of the starting capital + profit or - losses (of all trades). The profit are loss
are calculated for the opened and the closed trades.
Example:
Print("Account equity = ",AccountEquity());

Conversion functions
Hi folks,
Today we are going to talk about a very important set of MQL4 functions; the Conversion functions.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
98 of 258 6/14/2006 5:36 PM
Why should I use Conversion functions?
In many of situations you have a variable in a specific format and you want to use it in another format.
For example: When we use the CurTime() function which returns the current server time; it returns this
time in datetime format.
It will not problem for us if we are going to use this time as a datatime format for example adding to 2
hours to it or substracting it from the local time.
But if we want to display this time to the user using the Alert() function we will face a problem. the Alert()
can't convert automatically from datetime data type to string data type which we want the user to see. In
this case we have to use the conversion function TimeToStr().

Implicit conversions:
Beside the conversions functions we are going to study I have to mention that MQL4 will make implicit
conversions from a data type to other data type when you assign a wrong value for this data type.
For example:
string var1 = 100;
Alert(var1);
In the above code you have assigned an integer to a string variable. MQL4 will convert the number 100
from integer to string.
If you don't sure of that add this line:
Alert(var1+10);
What do you think you'll get? No, not 110 but you will get 10010 (Figure 1). That's because MQL4 has
converted the 100 to string and 10 to string then added them to each others as strings.

Figure 1
Let's study the conversion function available in MQL4!


CharToStr:
Syntax:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
99 of 258 6/14/2006 5:36 PM
string CharToStr( int char_code)
Description:
The CharToStr function converts from Char type to string type; it converts the ASCII char code passed to
it to string.
Parameters:
This function takes only one parameter:
int char_code
The ASCII char code of the character you want to convert it to string.
Example:
for (int cnt = 1 ; cnt < 255 ; cnt++)
{
Print("ASCII code: " + cnt + ": " + CharToStr(cnt));
}

DoubleToStr:
Syntax:
string DoubleToStr( double value, int digits)
Description:
The DoubleToStr function converts from double data type to string type; it converts the double value
passed to the function to string with the number of digits passed to the function.
Parameters:
This function takes two parameters:
double value
The double value you want to convert it to string.
int digits
The number of digits you want the function to use in converting the double value to string. it can be
ranged from 0 (no digits) to 8 (8 digits).
Example:
string value=DoubleToStr(1.2345678, 4);
// value is 1.2346

NormalizeDouble:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
100 of 258 6/14/2006 5:36 PM
Syntax:
double NormalizeDouble( double value, int digits)
Description:
The NormalizeDouble function rounds the double value passed to it to the number of digits passed. It's like
DoubleToStr function but it returns double value instead of string.
Parameters:
This function takes two parameters:
double value
The double value you want to round it.
int digits
The number of digits you want the function to use in rounding the double value. it can be ranged from 0
(no digits) to 8 (8 digits).
Example:
double value=1.2345678;
Print(NormalizeDouble(value,5));
// output: 1.2346

StrToDouble:
Syntax:
double StrToDouble( string value)
Description:
The StrToDouble function converts from string data type to double type; it converts the string value
passed to the function to a double.
Parameters:
This function takes only one parameter:
string value
The string value you want convert it to double value.
Example:
double value=StrToDouble("1.2345678");
Print(value);
// output: 1.2346

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
101 of 258 6/14/2006 5:36 PM
StrToInteger:
Syntax:
int StrToInteger( string value)
Description:
The StrToInteger function converts from string data type to integer type; it converts the string value
passed to the function to an integer.
Parameters:
This function takes only one parameter:
string value
The string value you want convert it to integer value.
Example:
double value=StrToInteger("1999");
Print(value);

StrToTime:
Syntax:
datetime StrToTime( string value)
Description:
The StrToTime function converts from string data type to datetime data type; the string value passed to
the function must be in the format: "yyyy.mm.dd hh:mi"
Parameters:
This function takes only one parameter:
string value
The string value you want convert it to datatime data type. This string have in one of these formats:
"yyyy.mm.dd hh:mi"
"hh:mi"
"yyyy.mm.dd"

Example:
datetime var1;
var1=StrToTime("2003.8.12 17:35");
var1=StrToTime("17:35"); // returns with current date
var1=StrToTime("2003.8.12"); // returns with midnight time "00:00"
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
102 of 258 6/14/2006 5:36 PM

TimeToStr:
Syntax:
string TimeToStr( datetime value, int mode=TIME_DATE|TIME_MINUTES)
Description:
The TimeToStr function converts from datetime data type to string data type; the return string value will
be in the format "yyyy.mm.dd hh:mi".
Parameters:
This function takes two parameters:
datetime value
The datatime value you want to convert it to string. It starts from 00:00 January 1, 1970.
int mode
Optional parameter determine the mode of conversion; what the string format the function will return.
It can be one or combination of these modes:
TIME_DATE the result will be in the format "yyyy.mm.dd",
TIME_MINUTES the result will be in the format"hh:mi",
TIME_SECONDS the result will be in the format "hh:mi:ss".
The default value is TIME_DATE|TIME_MINUTES which means the result will be in the format
"yyyy.mm.dd hh:mi".
Example:
strign var1=TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS);








Date and Time Functions
Hi folks,
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
103 of 258 6/14/2006 5:36 PM
We are going to study today a very important set of MQL4 functions; the Date and Time Functions, which
are the functions that returns the local (your computer) and server time.
As an example to show the importance of these function you can manage the time your expert advisor will
enter the market and exist from the market. Another example with the aid of these functions you can
know how long a position has been opened by subtracting the order opened time (returned by the function
OrderOpenTime) from the current time (returned by he function CurTime which we are going to study it
later).
There are a lot of useful usages of the date and time function that can't be listed here.
Before we dig into studying the date and time function we have to review the datetime data type because
it's the cornerstone of understanding how the date and time is calculating in MQL4.
datatime data type:
datetime data type is a special MQL4 data type, which holds a date and time data. You set the datetime
variable by using the keyword (D) followed by two signal quotations ('). Between the two signal quotations
you write a character line consisting of 6 parts for value of year, month, date, hour, minutes, and seconds.
datetime constant can vary from Jan 1, 1970 to Dec 31, 2037.
For example:
D'2004.01.01 00:00' // New Year
D'1980.07.19 12:30:27'
D'19.07.1980 12:30:27'
D'19.07.1980 12' //equal to D'1980.07.19 12:00:00'
D'01.01.2004' //equal to D'01.01.2004 00:00:00'

We use the keyword datetime to create a datetime variable.
For example:
datetime dtMyBirthDay= D'1972.10.19 12:00:00';
datetime dt1= D'2005.10.22 04:30:00';


Now, let's give the date and time functions a study trip:

CurTime:

Syntax:
datetime CurTime( )
Description:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
104 of 258 6/14/2006 5:36 PM
The CurTime function returns the current server time, it's not always the exact current server time but it's
the last know server time that the terminal has been retrieved it from the server with the last price
quotation.
The return value of the CurTime function is a datetime data type and it's the number of seconds elapsed
from 00:00 January 1, 1970.
What if you used this function (and all the date & time functions) in the testing mode - Back Testing?
In the testing mode the server time will be modeled by the tester.
Parameters:
This function takes no parameters and return datetime value.
Example:
if(CurTime()-OrderOpenTime()<360) return(0);

Day:

Syntax:
int Day( )
Description:
The Day function returns the current day of the month (1, 2, 3, 4, ..... 31) of the last known server time.
The day is modeled in the testing mode.
Parameters:
This function takes no parameters and return integer value.
Example:
if(Day()<5) return(0);

DayOfWeek:

Syntax:
int DayOfWeek( )
Description:
The DayOfWeek function returns the current day of the week of the last know server time:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
105 of 258 6/14/2006 5:36 PM
0 = Sunday
1 = Monday
2 = Tuesday
3 = Wednesday
4 = Thursday
5 = Friday
6 = Saturday
The day of week is modeled in the testing mode.
Parameters:
This function takes no parameters and return integer value.
Example:
// does not work on holidays.
if(DayOfWeek()==0 || DayOfWeek()==6) return(0);

DayOfYear:

Syntax:
int DayOfYear( )
Description:
The DayOfYear function returns the current day of the year (1, 2, 3, .... 365 (366) ) of the last know server
time.
The day of year is modeled in the testing mode.
Parameters:
This function takes no parameters and return integer value.
Example:
if(DayOfYear()==245) return(true);

Hour:

Syntax:
int Hour( )
Description:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
106 of 258 6/14/2006 5:36 PM
The Hour function returns the current hour (0, 1, 2, .... 23 ) of the last know server time.
The hour is modeled in the testing mode.
Note: The hour returned by the Hour function is the hour of the moment the program start and will not
change during the execution of the program.
Parameters:
This function takes no parameters and return integer value.
Example:
if(Hour()>=12 || Hour()<17) return(true);

LocalTime:

Syntax:
datetime LocalTime( )
Description:
The LocalTime function returns the current local computer time. The return value of the LocalTime
function is a datetime data type and it's the number of seconds elapsed from 00:00 January 1, 1970.
The local time is modeled in the testing mode as well as the server time.
Parameters:
This function takes no parameters and return datetime value.
Example:
if(LocalTime()-OrderOpenTime()<360) return(0);

Minute:

Syntax:
int Minute( )
Description:
The Minute function returns the current minute (0, 1, 2, .... 59 ) of the last know server time. Like the
Hour function the minute returned by the Minute function is the minute of the moment the program start
and will not change during the execution of the program.
The minute is modeled in the testing mode.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
107 of 258 6/14/2006 5:36 PM
Parameters:
This function takes no parameters and return integer value.
Example:
if(Minute()<=15) return("first quarter");

Month:

Syntax:
int Month( )
Description:
The Month function returns the current month (0, 1, 2, 3, .... 12 ) of the last know server time.
The month is modeled in the testing mode.
Parameters:
This function takes no parameters and return integer value.
Example:
if(Month()<=5) return("the first half year");

Seconds:

Syntax:
int Seconds( )
Description:
The Seconds function returns the current seconds (0, 1, 2, .... 59 ) of the minute of the last know server
time. Like the Hour and the Minute functions the seconds returned by the Seconds function is the second
of the moment the program start and will not change during the execution of the program.
The minute is modeled in the testing mode.
Parameters:
This function takes no parameters and return integer value.
Example:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
108 of 258 6/14/2006 5:36 PM
if(Seconds()<=15) return(0);

Year:

Syntax:
int Year( )
Description:
The Year function returns the current year of the last know server time.
The year is modeled in the testing mode.
Parameters:
This function takes no parameters and return integer value.
Example:
// return if the date is within the range from 1 Jan. to 30 Apr., 2006.
if(Year()==2006 && Month()<5) return(0);

TimeDay:

Syntax:
int TimeDay(datetime date)
Description:
The TimeDay function returns the day of the month (1, 2, 3, ... 31) of the given date. It extracts the day of
the month from the given date
Parameters:
datetime date:
The date (datetime data type) you want to extract the day of the month from.
Example:
int day=TimeDay(D'2003.12.31'); // day is 31

TimeDayOfWeek:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
109 of 258 6/14/2006 5:36 PM

Syntax:
int TimeDayOfWeek(datetime date)
Description:
The TimeDayOfWeek function returns the day of the week (0,1, 2, .... 6) of the given date. It extracts the
day of the week from the given date
Parameters:
datetime date:
The date you want to extract the day of the week from.
Example:
int weekday=TimeDayOfWeek(D'2004.11.2'); // day is 2 - Tuesday

TimeDayOfYear:

Syntax:
int TimeDayOfYear(datetime date)
Description:
The TimeDayOfYear function returns the day of the year (1, 2, 3, .... 365 (366)) of the given date. It extracts
the day of the year from the given date
Parameters:
datetime date:
The date you want to extract the day of the year from.
Example:
int day=TimeDayOfYear(CurTime());

TimeHour:

Syntax:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
110 of 258 6/14/2006 5:36 PM
int TimeHour(datetime date)
Description:
The TimeHour function returns the hour of the day (0,1, 2, .... 23) of the given date. It extracts the hours of
the day from the given date
Parameters:
datetime date:
The date you want to extract the hour of the day from.
Example:
int h=TimeHour(CurTime());

TimeMinute:

Syntax:
int TimeMinute(datetime date)
Description:
The TimeMinute function returns the minute of the hour (0,1, 2, .... 59) of the given date. It extracts the
minute of the hour from the given date
Parameters:
datetime date:
The date you want to extract the minute of the hour from.
Example:
int m=TimeMinute(CurTime());

TimeMonth:

Syntax:
int TimeMonth(datetime date)
Description:
The TimeMonth function returns the month of the year (1, 2, 3, .... 12) of the given date. It extracts the
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
111 of 258 6/14/2006 5:36 PM
month of the year from the given date
Parameters:
datetime date:
The date you want to extract the month of the year from.
Example:
int m=TimeMonth(CurTime());

TimeSeconds:

Syntax:
int TimeSeconds(datetime date)
Description:
The TimeSeconds function returns the seconds of the minute (0,1, 2, .... 59) of the given date. It extracts the
seconds of the minute from the given date
Parameters:
datetime date:
The date you want to extract the seconds of the minute from.
Example:
if(Seconds()<=15) return(0);

TimeYear:

Syntax:
int TimeYear(datetime date)
Description:
The TimeYear function returns the year of the given date. It extracts the year from the given date
Parameters:
datetime date:
The date you want to extract the year from.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
112 of 258 6/14/2006 5:36 PM
Example:
// return if the date is within the range from 1 Jan. to 30 Apr., 2006.
if(Year()==2006 && Month()<5) return(0);

Hope you enjoyed the lesson!
Coders Guru
Examples: Money Management
Hi folks,

One of the most important keys (if not the most important one) of success trading is the Money
Management technique you apply to your trading operations.
The Money Management is how to handle the money you put in one or more trades, where you put more
money in the good trades and put less money in the bad trades. And at the same time how to handle the
capital you using in your trading account where you spend more when you have more balance and spend
less when you have less balance.

The most of traders think first in when to buy/sell but the successful ones think first how manage the risk
before buying/selling
The Money Management briefly is the art of handling the size of the trade


Because we are in the development section we are taking another approach of talking about the Money
Management, we are going to talk about a MQL4 code which enable us to apply our Money Managements
and Risk controller techniques in the case of writing an expert advisor.

We have a simple here in MQL4.
//+------------------------------------------------------------------+
//| EMA_CROSS_2.mq4 |
//| Coders Guru |
//| http://www.forex-tsd.com |
//+------------------------------------------------------------------+
#property copyright "Coders Guru"
#property link "http://www.forex-tsd.com"
#define MAGICMA 20060306
//---- Trades limits
extern double TakeProfit=180;
extern double TrailingStop=30;
extern double StopLoss=70;
extern bool UseStopLoss = false;
extern double HedgingTakeProfit=20;
extern double HedgingStopLoss=10;
extern bool UseHedging = true;
extern bool ContinuesHedging = true;
//---- EMAs paris
extern int ShortEma = 10;
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
113 of 258 6/14/2006 5:36 PM
extern int LongEma = 80;
//---- Crossing options
extern bool ImmediateTrade = true; //Open trades immediately or wait for cross.
extern bool CounterTrend = true; //Use the originally CounterTrend crossing method or not
//---- Money Management
extern double Lots = 1;
extern bool UseMoneyManagement = true; //Use Money Management or not
extern bool AccountIsMicro = false; //Use Micro-Account or not
extern int Risk = 10; //10%
//---- Time Management
extern bool UseHourTrade = false;
extern int FromHourTrade = 8;
extern int ToHourTrade = 18;
extern bool Show_Settings = true;
extern bool Summarized = false;
extern double slippage = 3;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
if(Show_Settings && Summarized == false) Print_Details();
else if(Show_Settings && Summarized) Print_Details_Summarized();
else Comment("");
//----

return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}

bool isNewSumbol(string current_symbol)
{
//loop through all the opened order and compare the symbols
int total = OrdersTotal();
for(int cnt = 0 ; cnt < total ; cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
string selected_symbol = OrderSymbol();
if (current_symbol == selected_symbol)
return (False);
}
return (True);
}
int Crossed()
{
double EmaLongPrevious = iMA(NULL,0,LongEma,0,MODE_EMA, PRICE_CLOSE, 1);
double EmaLongCurrent = iMA(NULL,0,LongEma,0,MODE_EMA, PRICE_CLOSE, 0);
double EmaShortPrevious = iMA(NULL,0,ShortEma,0,MODE_EMA, PRICE_CLOSE, 1);
double EmaShortCurrent = iMA(NULL,0,ShortEma,0,MODE_EMA, PRICE_CLOSE, 0);

if(ImmediateTrade)
{
if (EmaShortCurrent<EmaLongCurrent)return (1); //down trend
if (EmaShortCurrent>EmaLongCurrent)return (2); //up trend
}

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
114 of 258 6/14/2006 5:36 PM
if (EmaShortPrevious>EmaLongPrevious && EmaShortCurrent<EmaLongCurrent ) return (1); //down trend
if (EmaShortPrevious<EmaLongPrevious && EmaShortCurrent>EmaLongCurrent ) return (2); //up trend
return (0); //elsewhere
}
//--- Bassed on Alex idea! More ideas are coming
double LotSize()
{
double lotMM = MathCeil(AccountFreeMargin() * Risk / 1000) / 100;

if(AccountIsMicro==false) //normal account
{
if (lotMM < 0.1) lotMM = Lots;
if ((lotMM > 0.5) && (lotMM < 1)) lotMM=0.5; //Thanks cucurucu
if (lotMM > 1.0) lotMM = MathCeil(lotMM);
if (lotMM > 100) lotMM = 100;
}
else //micro account
{
if (lotMM < 0.01) lotMM = Lots;
if (lotMM > 1.0) lotMM = MathCeil(lotMM);
if (lotMM > 100) lotMM = 100;
}

return (lotMM);
}
string BoolToStr ( bool value)
{
if(value) return ("True");
else return ("False");
}
void Print_Details()
{
string sComment = "";
string sp = "----------------------------------------\n";
string NL = "\n";
sComment = sp;
sComment = sComment + "TakeProfit=" + DoubleToStr(TakeProfit,0) + " | ";
sComment = sComment + "TrailingStop=" + DoubleToStr(TrailingStop,0) + " | ";
sComment = sComment + "StopLoss=" + DoubleToStr(StopLoss,0) + " | ";
sComment = sComment + "UseStopLoss=" + BoolToStr(UseStopLoss) + NL;
sComment = sComment + sp;
sComment = sComment + "ImmediateTrade=" + BoolToStr(ImmediateTrade) + " | ";
sComment = sComment + "CounterTrend=" + BoolToStr(CounterTrend) + " | " ;
if(UseHourTrade)
{
sComment = sComment + "UseHourTrade=" + BoolToStr(UseHourTrade) + " | ";
sComment = sComment + "FromHourTrade=" + DoubleToStr(FromHourTrade,0) + " | ";
sComment = sComment + "ToHourTrade=" + DoubleToStr(ToHourTrade,0) + NL;
}
else
{
sComment = sComment + "UseHourTrade=" + BoolToStr(UseHourTrade) + NL;
}

sComment = sComment + sp;
sComment = sComment + "Lots=" + DoubleToStr(Lots,0) + " | ";
sComment = sComment + "UseMoneyManagement=" + BoolToStr(UseMoneyManagement) + " | ";
sComment = sComment + "AccountIsMicro=" + BoolToStr(AccountIsMicro) + " | ";
sComment = sComment + "Risk=" + DoubleToStr(Risk,0) + "%" + NL;
sComment = sComment + sp;

Comment(sComment);
}
void Print_Details_Summarized()
{
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
115 of 258 6/14/2006 5:36 PM
string sComment = "";
string sp = "----------------------------------------\n";
string NL = "\n";
sComment = sp;
sComment = sComment + "TF=" + DoubleToStr(TakeProfit,0) + " | ";
sComment = sComment + "TS=" + DoubleToStr(TrailingStop,0) + " | ";
sComment = sComment + "SL=" + DoubleToStr(StopLoss,0) + " | ";
sComment = sComment + "USL=" + BoolToStr(UseStopLoss) + NL;
sComment = sComment + sp;
sComment = sComment + "IT=" + BoolToStr(ImmediateTrade) + " | ";
sComment = sComment + "CT=" + BoolToStr(CounterTrend) + " | " ;
if(UseHourTrade)
{
sComment = sComment + "UHT=" + BoolToStr(UseHourTrade) + " | ";
sComment = sComment + "FHT=" + DoubleToStr(FromHourTrade,0) + " | ";
sComment = sComment + "THT=" + DoubleToStr(ToHourTrade,0) + NL;
}
else
{
sComment = sComment + "UHT=" + BoolToStr(UseHourTrade) + NL;
}

sComment = sComment + sp;
sComment = sComment + "L=" + DoubleToStr(Lots,0) + " | ";
sComment = sComment + "MM=" + BoolToStr(UseMoneyManagement) + " | ";
sComment = sComment + "AIM=" + BoolToStr(AccountIsMicro) + " | ";
sComment = sComment + "R=" + DoubleToStr(Risk,0) + "%" + NL;
sComment = sComment + sp;

Comment(sComment);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
if (UseHourTrade)
{
if (!(Hour()>=FromHourTrade && Hour()<=ToHourTrade))
{
Comment("Time for trade has not come yet!");
return(0);
}
}
int cnt, ticket, ticket2, total;

string comment = "";
if(CounterTrend==true) comment = "EMAC_Counter";
if(CounterTrend==false) comment = "EMAC_Pro";
if(ImmediateTrade==true) comment = comment + "_Immediate";
if(ImmediateTrade==false) comment = comment + "Postponed";
if(Bars<100)
{
Print("bars less than 100");
return(0);
}
if(TakeProfit<10)
{
Print("TakeProfit less than 10");
return(0); // check TakeProfit
}

int isCrossed = 0;
isCrossed = Crossed ();

if(CounterTrend==false)
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
116 of 258 6/14/2006 5:36 PM
{
if(isCrossed==1) isCrossed=2;
if(isCrossed==2) isCrossed=1;
}

if(UseMoneyManagement==true) Lots = LotSize(); //Adjust the lot size

total = OrdersTotal();

if(total < 1 || isNewSumbol(Symbol()))
{
if(isCrossed == 1)
{

if(UseStopLoss)
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,slippage,Ask-StopLoss*Point,Ask+TakeProfit*Point,comment,MAGICMA,0,Green);
else
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,slippage,0,Ask+TakeProfit*Point,comment,MAGICMA,0,Green);

if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice());
}
else Print("Error opening BUY order : ",GetLastError());

if(UseHedging) Hedge(ticket,Lots);

return(0);
}
if(isCrossed == 2)
{
if(UseStopLoss)
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,slippage,Bid+StopLoss*Point,Bid-TakeProfit*Point,comment,123,0,Red);
else
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,slippage,0,Bid-TakeProfit*Point,comment,MAGICMA,0,Red);

if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened : ",OrderOpenPrice());
}
else Print("Error opening SELL order : ",GetLastError());

if(UseHedging) Hedge(ticket,Lots);

return(0);
}
return(0);
}




for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()<=OP_SELL && OrderSymbol()==Symbol() && OrderMagicNumber() == MAGICMA)
{
if(OrderType()==OP_BUY) // long position is opened
{
// check for trailing stop
if(TrailingStop>0)
{
if(Bid-OrderOpenPrice()>Point*TrailingStop)
{
if(OrderStopLoss()<Bid-Point*TrailingStop)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green);
return(0);
}
}
}
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
117 of 258 6/14/2006 5:36 PM
}
else // go to short position
{
// check for trailing stop
if(TrailingStop>0)
{
if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
{
if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0))
{
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
return(0);
}
}
}
}
}
}

if(ContinuesHedging && OrdersCount(Symbol()) < 2)
{
//Print(OrdersCount(Symbol()));
for(cnt=0;cnt<total;cnt++)
{
ticket = OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderSymbol() == Symbol())
Hedge(OrderTicket(),OrderLots());
}
}

return(0);
}
//+------------------------------------------------------------------+
int OrdersCount(string symbol)
{
int total = OrdersTotal();
int count =0;
for(int cnt = 0 ; cnt < total ; cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if (symbol == OrderSymbol())
count++;
}
return (count);
}
void Hedge (int order_ticket , double hlots)
{
int ticket, order_type;
double order_profit;
string hcomment = "EMAC_" + Symbol() + "_Hedging";

if(OrderSelect(order_ticket,SELECT_BY_TICKET,MODE_TRADES))
{
order_type = OrderType();
order_profit = OrderProfit();

if(order_type == OP_SELL && order_profit < 0 - slippage)
{
ticket=OrderSend(Symbol(),OP_BUY,hlots,Ask,slippage,Ask-HedgingStopLoss*Point,Ask+He
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("Hedgin BUY order opened : ",OrderOpenPrice());
}
else Print("Error opening Hedgin BUY order : ",GetLastError());
}

if(order_type == OP_BUY && order_profit < 0 - slippage)
{

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
118 of 258 6/14/2006 5:36 PM
ticket=OrderSend(Symbol(),OP_SELL,hlots,Bid,slippage,Bid+HedgingStopLoss*Point,Bid-H

if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("Hedgin SELL order opened : ",OrderOpenPrice());
}
else Print("Error opening Hedgin SELL order : ",GetLastError());
}

}
}


Examples: ProfitProtector Expert Advisor!
Hi folks,
Today we are going to take an idea to create Expert Advisor (That the Expert Advisors are for).
The idea:

How to protect my profits of all opening orders (if there's any) by the mean I want to take them when they
reach a specific amount and close all the trades when the drop down to a specific amount.
For example: There are 4 opened positions and they make profit. They've made 200 Pip right now.
suddenly the profit went to 150 then 100 then I'm losing money.
Our code today will prevent this situation, let's see the idea programicaly.
The problem:

First we want a way to calculate the profit of all opened positions.
When the profit goes to specific amount we are going to close all the opened position. But, we want the
program too to prevent the profit to drop again. So, we want to set another profit point that the program
will prevent any drops below it.
For example: the program will take the profit when it reaches 200 Pips and prevent the profit to drop
below to 100 Pips .
The programming problem now is when to start preventing the profit drop. How to tell the program that
the profit went over 100 Pip and we don't want it drop back?
We need a third point when the profit reach it the program will start to monitor the profit drop.
The example right now is: the program will take the profit when it reaches 200 Pips and start to monitor
the drop down of the profit when the profit reaches 150 Pips and prevent the profit to drop again to 100
Pips level.
Let's convert that to code!
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
119 of 258 6/14/2006 5:36 PM
The code:

Please download the code. I've added the profit protector code to a normal expert advisor of mine. We will
not study the expert advisor strategy in buying/selling/closing/trailing. But we are going to study the code
aimed to protect the profit.
These are the pieces of code concerning our idea:
.....//your normal code
extern double ProfitToProtect = 200;
extern double ProtectStarter = 150;
extern double LossToProtect = 100;
extern bool ProtectProfit= true;
bool ProtectLoss= false;
.....//your normal code
int start()
{
...... //your normal code
if(ProtectProfit)
ProfitProtect(ProfitToProtect);

if(ProtectLoss)
LossProtect(LossToProtect);
.......//your normal code
}
void ProfitProtect(double profit)
{
int total = OrdersTotal();
double MyCurrentProfit=0;
for (int cnt = 0 ; cnt < total ; cnt++)
{
OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
if (OrderMagicNumber() == MagicNumber)
MyCurrentProfit += OrderProfit();
}

if(MyCurrentProfit>=ProtectStarter) //start protection at this level!
ProtectLoss=true;
if(MyCurrentProfit>=profit)
CloseAll();
}
void LossProtect(double profit)
{
int total = OrdersTotal();
double MyCurrentProfit=0;
for (int cnt = 0 ; cnt < total ; cnt++)
{
OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
120 of 258 6/14/2006 5:36 PM
if (OrderMagicNumber() == MagicNumber)
MyCurrentProfit += OrderProfit();
}
if(MyCurrentProfit<=profit)
CloseAll();
}
void CloseAll()
{
int total = OrdersTotal();
for (int cnt = 0 ; cnt < total ; cnt++)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
if (OrderMagicNumber() == MagicNumber)
if(OrderType()==OP_BUY)
OrderClose(OrderTicket(),OrderLots(),Bid,Slippage, Violet);
if(OrderType()==OP_SELL)
OrderClose(OrderTicket(),OrderLots(),Ask,Slippage, Violet);
}
}

Code study:

We have defined our profit point as external variables at the top of the program:
extern double ProfitToProtect = 200;
extern double ProtectStarter = 150;
extern double LossToProtect = 100;
extern bool ProtectProfit= true;
Where the the ProfitToProtect is the amount we want the program to take the profit when it is reached.
And the ProtectStarter is the amount the program start at monitoring the profit to prevent drop down
again. And finally the LossToProtect is the amount of the profit the program prevent the profit to drop
below it.
We have added the option to the user to use our profit protector or not with the variable ProtectProfit;
bool ProtectLoss= false;
We have declared this variable outside the start() function to make it in a global scope and we will use this
variable to start the profit monitoring.
if(ProtectProfit)
ProfitProtect(ProfitToProtect);
If the user has chosen to use our protect (ProtectProfit=True) then the program will call the function
ProfitProtect(). We are going to study this function soon.
if(ProtectLoss)
LossProtect(LossToProtect);
If the ProtectLoss variable is true (It will be true when the profit reaches the ProtectStarter level) then the
program will call the function LossProtect() which we are going to study it soon.
void ProfitProtect(double profit)
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
121 of 258 6/14/2006 5:36 PM
{
int total = OrdersTotal();
double MyCurrentProfit=0;
for (int cnt = 0 ; cnt < total ; cnt++)
{
OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
if (OrderMagicNumber() == MagicNumber)
MyCurrentProfit += OrderProfit();
}

if(MyCurrentProfit>=ProtectStarter) //start protection at this level!
ProtectLoss=true;
if(MyCurrentProfit>=profit)
CloseAll();
}
The ProfitProtect() function takes a double parameter (profit you want to protect).
It starts by getting the number of opened orders by calling the function OrdersTotal()
then it declares a double variable MyCurrentProfit and initialize it to 0. We will use this variable to
calculate the profit of the opened positions.
Now we enter in loop from 0 to the count of the opened positions. In every loop we select the order using
OrderSelect() function and examine is the MagicNumber of the order is the same as our MagicNumber
variable to be sure that we are working only with the positions have been opened with our Expert Advisor.
Then we get the profit of the order using OrderProfit() and add it to the MyCurrentProfit variable.
Now we have the total profit stored in the MyCurrentProfit variable, We can check it now to find did it
reach the ProtectStarter value; if true we will enable ProtectLoss. And we have to check the
MyCurrentProfit variable against ProfitToProtect variable to find did it reach it or not; if true we will call
the CloseAll() function which will close all the opened positions.
void LossProtect(double profit)
{
int total = OrdersTotal();
double MyCurrentProfit=0;
for (int cnt = 0 ; cnt < total ; cnt++)
{
OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
if (OrderMagicNumber() == MagicNumber)
MyCurrentProfit += OrderProfit();
}
if(MyCurrentProfit<=profit)
CloseAll();
}
The LossProtect() function is very like the ProfitProtect() function, the only difference is it will monitor
the MyCurrentProfit value and close all the opened position if it goes below the LossToProtect vlaue.
void CloseAll()
{
int total = OrdersTotal();
for (int cnt = 0 ; cnt < total ; cnt++)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
if (OrderMagicNumber() == MagicNumber)
if(OrderType()==OP_BUY)
OrderClose(OrderTicket(),OrderLots(),Bid,Slippage, Violet);
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
122 of 258 6/14/2006 5:36 PM
if(OrderType()==OP_SELL)
OrderClose(OrderTicket(),OrderLots(),Ask,Slippage, Violet);
}
}

The CloseAll() function goes through all the opened position and check them against our expert
MagicNubmer then close every buy or sell position using OrderClose() function.
I hope everything is clear, And hope you find it a useful idea!
Coders Guru

Global variables
Hi folks,
Today we are going to study a set of MQL4 functions which needs to be clearer for the new comers to the
language. We are going to study the Global variables and the MQL4 functions that handle them.

What are the global variables?

The global variables are places to store data between the instances of MQL4 programs and MetaTrader
launches too.
In MQL4 you use the normal variables to store the data temporary and it exists only at the time that
program is running and vanishes with the un-initialization of the program. But the global variables exist
when you un-initialize the program and even if you shut down the terminal itself. The terminal can store
the global variables for four weeks from the last store.

How useful the global variables?

The main job of the global variables is enabling the inner communication between the experts advisor.

Assume that you have created two expert advisors:
The first expert advisor works on daily time frame and buys the EURUSD when the Moving Averages of
the price of the last 10 days crosses upward the Moving Averages of the price of the last 80 days.
And it sells the EURUSD when the Moving Averages of the price of the last 10 days crosses downward the
Moving Averages of the price of the last 80 days.

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
123 of 258 6/14/2006 5:36 PM
And the second expert advisor works on 1 hour time frame and buys the EURUSD when the Moving
Averages of the price of the last 10 hours crosses upward the Moving Averages of the price of the last 80
hours.
And it sells the EURUSD when the Moving Averages of the price of the last 10 hours crosses downward
the Moving Averages of the price of the last 80 hours.

You don't want the two expert advisors to take conflicted decisions. You don't want the first expert
advisor to sell the EURUSD while the second expert advisor is buying the EURUSD.

Any of the two expert advisors doesn't know anything about the other. How can they communicate?
They can communicate with the aid of writing/reading global variables.
For instance the first expert advisor can write a global variable when it open sell/buy order while the
second expert advisor can read this variable to be sure that it will not open a conflicting orders.

Of course the possibilities of using global variables are not limited. Our example today will use the global
variables in a very useful way.

Our example:
When you attach an expert advisor to more than one chart/pair and want to change one of the expert
advisor inputs values for all the charts you have to change this input for every chart.
If your expert advisor attached to ten pairs it will be a real problem to make the change 10 times.
Our program today will use the global variables to make the changes available to all the charts hold our
expert advisor.


Global variables functions:
There are 6 functions in MQL4 responsible of handling the global variables. These are the global variables
functions:

GlobalVariableCheck:
Syntax:
bool GlobalVariableCheck (string name)
Description:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
124 of 258 6/14/2006 5:36 PM
The GlobalVariableCheck function checks if there's a global variable with the name passed to, it returns
true if it exists and false if not exists.
You can use GetLastError to get the error information if any error has been occurred will you calling this
function.
Parameters:
This function takes only one parameter:
string name
The global variable name the function will check is it exists or not.
Example:

if(!GlobalVariableCheck("ge_TakeProfit "))
Alert("ge_TakeProfit global variable is not exist");


GlobalVariableDel:
Syntax:

bool GlobalVariableDel (string name)
Description:

The GlobalVariableDel function deletes the global variable you passed its name and return true in success
and false if it failed to delete it.
You can use GetLastError to get the error information if any error has been occurred will you calling this
function.

Note: If the global variable not found the returned value will be 0 while the error code will be 4057 which
means global variables processing error.

Parameters:
This function takes only one parameter:
string name
The global variable name the function will delete.

Example:

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
125 of 258 6/14/2006 5:36 PM
Alert(GlobalVariableDel("ge_TakeProfit "));


GlobalVariableGet:
Syntax:

double GlobalVariableGet (string name)

Description:

The GlobalVariableGet function returns the value of the global variable name passed to it. This value must
to be double data type.
You can use GetLastError to get the error information if any error has been occurred will you calling this
function.

Note: You can store in the global variable and data type but the double data type. And if you tried to store any
data type other than the double data type, MQL4 will try to convert it to double data type.

Note: If the global variable not found the returned value will be 0 while the error code will be 4058 which
means global variable not found. So, you have to use GlobalVariableCheck function before using
GlobalVariableGet if your variable maybe 0.

Parameters:
This function takes only one parameter:
string name
The global variable name the function will return its stored value.
Example:

if(GlobalVariableCheck("ge_TakeProfit"))
TakeProfit = GlobalVariableGet("ge_TakeProfit");


GlobalVariableSet:
Syntax:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
126 of 258 6/14/2006 5:36 PM

datetime GlobalVariableSet (string name, double value)

Description:

The GlobalVariableSet function sets the variable name passed to it with the value passed to it.
If the global variable name does not exist the function will create it and set it to the passed value. If it
exists the function will change its old value to the new one.
The returned value is a datetime data type which is the time of the last access time of the global variable if
the function successes and if it failed the return value will be 0.
You can use GetLastError to get the error information if any error has been occurred will you calling this
function.

Parameters:
This function takes two parameters:
string name
The global variable name the function will set its value (or create it and sets its value).
double value
The value of the global variable you want to set (or create). This value must be double (numeric) data
type.

Example:

Alert(GlobalVariableDel("ge_TakeProfit "));


GlobalVariableDel:
Syntax:

bool GlobalVariableDel (string name)

Description:

The GlobalVariableDel function deletes the global variable you passed its name and return true in success
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
127 of 258 6/14/2006 5:36 PM
and false if it failed to delete it.
You can use GetLastError to get the error information if any error has been occurred will you calling this
function.

Note: If the global variable not found the returned value will be 0 while the error code will be 4057 which
means global variables processing error.

Parameters:
This function takes only one parameter:

string name
The global variable name the function will delete.

Example:

Alert(GlobalVariableDel("ge_TakeProfit "));


iMaOnArray (Moving average of indicator)
Hi folks,
I've got a lot messages in the forex-tsd forum asking me how to use iMaOnArray function to get the
Moving Average of a specific indicator. Today I'm going to answer all of you in this article.

What's the moving average of indicator?
When you attach an indicator to the chart it uses the price to for it calculation and save (draw) them . You
can calculate the moving average of this array.
I'll give you a manual example before going to create our mql4 version.
Let's say that we will attach the CCI (Commodity Channel Index) indicator to our chart (Figure 1).
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
128 of 258 6/14/2006 5:36 PM

Now we want to get the moving average of the CCI. We can do that by dragging the Moving Average
indicator to the window holds the CCI indicator and choose the Apply to: Previous Indicator's Data
(Figure 2).

And that's what you get (Figure 3)

How to do that programicly?
If you are interested in getting the moving average of any indicator like the above manual setup, you can
'trigger' your MetaEditor and write this code:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
129 of 258 6/14/2006 5:36 PM
//+------------------------------------------------------------------+
//| iMAOnArray.mq4 |
//| Coders Guru |
//| http://www.metatrader.info |
//+------------------------------------------------------------------+
#property copyright "Coders Guru"
#property link "http://www.metatrader.info"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 LawnGreen
#property indicator_color2 DarkBlue
double ExtMapBuffer1[];
double ExtMapBuffer2[];
int init()
{
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,2);
SetIndexBuffer(1,ExtMapBuffer2);

return(0);
}
int deinit()
{
return(0);
}

int start()
{
int bar, limit;

int counted_bars=IndicatorCounted();
if(counted_bars<0) return(-1);
if(counted_bars>0) counted_bars--;
limit=Bars-IndicatorCounted();


for(bar=0; bar<limit; bar++)
ExtMapBuffer1[bar] = iCCI(NULL,0,14,PRICE_TYPICAL,bar);

for(bar=0; bar<limit; bar++)
ExtMapBuffer2[bar]=iMAOnArray(ExtMapBuffer1,Bars,14,0,MODE_EMA,bar);

return(0);
}

As you can notice in the above code that we use the function iCCI and iMAOnArray to calculate the
Moving average of the CCI indicator.
The iCCI function simply calculate the CCI of a giving bar and return its value. We store those values
returned by iCCI function in our buffer ExtMapBuffer1.
Now we have a full of data buffer (ExtMapBuffer1), how to get the Moving Average of this buffer?
iMAOnArray:
With the aid of the iMAOnArray function we can calculate the moving average of the values stored in an
array(buffer).
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
130 of 258 6/14/2006 5:36 PM
This is the syntax of the iMAOnArray function:
double iMAOnArray(double array [],int total,int period,int ma_shift,int ma_method,int shift)
The iMAOnArray - as you see in its syntax - returns double value; this is the value of the moving average -
counted on the array - of the given bar. Don't worry you will understand well when you know the
parameters of the iMAOnArray function.
Parameters:
double array []:
This is the array of the values you want to calculate the moving average of it.
You have to fill this array with double data type items.
In our example we used the bufferex1 as the array[] parameter passed to iMAOnArray after filling that
array with the values of the CCIs of the bars in our chart.
int total:
You use the total parameter to indicate the count of items of the data from the array you want to use to
calculate the moving average.
If you want to use all the items in the array in your moving average calculation pass 0 in the total
parameter.
int period:
The moving average period of the moving average you want to use.
If you are familiar to moving average you can skip this section.
when use the moving average indicator with the hourly chart and use 12 as the period of moving average
calculation ; it means that you want to know the average of the price of the previous 12 hours.
when use the moving average indicator with the daily chart and use 30 as the period of moving average
calculation ; it means that you want to know the average of the price of the previous 30 days.
int ma_method:
The moving average method you want to use in your calculation.
These are the moving average methods available in MetaTrader



Lesson 10 - Your First Indicator (Part1)
Welcome to the practical world of MQL4 courses; welcome to your first indicator in MQL4.
I recommend you to read the previous nine lessons very carefully, before continuing with these series of
courses, that’s because we will use them so much in our explanations and studies of the Expert Advisors
and Custom Indicators which we will create in this series of lessons.
Today we are going to create a simple indictor which will not mean too much for our trade world but it
means too much to our MQL4 programming understanding.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
131 of 258 6/14/2006 5:36 PM

It simply will collect the subtraction of High [] of the price – Low [] of the price; don’t be in a hurry, you
will know everything very soon.
Let’s swim!

MetaEditor:
This is the program which has been shipped with MT4 (MetaTrader 4) enables you to write your
programs, read MQL4 help, compile your program and More.

I’ve made a shortcut for MetaEditor on my desktop for easily access to the program.
If you want to run MetaEditor you have three choices.

1- Run MT4, then click F4, choose MetaEditor from Tools menu or click its icon on the Standard
toolbar (Figure 1).
2- From Start menuà Programs, find MetaTrader 4 group then click MetaEditor.
3- Find the MT4 installation path (usually C:\Program Files\MetaTrader 4), find the MetaEditor.exe
and click it (I recommend to make a shortcut on you desktop).


Figure 1 – MetaTrader Standard Toolbar

Any method you have chosen leads you to MetaEditor as you can see in figure 2.

As you can see in figure 2, there are three windows in MetaEditor:

1- The Editor window which you can write your program in.
2- The Toolbox window which contains three tabs:
a. Errors tab, you see here the errors (if there any) in your code.
b. Find in files tab, you see here the files which contain the keyword you are searching for
using the toolbar command “Find in files” or by clicking CTRL +SHIFT+ F hotkeys.
c. Help tab, you can highlight the keyword you want to know more about it and click F1,
and you will see the help topics in this tab.
3- The Navigator window which contains three tabs:
a. Files tab, for easy access to the files saved in the MT4 folder.
b. Dictionary tab enables you to access the MQL4 help system.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
132 of 258 6/14/2006 5:36 PM
c. Search tab enables you to search the MQL4 dictionary.


Figure 2 – MetaEditor Windows

I recommend you to navigate around the MetaEditor Menus, Toolbar and windows to be familiar with it.

Now let’s enjoy creating our first custom indicator.
Note:Custom Indicator is a program which enables you to use the functions of the technical indicators and it
cannot automate your deals.

First three steps:

Now you have run your MetaEditor and navigated around its Menus, Toolbar and windows, let’s USE it.

To create a custom indicator you have to start with three steps (you will learn later how to skip these
boring steps (my personal opinion).

Step 1: Click File menu à New (you use CTRL+N hotkey or click the New Icon in the Standard toolbar).
You will get a wizard (Figure 3) guiding you to the next step.
Choose Custom Indicator Program option, and then click next.

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
133 of 258 6/14/2006 5:36 PM

Figure 3 - New project wizard

Step 2: When you clicked Next, you will get the second step wizard (Figure 4) which will enable you to edit
the properties of your program. In this step you can enter these properties:
1- Name of your program, this is the name which the world will call you program with and it will be saved
as the_name_you_have_chosen.mq4
2- Author name, the creator of the program name.
3- Link to your web site.
4- External variables list: I want to pause here to remember you about external variable.
External variables are the variables which will be available to the user of you indicator to set from the
properties tab of your indicator in MetaTrader. For example: MA_Period in the very popular EMA
indicator. And these variables will be declared with the “extern” keyword in your code (Please review
Variables lesson).
So, this section of the wizard enables you to add these kinds of variables.

In our first indicator example we will not need any external variables just write the values you see in
figure 4 and let’s go to step 3 by clicking Next button.


Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
134 of 258 6/14/2006 5:36 PM

Figure 4 – Program properties wizard.

Step 3: The third wizard you will get when you clicked Next button is the Drawing properties wizard
(Figure 5).
Its job is enabling you to set the dawning properties of the lines of your indicator, for example: how many
lines, colors and where to draw your indicator (in the main chart or in separate windows).
This wizard contains the following options:

1- Indicator in separate window option: by clicking this option, your indicator will be drawn in separate
windows and not on the main chart window. If you didn’t check the option, your indicator will be drawn
in the main chart window.
2- Minimum option: it will be available (enabled) only if you have checked the Indicator in separate
window option, and its job is setting the bottom border for the chart.
3- Maximum option: it will be available (enabled) only if you have checked the Indicator in separate
window option, and its job is setting the top border for the chart
4- Indexes List: here you add your indicator line and set its default colors.

I want you to wait to the next lesson(s) to know more about these options and don’t be in a hurry.
For our first indicator example, choose Indicator in separate window option and click Add button, when
you click add button the wizard will add a line to the indexes list like you see in figure 5.

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
135 of 258 6/14/2006 5:36 PM

Figure 5 - Drawing properties wizard.

When you click Finish button the Magic will start. You will see the wizard disappeared and the focus
returned to the MetaEditor environment and… guess what?

You have ready to use first indicator draft code.

This is the code you will get:

//+------------------------------------------------------------------+
//| My_First_Indicator.mq4 |
//| Codersguru |
//| http://www.forex-tsd.com |
//+------------------------------------------------------------------+
#property copyright "Codersguru"
#property link "http://www.forex-tsd.com"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- buffers
double ExtMapBuffer1[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,ExtMapBuffer1);
//----
return(0);
}
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
136 of 258 6/14/2006 5:36 PM
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
//----
//----
return(0);
}
//+------------------------------------------------------------------+

As you see in the above code, the wizard has written a lot of code for you, now I have to thank the wizard
and to thank you too.
In the next lesson we will discover every line of code you have seen above and add our code to make our
first indicator. To this lesson I hope you be ready!

Please don’t forget to download the source code of the first indicator and warm yourself for the next
lesson.
I welcome very much the questions and the suggestions.
See you
Coders’ Guru

Lesson 11 - Your First Indicator (Part2)
Welcome to the second part of “Your First Indicator” lesson.
In the previous lesson we didn’t write any line of code, that’s because the New Project
Wizard wrote all the code for us. Thanks!
Today we are going to add few lines to the code the wizard had generated to make our
program more useful.
Afterwards, we are going to explain the whole of the code line by line.
Let’s coding
Code we have added:
We have added the code which in a bold dark blue to our previous code:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
137 of 258 6/14/2006 5:36 PM
//+------------------------------------------------------------------+
//| My_First_Indicator.mq4 |
//| Codersguru |
//| http://www.forex-tsd.com |
//+------------------------------------------------------------------+
#property copyright "Codersguru"
#property link "http://www.forex-tsd.com"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- buffers
double ExtMapBuffer1[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,ExtMapBuffer1);
string short_name = "Your first indicator is running!";
IndicatorShortName(short_name);
//----
return(1);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
138 of 258 6/14/2006 5:36 PM
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
//---- check for possible errors
if (counted_bars<0) return(-1);
//---- last counted bar will be recounted
if (counted_bars>0) counted_bars--;
int pos=Bars-counted_bars;
double dHigh , dLow , dResult;
Comment("Hi! I'm here on the main chart windows!");
//---- main calculation loop
while(pos>=0)
{
dHigh = High[pos];
dLow = Low[pos];
dResult = dHigh - dLow;
ExtMapBuffer1[pos]= dResult ;
pos--;
}
//----
return(0);
}
//+------------------------------------------------------------------+
How will we work?
We will write the line(s) of the code we are going to explain then we will explain them
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
139 of 258 6/14/2006 5:36 PM
afterwards, if there are no topics, we will explain the line(s) of code directly. But at the
most of the time we will pause to discuss some general topics.
I want to here your suggestion about this method please!
Now let’s crack this code line by line.
//+------------------------------------------------------------------+
//| My_First_Indicator.mq4 |
//| Codersguru |
//| http://www.forex-tsd.com |
//+------------------------------------------------------------------+
Comments:
The first five lines of code (which are in gray color) are comments.
You use Comments to write lines in your code which the compiler will ignore them.
You are commenting your code for a lot of reasons:
_ To make it clearer
_ To document some parts like the copyright and creation date etc.
_ To make it understandable.
_ To tell us how the code you have written is work.
_ …
You can write comments in two ways:
Single line comments: The Single line comment starts with “//” and ends with the new
line.
Multi-line comments: The multi-line comment start with “/*” and ends with “*/” and
you can comment more than one line.
In our program the MQL4 wizard gathered from the data we entered the name of the
program, author and the link and wrote them as comments at the top of our program.
#property copyright "Codersguru"
#property link "http://www.forex-tsd.com"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Red
Property directive:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
140 of 258 6/14/2006 5:36 PM
As you notice all of these lines start with the word (#property). That’s because they are
kind of the Preprocessors directives called property directives.
The Preprocessors are the instructions you give to the compiler to carry them out before
starting (processing) your code.
The property directives are predefined constants called “Controlling Compilation”
built in the MQL4 language; their job is setting the properties of your program.
For example: is your Indicator will appear in the main chart window or in a separate
window? Who is the writer of the program?
Note: The preprocessors lines end with a carriage-return character (new line) not a
semi-colon symbol.
We will try to discuss here the property directives available in MQL4.
link:
This property setting the web link to your web site which you asked to enter it in step 2
in the Expert Advisor Wizard (review the previous lesson).
The data type of this property is string.
copyright:
It’s the name of the author of the program, same as the link property you asked to enter
it in step 2 in the Expert Advisor Wizard.
The data type of this property is string.
stacksize:
It’s an integer value sets the memory size for every thread, the default value is 16384.
The data type of this property is integer.
indicator_chart_window:
When you set this property, your indicator will be drawn in the main chart window
(Figure 1). You have to choose one of two options for your Indicators, drawing them in
the main chart windows by using this property, or drawing them in separate windows by
choosing the indicator_separate_window. You can’t use the both of them at the same
time.
The data type of this property is void, which means it takes no value.
indicator_separate_window:
When you set this property, your indicator will be drawn in a separate window (Figure
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
141 of 258 6/14/2006 5:36 PM
1). You can set the scale of the separate indicator window using two properties
indicator_minimum for the minimum value and indicator_maximum for the
maximum value of the scale.
And you can set the level of your indicators on these scales using the property
indicator_levelN where’s the N is the indicator number.
Both of the properties indicator_chart_window and indicator_separate_window are
void data type, which mean they don’t take value and you just write them.
In our program we will draw our indicator in a separate window:
#property indicator_separate_window
Figure 1
indicator_minimum:
With the aid of this property we are setting the minimum value of the separate windows
scale, which is the bottom border of the windows. For example:
#propery indicator_minimum 0
#propery indicator_ maximum 100
Here we have set the bottom border of the window to 0 and the top border to 100 (see
indicator_ maximum), hence we have a scale ranged from 0 to 100 in our separate
window which we are drawing our indicator.
The data type of this property is integer.
indicator_maximum:
With the aid of this property we are setting the maximum value of the separate windows
scale, which is the top border of the windows.
This value must be greater than the indicator_minimum value.
The data type of this property is integer.
Main chart window
Separate window
indicator_levelN:
With the aid of this property we are setting the level of the indicator in the scale we have created with the
properties indicator_minimum and indicator_maximum, this value
must be greater than the indicator_minimum value and smaller than the
indicator_maximum value.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
142 of 258 6/14/2006 5:36 PM
N is the indicator number which we are setting its level, it must range from 1 to 8
(because we are allowed only to use up to 8 indicator buffers in our program, so we can
set the indicator_level for each of them using its number). For example:
#property indicator_minimum 0
#property indicator_minimum 100
#property indicator_level1 10 //set the first indicator level
#property indicator_level2 65.5 //set the second indicator level
The data type of this property is double.
indicator_buffers:
With the aid of this property we are setting the number of memories spaces (Arrays)
allocated to draw our line(s). When we set the number (ranged from 1 up to 8) we are
telling MQL4: “Please allocate a memory space for me to draw my indicator line”.
In our program we used only one buffer.
#property indicator_buffers 1
That’s because we will draw only one line.
indicator_colorN:
We can use up to 8 lines in our indicator, you can set the color of each of them using this
property indicator_colorN , where the N is the line number which defined by
indicator_buffers.
The user of your Indicator can change this color from the properties dialog of your
Indicator (Figure 2).
In our program the indicator line color will be red.
#property indicator_color1 Red
The data type of this property is color.
Figure 2
double ExtMapBuffer1[];
Arrays:
In our life we usually group similar objects into units, in the programming we also need
to group together the data items of the same type. We use Arrays to do this task.
Arrays are very like the list tables, you group the items in the table and access them the
number of the row. Rows in the Arrays called Indexes.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
143 of 258 6/14/2006 5:36 PM
To declare an array you use a code like that:
int my_array[50];
Here, you have declared an array of integer type, which can hold up to 50 items.
You can access each item in the array using the index of the item, like that:
My_array[10] = 500;
Here, you have set the item number 10 in the array to 500.
You can initialize the array at the same line of the declaration like that:
int my_array[5] = {1,24,15,66,500};
In our program we used this line of code:
double ExtMapBuffer1[];
Here we have declared and array of double type. We will use array to calculate our
values which we will draw them on the chart.
int init()
{
}
Special functions:
Functions are blocks of code which like a machine takes inputs and returns outputs
(Please review lesson 7 – Functions).
In MQL4 there are three special functions
init():
Every program will run this function before any of the other functions, you have to put
here you initialization values of you variables.
start():
Here’s the most of the work, every time a new quotation have received your program
will call this function.
deinit():
This is the last function the program will call before it shutdown, you can put here any
removals you want.
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,ExtMapBuffer1);
string short_name = "Your first indicator is running!";
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
144 of 258 6/14/2006 5:36 PM
IndicatorShortName(short_name);
Custom indicator functions:
I can’t give you a description for all of the indicators functions in this lesson. But we
will use them all in our next lessons with more details. So, we will study here the
functions used in our program.
SetIndexStyle:
void SetIndexStyle( int index, int type, int style=EMPTY, int width=EMPTY, color
clr=CLR_NONE)
This function will set the style of the drawn line.
The index parameter of this function ranges from 1 to 7 (that’s because the array
indexing start with 0 and we have limited 8 line). And it indicte which line we want to
set its style.
The type parameter is the shape type of the line and can be one of the following shape
type’s constants:
DRAW_LINE (draw a line)
DRAW_SECTION (draw section)
DRAW_HISTOGRAM (draw histogram)
DRAW_ARROW (draw arrow)
DRAW_NONE (no draw)
The style parameter is the pen style of drawing the line and can be one of the following
styles’ constants:
STYLE_SOLID (use solid pen)
STYLE_DASH (use dash pen)
STYLE_DOT (use dot pen)
STYLE_DASHDOT (use dash and dot pen)
STYLE_DASHDOTDOT (use dash and double dots)
Or it can be EMPTY (default) which means it will be no changes in the line style.
The width parameter is the width of line and ranges from 1 to 5. Or it can be EMPTY
(default) which means the width will not change.
The clr parameter is the color of the line. It can be any valid color type variable. The
default value is CLR_NONE which means empty state of colors.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
145 of 258 6/14/2006 5:36 PM
In our line of code:
SetIndexStyle(0,DRAW_LINE);
We have set the index to 0 which means we will work with the first (and the only) line.
And we have set the shape type of our line to DRAW_LINE because we want to draw a
line in the chart.
And we have left the other parameters to their default values.
SetIndexBuffer:
bool SetIndexBuffer( int index, double array[])
This function will set the array which we will assign to it our indicator value to the
indicator buffer which will be drawn.
The function takes the index of the buffer where’s 0 is the first buffer and 1 is the second,
etc. Then it takes the name of the array.
It returns true if the function succeeds and false otherwise.
In our program the array which will hold our calculated values is ExtMapBuffer1.
And we have only one indicator buffer (#property indicator_buffers 1). So it
will be the buffer assigned.
IndicatorShortName:
void IndicatorShortName( string name)
This function will set the text which will be showed on the upper left corner of the chart
window (Figure 3) to the text we have inputted.
In our program we declared a string variable and assigned the value “You first indicator
is running” to it, then we passed it to the IndicatorShortName function.
string short_name = "Your first indicator is running!";
IndicatorShortName(short_name);
Figure 3
return(0);
This is the return value of the init() function which terminate the function and pass the
program to the execution of the next function start().
int deinit()
{
//----
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
146 of 258 6/14/2006 5:36 PM
//----
return(0);
}
Nothing new to say about deinit() function.
We will continue with remaining of the code in the next lesson.
I hope you enjoyed the lesson and I welcome your questions.
See you
Coders’ Guru
Lesson 16 - Your First Expert Advisor (Part 4)
we have reached the edge of the moon in our way to the truth, I’m not under the impact
of alcoholic poisoning (I don’t drink at all), but I’m so happy to reach the last part of
explaining or first expert advisor. Yes! This is the last part of the expert advisor lesson.
I hope you enjoyed the journey discovering how to write our simple yet important expert
advisor.
Let’s take the final step.
The code we have:
//+------------------------------------------------------------------+
//| My_First_EA.mq4 |
//| Coders Guru |
//| http://www.forex-tsd.com |
//+------------------------------------------------------------------+
#property copyright "Coders Guru"
#property link "http://www.forex-tsd.com"
//---- input parameters
extern double TakeProfit=250.0;
extern double Lots=0.1;
extern double TrailingStop=35.0;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
147 of 258 6/14/2006 5:36 PM
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);
}
}
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
148 of 258 6/14/2006 5:36 PM
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
int cnt, ticket, total;
double shortEma, longEma;
if(Bars<100)
{
Print("bars less than 100");
return(0);
}
if(TakeProfit<10)
{
Print("TakeProfit less than 10");
return(0); // check TakeProfit
}
shortEma = iMA(NULL,0,8,0,MODE_EMA,PRICE_CLOSE,0);
longEma = iMA(NULL,0,13,0,MODE_EMA,PRICE_CLOSE,0);
int isCrossed = Crossed (shortEma,longEma);
total = OrdersTotal();
if(total < 1)
{
if(isCrossed == 1)
{
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,
"My EA",12345,0,Green);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
149 of 258 6/14/2006 5:36 PM
Print("BUY order opened : ",OrderOpenPrice());
}
else Print("Error opening BUY order : ",GetLastError());
return(0);
}
if(isCrossed == 2)
{
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,
Bid-TakeProfit*Point,"My EA",12345,0,Red);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Print("SELL order opened : ",OrderOpenPrice());
}
else Print("Error opening SELL order : ",GetLastError());
return(0);
}
return(0);
}
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()<=OP_SELL && OrderSymbol()==Symbol())
{
if(OrderType()==OP_BUY) // long position is opened
{
// should it be closed?
if(isCrossed == 2)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet);
// close position
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
150 of 258 6/14/2006 5:36 PM
return(0); // exit
}
// check for trailing stop
if(TrailingStop>0)
{
if(Bid-OrderOpenPrice()>Point*TrailingStop)
{
if(OrderStopLoss()<Bid-Point*TrailingStop)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-
Point*TrailingStop,OrderTakeProfit(),0,Green);
return(0);
}
}
}
}
else // go to short position
{
// should it be closed?
if(isCrossed == 1)
{
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet);
// close position
return(0); // exit
}
// check for trailing stop
if(TrailingStop>0)
{
if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
{
if((OrderStopLoss()>(Ask+Point*TrailingStop)) ||
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
151 of 258 6/14/2006 5:36 PM
(OrderStopLoss()==0))
{
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,
OrderTakeProfit(),0,Red);
return(0);
}
}
}
}
}
}
return(0);
}
//+------------------------------------------------------------------+
In the previous lesson, we checked the OrdersTotal is less than 1 in order to open a Buy
or a Sell orders in the case that there were no already opened orders.
We have used this code:
if(total < 1)
{
if(isCrossed == 1)
{
.....
}
if(isCrossed == 2)
{
.....
}
return(0);
}
This was the Open New Order routine. Today we will study Modify-Close Opened
Orders routine.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
152 of 258 6/14/2006 5:36 PM
for(cnt=0;cnt<total;cnt++)
{
....
}
In the above block of code we used a for loop to go through all the already opened orders.
We start the loop from the cnt = 0 and the end of the loop is the total number of already
orders. Every loop cycle we increase the number of cnt by 1 (cnt++).So, cnt will hold in
every cycle the poison of the order (0,1,2,3 etc) which we will use with OrderSelect
function to select each order by its position.
Our today's mission is studying what's going inside the heart of the above loop.
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()<=OP_SELL && OrderSymbol()==Symbol())
{
....
}
The OrderSelect function used to select an opened order or a pending order by the ticket
number or by index.
We used the OrderSelect here before using the OrderType and OrderSymbol functions
because if we didn't use OrderSelect, the OrderType and OrderSymbol functions will not
work.
Note: You have to use OrderSelect function before the trading functions which takes no
parameters:
OrderMagicNumber, OrderClosePrice, OrderCloseTime, OrderOpenPrice,
OrderOpenTime, OrderComment, OrderCommission, OrderExpiration, OrderLots,
OrderPrint, OrderProfit, OrderStopLoss, OrderSwap, OrderSymbol, OrderTakeProfit,
OrderTicket and OrderType
We used SELECT_BY_POS selecting type which means we want to select the order by its
index (position) not by its ticket number.
Note: The index of the first order is 0 and the index of the second one is 1 index etc.
And we used MODE_TRADES mode which means we will select from the currently
trading orders (opened and pending orders) not from the history.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
153 of 258 6/14/2006 5:36 PM
The OrderType function returns the type of selected order that will be one of:
OP_BUY, OP_SELL, OP_BUYLIMIT, OP_BUYSTOP, OP_SELLLIMIT or
OP_SELLSTOP
We checked the type of the order to find is it equal or lesser than OP_SELL.
Which means it maybe one of two cases: OP_SELL or OP_BUY (because OP_SELL=1
and OP_BUY = 0). We did that because we will not work with pending orders.
We want too to work only with the order opened in the chart we loaded our expert
advisor on, so we check the OrderSymbol of the order with the return value of Symbol
function which returns the current chart symbol. If they are equal it means we are
working with the currently loaded symbol.
So, all the coming code will work only if the OrderType is OP_SELL or OP_BUY and the
Symbol = OrderSymbol.
if(OrderType()==OP_BUY) // long position is opened
{
....
}
We are working only with two types of orders, the first type is OP_BUY.
The code above means:
Is there a long (Buy) position opened? If yes! Execute this block of code….
Let's see what will do in the case of a long position has been opened
if(isCrossed == 2)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet);
// close position
return(0); // exit
}
We have opened a Buy order when the shortEma crossed the longEma upward.
It's a logical to close this position when the shortEma and longEma crosses each others in
reversal direction (downward).
So, we checked the isCrossed to find is it = 2 which means the reversal has been occurred
and in this case we close the Buy order.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
154 of 258 6/14/2006 5:36 PM
We used the OrderClose function to close the order. OrderClose function closes a
specific opened order by its ticket. (Review appendix 2).
We’ve got the ticket number of the selected order using the OrderTicket function and
passed it as the first parameter for OrderClose function.
The second parameter in the OrderClose is Lots (the number of lots); we used the
OrderLots function to get the lots value of the selected order.
The third parameter in OrderClose is the preferred close price and we used the Bid
function to get the bid price of the selected order.
The fourth parameter is the slippage value and we used 3.
The fifth parameter is the color of the closing arrow and we used Violet color.
We didn't forget to terminate the start function with return(0) statement.
// check for trailing stop
if(TrailingStop>0)
{
if(Bid-OrderOpenPrice()>Point*TrailingStop)
{
if(OrderStopLoss()<Bid-Point*TrailingStop)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-
Point*TrailingStop,OrderTakeProfit(),0,Green);
return(0);
}
}
}
Note: We are still inside the block of: if(OrderType()==OP_BUY).
We are going to apply our trailing stop technique for the opened Buy position in this
block of code.
Firstly, we have checked the TrailingStop variable the user supplied to check was it a
valid value or not (greater than 0).
Then we applied our trailing stop technique for the opened Buy orders which is:
We modify the stoploos of the order when the subtraction of the current bid price and
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
155 of 258 6/14/2006 5:36 PM
the opened price of order is greater than the TrailingStop
and
the current stoploss is lesser than the subtraction of the current bid price and the
TrailingStop.
We used the OrderModify function to make the desired modification.
These are parameters we used with OrderModify:
ticket: We've got the current order ticket with OrderTicket function.
price: We’ve got the open price of the order with OrderOpenPrice function.
stoploss: Here's the real work! Because we are in a Buy position we set our new stoploss
to the value of the subtraction of the current bid price and the TrailingStop.
That's our way trailing the stoploss point every time we make profits.
Note: Stop losses are always set BELOW the current bid price on a buy and ABOVE the
current asking price on a sell.
takeprofit: No changes, we've got the current profit value of the order with
OrderTakeProfit function.
expiration: We didn't set an expiration date to our order, so we used 0.
arrow_color: Still Green color.
Finally we terminate the start function.
else // go to short position
{
....
}
Note: else here belongs to the code:
if(OrderType()==OP_BUY) // long position is opened
{
....
}
We have studied the case of the type of the order is a Buy order.
So, we are working now a Sell order type.
Let's see what are we going to do in the case of a short (Sell) position has been already
opened?
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
156 of 258 6/14/2006 5:36 PM
if(isCrossed == 1)
{
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet);
// close position
return(0); // exit
}
We’ve opened a Sell order when the shortEma crossed the longEma downward.
It's the time to close this position when the shortEma and longEma crosses each others in
reversal direction (upward). Which happens in the case of isCrossed = 1.
We used the OrderClose function to close the order, we used the same parameters we use
in the case of closing a Buy order except the third parameters the preferred close price, in
this case is the Ask price.
Then we terminated the start function.
// check for trailing stop
if(TrailingStop>0)
{
if((OrderOpenPrice()-Ask)>Point*TrailingStop)
{
if((OrderStopLoss()>(Ask+Point*TrailingStop)) ||
(OrderStopLoss()==0))
{
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,
OrderTakeProfit(),0,Red);
return(0);
}
}
}
We are going to apply our trailing stop technique for the opened Sell position in this
block of code.
Firstly, we’ve checked the TrailingStop variable the user supplied to check was it a valid
value or not (greater than 0).
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
157 of 258 6/14/2006 5:36 PM
Then we applied our trailing stop technique for the opened Sell orders which is:
We modify the stoploss of the order when the subtraction of the order's opened price
and the current ask price is greater than the TrailingStop
and
the current stoploss is greater than the addition of the current ask price and the
TrailingStop.
We used the OrderModify function to make the desired modification. And used the same
parameters we use in the case of modifying already opened Buy order except the third
parameter which indicates our stoploss value:
We set our new stoploss to the value of the addition of the current ask price and the
TrailingStop.
And the fifth parameter which indicates the color of the arrow in this case is Red.
Then we terminated the start function using return(0);
return(0);
This line terminates the start function in all other case; there are no conditions to open
new positions and there are no needs to close or modify the already opened orders.
Just don’t forget it.
I hope you enjoyed the lesson.
I welcome very much your questions and suggestions.
Coders’ Guru
Life cycle of MQL4 program
Hi folks,
Today we are going to discuss a flustering issue for the most of new MQL4 comers; the life cycle of the
MQL4 program.
What the first block of code is executed first and what the last block of code is executed, what's the phases
of the MQL4 program. What's the different between the life cycle of the expert advisors and script? and a
lot of questions about the MQL4 program life cycle.
Let's know first what happen when the MQL4 starts?

When the MQL4 program starts:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
158 of 258 6/14/2006 5:36 PM
The first time you attach the MQL4 to chart the first thing MetaTrader will do is showing the input dialog
depending on the type of the program:

Expert Advisors:
In this case you'll get the expert advisor input window (Figure 1) which enable you to set the parameters
of the expert advisor if there was any (i.e. take profit and stop loss levels).
Each variable you declare using "extern" keyword will appear in the expert advisor input windows with
its default value.


Indicators:
The same as expert advisors, the first time you attach an indicator to chart you'll get the parameters
window (Figure 2) which enable you to set the parameters of the indicator, the colors of the indicator lines
(Figure 3) and the levels of the sub-window chart (Figure 4).
Each variable you declare using "extern" keyword will appear in the indicator parameters windows with
its default value.
The colors are defined using the preprocessor keyword "#property indicator_colorN", for example:
#property indicator_color1 Silver
#property indicator_color2 Red
and the preset levels are defined using the preprocessor keywords "#property indicator_levelN",
"#property indicator_levelcolor", "#property indicator_levelwidth" and "#property
indicator_levelstyle".
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
159 of 258 6/14/2006 5:36 PM




Scripts:
If there were any inputs coded in the script using the extern keyword, they will appear in the script input
window (Figure 5) only if you used the preprocessor keyword "#property show_inputs".
If you used "#property show_confirm" preprocessor keyword a confirmation message box will appear
before the script input window.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
160 of 258 6/14/2006 5:36 PM


This is the first step MetaTrader will take in the journey of the MQL4 program life. Let's see what will
happen nex?

Initialization phase?
The next phase in the MQL4 program cycle is the initialization phase.
Every line of code you wrote inside the block of init() function will be executed in this phase. This phase
executed if one of these triggers occurred:
1- The first time you attach the program to a new chart (After the input window appearance).
2- When you start MetaTrader and there were opened chart(s) that hosts expert advisors or indicators.
The script is executed only once (to the end of its life cycle) then de-initialized so MetaTrader wouldn't
host opened scripts.
3- When you change the period of the chart and the program was hosted on one or more charts (except the
scripts).
4- When you change the symbol of the chart and the program was hosted on one or more charts (except
the scripts).
5- When you recompile the program in MetaEditor and the program was hosted on one or more charts
(except the scripts).
6- When you change one of the program inputs (hitting F7 hot key to open expert advisor input window
and right click the indicator then choose indicator properties from the context menu - Figure 6).
7- When you change the account the expert advisors will be initialized.
Unlike the above case, the initialization code is executed only one time during the life cycle of the program
and will not be called again till the end of the program.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
161 of 258 6/14/2006 5:36 PM

Execution phase:
After the initialization of the program it will wait for new quotation arrival from the server, every time
MetaTrader receives new price quotation from the server it calls start() function and execute all the lines
of the code in its block.
Note: The scripts is an exception because its start() function is executed once you attach it to the chart and
immediately after the init() function then the script is detached from the chart.
The start() function have to finish its job first before receiving/reacting to new quotations, that means the
code of start() function is executed line by line and only when MetaTrader find the return keyword it will
be ready to call start() function again with the most new quotation.
If there were any quotations that arrived while the execution of start() function it would be ignored by the
program,
Besides the new quotation arrival trigger, the start() function is executed in these cases:
1- For the indicators the start() function is recalled in the case of changing the chart symbol.
2- For the indicators the start() function is recalled in the case of changing the chart period
Note: The start() function will not be run when you open the expert advisor input window, you have to
close it to enable MetaTrader to execute start() function again.
The execution phase is the longest phase in the program cycle life and in the most of programs the start()
function block code is the most important code.

De-initialization phase?
Every program attached has its end, when the program ends its job the block of deinit() function will be
executed.
These are the triggers of the deinit() function:
1- When you shut down MetaTader and the program was hosted on one or more charts.
2- When you close the chart that hosts the program.
3- Before the changing of the period of the chart that hosts the program.
4- Before the changing of the symbol of the chart that hosts the program.
5- When you recompile the program and the program was hosted on one or more charts.
6- When you change the inputs of the program.
7- When you change the account the expert advisors will be de-initialized.

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
162 of 258 6/14/2006 5:36 PM
These was the life cycle of the MQL4 program and it's the time to de-initialize the lesson.
Hope you enjoyed it,
Coders Guru
MarketInfo function
Hi folks,
We are going to complete our series of lessons that answer the question: "How to deal with currency pairs
which are different than the current chart currency (The chart that hosts the expert advisor)? For
example, how to make an expert advisor that can open Buy position of GBPUSD or USDCHF while the
expert advisor is hosted on EURUSD chart?"
In the previous lesson we studied the Timeseries Access functions that enables us to access the price date
of any chart (currency and timeframe) regardless of the chart that hosts the expert advisor. But they are
not enough to write our expert advisor.
What's the Bid/Ask price we are going to use with OrderSend to open the order? We can't use the
function Bid() and Ask() because they are returning the current currency Bid and Ask price.
Our magic function today is MarketInfo() function:
MarketInfo() function:
Syntax:
double MarketInfo( string symbol, int type)

Description:
The MarketInfo() function is the function you need to retrieve various market data of the given currency,
for example: the current Bid price of the currency, the current Ask price of the currency, the Swap value
of Buy or Selling the currency and the number of digits the currency uses.
Note: A part of this data are stored in the Predefined Variables but this data is exclusive for the current
chart and MarketInfo() function give us more data about the currency.

This function can return the following important data:




MQL4 programs protection!
Hi folks!
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
163 of 258 6/14/2006 5:36 PM
I'm very fanatic for sharing MQL4 codes/ideas, however I've got a lot of requests asking me about MQL4
indicator/experts protection. I think it's not evil to use your programming talent to get some money if you
don't want to share (it's a choice anyway).
Without protecting your MQL4 code it will be waste of time to try to commercialize your programs, that's
why I'm writing this article.

Source code verse binary:

Just as a review and to emphasis that we are talking about how to protect the .ex4 files read the next
section:
There are two kinds of files that you use with MetaTrader; the program files and the executable files:

The program files are normal text files but have one of these extensions: .mq4 and .mgh.
These files are the source code of the programs wrote in MQL4 programming language; source code
means they could be opened for viewing or editing in MetaEditor.
The executable files are binary files (you can't open them for viewing or editing) and has the extension
.ex4.
These files are the result of compiling the .mq4 files using MetaEditor, and these are the files that you can
load them in MetaTrader and use them.
Compiling is an operation taken by a special program (called a compiler) to convert the program from
text (readable) format to the binary format which the computer can understand (computers think in
binary).
This is the general definition of compiling. Compiling in our case is converting the mq4 files to ex4 for file
using MetaEditor program. We are doing this by opening the mq4 files in MetaEditor then pressing F5
hot key. MetaEditor will compile (convert) the file to ex4 format and keeping the mq4 file untouched
MetaEditor will place the generated ex4 file at the same path as the mq4 file. We compile the mq4 files
because the MetaTrader can't load any files except ex4 files.
The source code of MQL4 programs can't be protect because it's in text format and when you distribute it
you intend to give the receiver the access to the source code of the program.
The executable version of the program is the only version that you can protect it. You protect it by write
the protection code in the source code of the program then compile it to the ex4 format then distribute it to
the user.
Kinds (ideas) of the protection:

We are going to discuss some ideas of MQL4 programs protection, maybe they are not the best but they
are the common ideas, we are going to write some code to apply these ideas:
Password protection code:
This the widely used method to protect softwares in general and can be used to protect MQL4 programs.
When the user buy your program you send him the program with a password and he can use the program
without the password.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
164 of 258 6/14/2006 5:36 PM
This is a simple code to apply password protection method:
int start()
{
extern string Please_Enter_Password = "0";
// your code here....
int start()
{
if (password != "viva metatrader") //change to the password you give the user!
{
Alert ("Wrong password!");
return (0);
}
// your code here....
}

In the code above the password is "viva metatrader" which is hard coded in the MQL4 file. You have to
compile the program after adding this piece of code and send it to the user with the password.

Trial period protection:
If you want to give the user of the program a try-before-buy program you can limit the usage of your
program by limited period of time and after this period the program will not work.
Use the code below to limit your program for period of time.
int start()
{
string expire_date = "2006.31.06"; //<-- hard coded datetime
datetime e_d = StrToTime(expire_date);

if (CurTime() >= e_d)
{
Alert ("The trial version has been expired!");
return(0);
}
// your normal code!
return(0);
}

Limited account number protection:
In this method of protection you will ask the user to give you his account number and you write the
following code to prevent the program to work with another accounts:
int start()
{

int hard_accnt = 11111; //<-- type the user account here before compiling
int accnt = AccountNumber();

if (accnt != hard_accnt)
{
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
165 of 258 6/14/2006 5:36 PM
Alert ("You can not use this account (" + DoubleToStr(accnt,0) + ") with this program!");
return(0);
}
// your normal code!
return(0);
}

Limited account type protection:
In this method of protection you will allow the user to use the program in demo mode only and prevent
him to use the program in live trading. It's not strong protection because the user can host the program in
another instance of MetaTrader that runs in demo mode and trade manually in the real account instance.
int start()
{

bool demo_account = IsDemo();

if (!demo_account)
{
Alert ("You can not use the program with a real account!");
return(0);
}
// your normal code!
return(0);
}

DLL protection:
This is the method of choice, write your own C++ DLL and let the MQL4 program export it.
In C++ you can do anything, for instance you can make the DLL communicated to your server (if you
have one) enabling the user to download a certificate or even update the MQL4 program.
I hope I can to write all purposes MQL4 protection DLL. I'll let you know when I write one.
Hope you enjoyed the article!







Object functions
Hi folks,
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
166 of 258 6/14/2006 5:36 PM
You use objects (Line studies, shapes, arrows and texts) as a visual aid to facilitate the analysis of chart.
Drawing objects in MetaTrader manually is an easy task, you just have to choose the object you want to
draw from the Insert menu or from the Line Studies toolbar (Figures 1 and 2).
Then you can modify/delete the created object by selecting the object on the chart and right click it then
choose the operation you want from the context menu (Figure 3).


Figure 1 - Insert menu

Figure 2 - Line studies toolbar

Figure 3 - Objects context menu

Today we are going to know how to programicaly work with objects in MQL4. We are going to study the
Object functions which enable us to handle everything you can manually do with the objects and the
things you can't do manually.
For example if you have hundred of objects on the chart and you want to delete them, it's a hard task to
do it manually but in MQL4 it's a very easy task (as you'll see later)
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
167 of 258 6/14/2006 5:36 PM
Let's see the Object functions:

ObjectCreate:

Syntax:
bool ObjectCreate(string name, int type, int window, datetime time1, double price1, datetime time2=0,
double price2=0, datetime time3=0, double price3=0)

Description:
The ObjectCreate function creates a new object with the specified name and type, in the specified window
and coordinates. The function returns true if the object successfully created otherwise it returns false. To
know the exact error use GetLastError() function.
Object name:
The name of the object is the name you see in the Objects list window (Figure 4) and this name works as a
handle for the object which you can use later to work with this object (For example to delete it or move it)
so it must be unique.
Figure 4 - Objects list window
Windows:
You can draw the object on the chart main window (The main window which show the price date) or on
any of the chart sub-windows , you use the index of the window with the ObjectCreate function and you
have to remember that:
1- The index of the chart main window is 0.
2- The chart sub-windows indexes start from 1 up to the number of the windows minus 1.
3- To get the number of window use the function WindowsTotal( ).
4- To find the index of a specific window by its indicator name use the function WindowFind( string
name).
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
168 of 258 6/14/2006 5:36 PM
5- The index of the window must be less than the total of windows (retuned by WindowsTotal( ) function).

Coordinates:

You can use up to 3 coordinates for the object drawing depending on the type of the object, for example
the Vertical line object uses only 1 coordinate, the Trend line object uses 2 coordinates and the Channel
object use 3 coordinates.
The X (vertical) coordinate of the object is the time on the chart and the Y (horizontal) coordinate of the
object is the price on the chart (Figure 5).
The first coordinate pairs (X and Y) are required parameters even if an object like the OBJ_LABEL will
ignore them, while the second and third coordinates pairs are optional and you have to use them only with
the object which use 2 or 3 coordinates.


Figure 5 - Coordinates
Parameters:
string name:
The string name of the object which you will use it later as a reference of object.
int type:
The type of the object you want to draw, you pass to the ObjectCreate function the integer representation
of the object or the constant name of this integer, this is the table of the object integers representation and
their constant names:
Constant Value Description
OBJ_vL!NE 0 vertical line. Uses time part of first coordinate.
OBJ_HL!NE 1 Horizontal line. Uses price part of first coordinate.
OBJ_TREND 2 Trend line. Uses 2 coordinates.
OBJ_TRENDBYANGLE 3 Trend by angle. Uses 1 coordinate. To set angle of line use ObjectSet() function.
OBJ_REGRESS!ON + Regression. Uses time parts of first two coordinates.
OBJ_CHANNEL 5 Channel. Uses 3 coordinates.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
169 of 258 6/14/2006 5:36 PM
OBJ_STDDEvCHANNEL 6 Standard deviation channel. Uses time parts of first two coordinates.
OBJ_GANNL!NE / Gann line. Uses 2 coordinate, but price part of second coordinate ignored.
OBJ_GANNFAN 8 Gann fan. Uses 2 coordinate, but price part of second coordinate ignored.
OBJ_GANNGR!D 9 Gann grid. Uses 2 coordinate, but price part of second coordinate ignored.
OBJ_F!BO 10 Fibonacci retracement. Uses 2 coordinates.
OBJ_F!BOT!NES 11 Fibonacci time zones. Uses 2 coordinates.
OBJ_F!BOFAN 12 Fibonacci fan. Uses 2 coordinates.
OBJ_F!BOARC 13 Fibonacci arcs. Uses 2 coordinates.
OBJ_EXPANS!ON 1+ Fibonacci expansions. Uses 3 coordinates.
OBJ_F!BOCHANNEL 15 Fibonacci channel. Uses 3 coordinates.
OBJ_RECTANGLE 16 Rectangle. Uses 2 coordinates.
OBJ_TR!ANGLE 1/ Triangle. Uses 3 coordinates.
OBJ_ELL!PSE 18 Ellipse. Uses 2 coordinates.
OBJ_P!TCHFORK 19 Andrews pitchfork. Uses 3 coordinates.
OBJ_CYCLES 20 Cycles. Uses 2 coordinates.
OBJ_TEXT 21 Text. Uses 1 coordinate.
OBJ_ARROW 22 Arrows. Uses 1 coordinate.
OBJ_LABEL 23 Text label. Uses 1 coordinate in pixels.

int window:
The index of the window you want to draw the object on, the chart main window has the index 0 and the
sub chart starts from 1 to the total of the window - 1.
datetime time1:
The first vertical coordinate of the object. This parameter is required and you can set it to 0 if the object
will not use the vertical coordinate.
This parameter is a datetime type (because the vertical coordinate of the chart is the time coordinate).
double price1:
The first horizontal coordinate of the object. This parameter is required and you can set it to 0 if the
object will not use the horizontal coordinate.
This parameter is a double type (because the horizontal coordinate of the chart is the price coordinate).
You have to note which currency pair you are going to draw on its chart because the prices ranges differs
from currency to currency.
datetime time2:
The second vertical coordinate of the object. It's an optional parameter which you can use it if your object
uses 2 coordinates.
double price2:
The second horizontal coordinate of the object. It's an optional parameter which you can use it if your
object uses 2 coordinates.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
170 of 258 6/14/2006 5:36 PM
datetime time3:
The third vertical coordinate of the object. It's an optional parameter which you can use it if your object
uses 3 coordinates.
double price3:
The third horizontal coordinate of the object. It's an optional parameter which you can use it if your
object uses 3 coordinates.

Example:
// new text object
if(!ObjectCreate("text_object", OBJ_TEXT, 0, D'2004.02.20 12:30', 1.0045))
{
Print("error: can't create text_object! code #",GetLastError());
return(0);
}
// new label object
if(!ObjectCreate("label_object", OBJ_LABEL, 0, 0, 0))
{
Print("error: can't create label_object! code #",GetLastError());
return(0);
}
ObjectSet("label_object", OBJPROP_XDISTANCE, 200);
ObjectSet("label_object", OBJPROP_YDISTANCE, 100);

ObjectDelete:

Syntax:
bool ObjectDelete(string name)

Description:
The ObjectDelete function deletes the object by its name (you have to provide the exact name of the
object). If the object successfully deleted the function will return true, otherwise it will return false. Use
GetLastError() function to get more details about the error.

Parameters:
string name:
The string name of the object you want to delete.

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
171 of 258 6/14/2006 5:36 PM
Example:
ObjectDelete("text_object");

ObjectDescription:

Syntax:
string ObjectDescription(string name)
Description:
The ObjectDescription function returns the description of the object (Figure 6).
For the objects OBJ_TEXT and OBJ_LABEL which has no description the returned value is the text
drawn by these objects (Figure 7).

Figure 6- Object description

Figure 7
Parameters:
string name:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
172 of 258 6/14/2006 5:36 PM
The string name of the object you want to get its description.
Example:
Print(ObjectDescription("Text 44465"));

ObjectFind:

Syntax:
int ObjectFind(string name)
Description:
The ObjectFind function searches all the drawn objects for the specified object name and returns the index
of the window that host the object if found and returns -1 if the object not found. The chart main window
is 0 index and the first chart sub-window is 1 then 2 etc.
Parameters:
string name:
The string name of the object you want to search for.
Example:
if(ObjectFind("line_object2")!=win_idx) return(0);

ObjectGet:

Syntax:
double ObjectGet(string name, int index)
Description:
The ObjectGet function returns the value of the specified object property of the given index.
For example to get the first vertical (time) of the object use ObjectGet(object_name, 0).
Parameters:
string name:
The string name of the object you want to get one of its proporties.
int index:
The property index which can be one of these values:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
173 of 258 6/14/2006 5:36 PM
Constant Value Type Description
OBJPROP_T!NE1 0 datetime Datetime value to set/get first coordinate time part.
OBJPROP_PR!CE1 1 double Double value to set/get first coordinate price part.
OBJPROP_T!NE2 2 datetime Datetime value to set/get second coordinate time part.
OBJPROP_PR!CE2 3 double Double value to set/get second coordinate price part.
OBJPROP_T!NE3 + datetime Datetime value to set/get third coordinate time part.
OBJPROP_PR!CE3 5 double Double value to set/get third coordinate price part.
OBJPROP_COLOR 6 color Color value to set/get object color.
OBJPROP_STYLE / int value is one of STYLE_SOL!D, STYLE_DASH, STYLE_DOT,
STYLE_DASHDOT, STYLE_DASHDOTDOT constants to set/get object
line style.
OBJPROP_W!DTH 8 int !nteger value to set/get object line width. Can be from 1 to 5.
OBJPROP_BACK 9 bool Boolean value to set/get background drawing flag for object.
OBJPROP_RAY 10 bool Boolean value to set/get ray flag of object.
OBJPROP_ELL!PSE 11 bool Boolean value to set/get ellipse flag for fibo arcs.
OBJPROP_SCALE 12 double Double value to set/get scale object property.
OBJPROP_ANGLE 13 double Double value to set/get angle object property in degrees.
OBJPROP_ARROWCODE 1+ int !nteger value or arrow enumeration to set/get arrow code object
property.
OBJPROP_T!NEFRANES 15 int value can be one or combination (bitwise addition) of object visibility
constants to set/get timeframe object property.
OBJPROP_DEv!AT!ON 16 double Double value to set/get deviation property for Standard deviation
objects.
OBJPROP_FONTS!ZE 100 int !nteger value to set/get font size for text objects.
OBJPROP_CORNER 101 int !nteger value to set/get anchor corner property for label objects.
Nust be from 0-3.
OBJPROP_XD!STANCE 102 int !nteger value to set/get anchor X distance object property in pixels.
OBJPROP_YD!STANCE 103 int !nteger value is to set/get anchor Y distance object property in
pixels.
OBJPROP_F!BOLEvELS 200 int !nteger value to set/get Fibonacci object level count. Can be from 0
to 32.
OBJPROP_LEvELCOLOR 201 color Color value to set/get object level line color.
OBJPROP_LEvELSTYLE 202 int value is one of STYLE_SOL!D, STYLE_DASH, STYLE_DOT,
STYLE_DASHDOT, STYLE_DASHDOTDOT constants to set/get object
level line style.
OBJPROP_LEvELW!DTH 203 int !nteger value to set/get object level line width. Can be from 1 to 5.
OBJPROP_F!RSTLEvEL+n 210+n int Fibonacci object level index, where n is level index to set/get. Can be
from 0 to 31.

Example:
color oldColor=ObjectGet("hline12", OBJPROP_COLOR);
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
174 of 258 6/14/2006 5:36 PM

ObjectGetFiboDescription:

Syntax:
string ObjectGetFiboDescription(string name, int index)
Description:
The ObjectGetFiboDescription function returns the description of the given Fibonacci object level.
For example in Figure 8 the description of the second line from bottom (its index is 0) is "23.6".
The index of Fibonacci object levels start from bottom upward and you can use up to 32 levels.


Figure 8
Parameters:
string name:
The string name of the Fibonacci object you want to get its level description.
int index:
The index of the level (line) you want to get its level description.
Example:
Print(ObjectGetFiboDescription("Fibo 2638", 1));

ObjectGetShiftByValue:

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
175 of 258 6/14/2006 5:36 PM
Syntax:
int ObjectGetShiftByValue(string name, double value)
Description:
The ObjectGetShiftByValue function returns the index of the bar (shifted from the current - 0 upward) for
the given price of the given object. This price is calculated with the first and second coordinates of the
object (using liner equation).
Foe example in figure 9 the bar index for the price 1.2156 of the Trendline object is the bar 11.


Figure 9
Parameters:
string name:
The string name of the object you want to get the bar index for one of its prices (values)
double value:
The price value of the object.
Example:
Print(ObjectGetShiftByValue("Trendline 5879", 1.2156));

In the next lesson we are going to continue with the remaining Object Function and we are going to make
a simple MQL program to apply what we learnt about the objects programming.
Hope you find the lesson helpful one and hope to see your comments!
Coders Guru!

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
176 of 258 6/14/2006 5:36 PM
Object Functions - Part 2
Hi folks,
Today we are going to continue with the remaining of Object Functions and we have a simple MQL
program to apply some of what we have learnt about drawing objects programicaly.
Let's see what left of the object functions:

ObjectMove:

Syntax:
bool ObjectMove(string name, int point, datetime time1, double price1)
Description:
The ObjectMove function changes the specified coordinate of the object to new x and y coordinate.
Any object has up to 3 coordinates and they are indexed 0, 1 and 2. You specify the coordinate you want to
change with its index (point parameter) then set new x and y values for the new coordinate (time1 and
time2).
The function returns true if it successfully had changed the coordinate and false otherwise.
Note: If you have a 2 or 3 coordinates object and want to change the 2 or 3 coordinates, you have to use
ObjectMove function 2 or 3 times for every coordinate.
Parameters:
string name:
The string name of the object you want to change its coordinate.
int point:
Coordinate index (0, 1, 2) you want to change it.
datetime time1:
The first vertical coordinate of the object. This parameter is a datetime type (because the vertical
coordinate of the chart is the time coordinate).
double price1:
The first horizontal coordinate of the object. This parameter is a double type (because the horizontal
coordinate of the chart is the price coordinate).

Note: You have to note which currency pair you are going to draw on its chart because the prices ranges
differs from currency to currency.
Example:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
177 of 258 6/14/2006 5:36 PM
ObjectMove("MyTrend", 1, D'2005.02.25 12:30', 1.2345);

ObjectName:

Syntax:
string ObjectName(int index)
Description:
The ObjectName function returns the object name for the given index from the object list. To check the
error use GetLastError() function.
Parameters:
int index:
The index of the object you want to get its name.
Note: The index must be equal to 0 or greater, and be less than the total of the objects count returned by
ObjectsTotal() function.
Example:
int obj_total=ObjectsTotal();
string name;
for(int i=0;i<obj_total;i++)
{
name=ObjectName(i);
Print(i,"Object name is " + name);
}

OrderSend - Type of orders!
Hi folks,
"OK, now I have a brain pain! I just spent the morning scanning thru the MQL4 and MetaTrader help
file pages to try and track down if I missed anything."
Could you please answer me only one question:
When I open a Buy order using OrderSend function, Should I use the Ask or the Bid price? What about
the Stop loss is it going below or above the Ask or the Bid price? What about the Take profit?
When I open a Sell order using OrderSend function, Should I use the Ask or the Bid price? What about
the Stop loss is it going below or above the Ask or the Bid price? What about the Take profit?
What about BUYLIMIT, BUYSTOP, SELLLIMIT and SELLSTOP orders?
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
178 of 258 6/14/2006 5:36 PM
Is that the only one question? Well here’s the answer!

OP_BUY
Ask
Ask-StopLoss
Ask+TakeProfit
You Buy at the current Ask price of the currency!
You set the StopLoss Below (-) the Ask price!
You set the TakeProfit Above (+) the Ask price!
Example:
OrderSend(Symbol(),OP_BUY,Lots,Ask,slippage,
Ask-StopLoss*Point,Ask+TakeProfit*Point,”comment”,0,0,Green);

OP_SELL
Bid
Bid+StopLoss
Bid-TakeProfit
You Sell at the current Bid price of the currency!
You set the StopLoss Above (+) the Bid price!
You set the TakeProfit Below (-) the Bid price!
Example:
OrderSend(Symbol(),OP_SELL,Lots,Bid,slippage,
Bid+StopLoss*Point,Bid-TakeProfit*Point, ”comment”,0,0,Green);

OP_BUYLIMIT
Ask-Level
Ask-Level-StopLoss
Ask-Level +TakeProfit
You Buy at future price level Below the current Ask price of the currency!
You set the StopLoss Below (-) the Ask - the level price!
You set the TakeProfit Above (+) the Ask - the level price!
Example:
OrderSend(Symbol(),OP_BUYLIMIT,Lots,Ask-Level*Point,slippage,
(Ask-Level*Point)-StopLoss*Point,
( Ask-Level*Point)+TakeProfit*Point,”comment”,0,0,Green);

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
179 of 258 6/14/2006 5:36 PM
OP_BUYSTOP

Ask+Level
Ask+Level -StopLoss
Ask+Level +TakeProfit
You Buy at future price level Above the current Ask price of the currency!
You set the StopLoss Below (-) the Ask + the level price!
You set the TakeProfit Above (+) the Ask + the level price!
Example:
OrderSend(Symbol(),OP_BUYSTOP,Lots,Ask+Level*Point,slippage,
(Ask+Level*Point)-StopLoss*Point,
( Ask+Level*Point)+TakeProfit*Point,”comment”,0,0,Green);

OP_SELLLIMIT

Bid+Level
Bid +Level +StopLoss
Bid+Level –TakeProfit
You Sell at future price level Above the current Bid price of the currency!
You set the StopLoss Above (+) the Bid + the level price!
You set the TakeProfit Below (-) the Bid + the level price!
Example:
OrderSend(Symbol(),OP_SELLLIMIT,Lots,Bid+Level*Point,slippage,
(Bid+Level*Point)+StopLoss*Point,
(Bid +Level*Point)-TakeProfit*Point,”comment”,0,0,Green);

OP_SELLSTOP
Bid-Level
Bid -Level +StopLoss
Bid-Level-TakeProfit
You Sell at future price level Below the current Bid price of the currency!
You set the StopLoss Above (+) the Bid + the level price!
You set the TakeProfit Below (-) the Bid - the level price!
Example:
OrderSend(Symbol(),OP_SELLSTOP,Lots,Bid-Level*Point,slippage,
(Bid-Level*Point)+StopLoss*Point,
(Bid -Level*Point)-TakeProfit*Point,”comment”,0,0,Green);
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
180 of 258 6/14/2006 5:36 PM
Predefined variables
Hi folks,

Today we are going to talk about a very important topic, the Predefined variables.
I still considering them functions (I'm going to tell you why later) but I'll use Predefined variables as
MetaQuotes has mentioned them.
What are the Predefined variables?
The Predefined variables are set of the most important variables which MetaTrader set continuously for
every loaded chart. They are price related variables that reflect the current price data the chart had got.
These is the list of the predefined variables:
Ask, Bid, Bars, Close, Open, High, Low, Time, Digits, Point and Volume
I'm calling them functions because:
Ask, Bid, Bars, Close, Open, High, Low, Time, Digits, Point and Volume are functions Although
MetaQuotes called them predefined variables.
Variable means "a space in memory and data type you specify", while function means "do something and
return some value". For example Bars collects and returns the number of the bars in chart. So, is it a
variable?
Another example will proof for you that they are not variables:
If you type and compile this line of code:
Bars=1;
You will get this error:
'Bars' - unexpected token
That’s because they are not variables hence you can’t assign a value to them.
Anyway, it doesn't matter what should you call them, the really matter is how to use them!
Let's study the Predefined variables set:

StringConcatenate:

Syntax:
double Ask
Description:
The Ask function return the last known Ask price (the sell price) for the current symbol. To be sure it
reflects the actual market price you have to use the RefreshRates() function.
Note: To get the Ask price for a
Parameters:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
181 of 258 6/14/2006 5:36 PM
Example:







Questions - Close price
How can i get the close, low, high price of current bar? When I use Close[0], iClose(Symbol(), 0, 0) to get
close price of current bar, thess two values are always the same as Open[0](when running tester tool of
MetaTrader, right now I'm running MIG Trade Station, demo account) ? The same for low and high
prices? Please tell me how can i figure out it. Many thanks for reading!

---------- REPLY -----------------
Hi there!
Close[0] returns the close price of the current bar (The same is true for the High[0] return the high price
of the current bar, Low[0] returns the low price of the current bar and Open[0] returns the open price of
the current bar)
iClose function is very like Close function but it can return the close price for another symbol and
timframe. If you used it like this:
iClose(NULL,0,0)
it will equal to Close[0]. (The same is true for the iHigh, iLow and iOpen functions).
Coders Guru
String functions
Hi folks,
Our set of functions today are the String Functions. They are the MQL4 functions we need to handle the
string variables!
Let's give the string data type an overview first!

string data type:

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
182 of 258 6/14/2006 5:36 PM
The string data type is an array of characters enclosed in double quote (").
This array of characters is an array which holds one character after another, starting at index 0. After the
last character of data, a NULL character is placed in the next array location. It does not matter if there
are unused array locations after that.
A NULL character is a special character (represented by the ASCII code 0) used to mark the end of this
type of string.
See figure 1 for a simple representation of the string constant “hello” in the characters array.
Figure 1 – Characters array
MQL4 limits the size of the string variable to 255 characters and any character above 255 characters will
generate this error: (too long string (255 characters maximum)).
We use the keyword string to create a string variable.
For example:
string str1 = "Hello world!, with you coders guru”;
string str2 = "Copyright © 2005, \"Forex-tsd forum\"."; //Notice the use of (") character.
string str3 = "1234567890";

Now let's study the MQL4 functions concerned about the Strings:

StringConcatenate:

Syntax:
string StringConcatenate( ... )
Description:
The StringConcatenate function take the set of parameters passed to it and glue them together and returns
them as a string.
Note: (...) means that you can pass to this function any kind of data type and any number of parameters
separated by comma.
You can pass to this function any kind of data type except the arrays and any number of parameters
separated by comma very like the Print(), Alert() and Comment() functions.
If you want to pass a double data type to this function the number of digits will be used are 4 digits if you
want to change this number you have to use the function DoubleToStr().
The bool, color and datatime passed to function will be printed in their numeric presentation. , if you want
to print them in string format use the string name of the bool or the color value and for the datetime use
the function TimeToStr().
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
183 of 258 6/14/2006 5:36 PM
Note: You can use the + operator to add string to another string for example "coders" + "guru" will
produce "codersguru", however MetaTrader saying that StringConcatenate() function works faster
gluing strings together.
Parameters:
This function takes any number of parameters:
...
Any values, separated by commas.
Example:
string text;
text=StringConcatenate("Account free margin is ", AccountFreeMargin(), "Current time is ",
TimeToStr(CurTime()));
// slow text="Account free margin is " + AccountFreeMargin() + "Current time is " + TimeToStr(CurTime())
Print(text);


StringFind:

Syntax:
int StringFind( string text, string matched_text, int start=0)
Description:
The StringFind function search for substring (part of the given string for example "gur" is substring from
the string "codersguru") in a given string, if the function find the substring it returns its position, if the
function didn't find the substring it returns -1.
Parameters:
This function takes two parameters:
string text
The string you want to search in it for the substring.
string matched_text
The substring you want to find it in the string.
int start=0
The index of the starting position for the search. the first character in the string has the index 0 then 1
then 2 etc.
The default value is 0 which means to search from the start of the string.
Example:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
184 of 258 6/14/2006 5:36 PM
string text="The quick brown dog jumps over the lazy fox";
int index=StringFind(text, "dog jumps", 0);
if(index!=16)
Print("oops!");


StringGetChar:

Syntax:
int StringGetChar( string text, int pos)
Description:
The StringGetChar function returns the character in a given position from a given string. it return it as
character code (the ASCII code of the character).
Parameters:
This function takes two parameters:
string text
The string you want to get the character from.
int pos
The position of the character you want to get, don't forget that the string array starts with 0.
Example:
int char_code=StringGetChar("abcdefgh", 3);
// char code 'c' is 99

StringLen:

Syntax:
int StringLen( string text)
Description:
The StringLen function returns how many character (the length) of the given string.
Parameters:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
185 of 258 6/14/2006 5:36 PM
This function takes only one parameter:
string text
The string you want to get its length..
Example:
string str="some text";
if(StringLen(str)<5) return(0);


StringSetChar:

Syntax:
string StringSetChar( string text, int pos, int value)
Description:
The StringSetChar function change one character of the given string in a given position to another
character and returns the new string.
Parameters:
This function takes three parameters:
string text
The string you want change a character in it.
int pos
The position of the character you want to change.
int value
The new character you want to set it.
Example:
string str="abcdefgh";
string str1=StringSetChar(str, 3, 'D');
// str1 is "abcDefgh"


StringSubstr:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
186 of 258 6/14/2006 5:36 PM

Syntax:
string StringSubstr( string text, int start, int count=EMPTY)
Description:
The StringSubstr function extracts the string from given position to a given count (ex: "codersguru" the
position is 3 and the count is 2 then the extracted string is "de"). The function returns the extracted string
if any or it returns EMPTY string.
Parameters:
This function takes three parameters:
string text
The string you want to extract from it.
int start
Where to start your extracting.
int count=EMPTY
The count of character you want to extract. The default value is EMPTY.
Example:
string text="The quick brown dog jumps over the lazy fox";
string substr=StringSubstr(text, 4, 5);
// subtracted string is "quick" word

Timeseries access functions - Part 1
Hi folks,
I've got a lot of messages asking me "How to deal with currency pairs which are different than the current
chart currency (The chart that hosts the expert advisor)? For example, how to make an expert advisor
that can open Buy position of GBPUSD or USDCHF while the expert advisor is hosted on EURUSD
chart?" Good question, Huh?
To reply these related questions we have to start with studding the Timeseries Access functions.
The Timeseries Access functions are a set of functions that enables us to access the price date of any chart
(currency and timeframe) regardless of the chart that hosts the expert advisor.
Let's give these functions a brief look:



Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
187 of 258 6/14/2006 5:36 PM
iBars

Syntax:
int iBars( string symbol, int timeframe)

Description:
The iBars function returns the number of Bars of the specified chart, you specify the chart by the symbol
name and the timeframe.
Note: If the chart of the symbol and timeframe you are trying to get its price data is not opened,
MetaTrader will try to connect to the server to retrieve the request price data. In this case and with the all
of the Timeseries access functions you have to check the the last was the error # 4066 -
ERR_HISTORY_WILL_UPDATED (which means the requested data is under updating) to be sure that
the price data is up-to-date. And retry your request for the price data.
Note: If you want to get the number of bars of the current chart (symbol and timeframe) use Bars
function.

Parameters:
string symbol:
The symbol (currency pair) of the chart you want to get its bars number.
Use NULL if you want to use current symbol.
int timeframe:
The timeframe (in integers, ex: 1,5,30,60 etc) of the chart you want to get its bars number.
Use 0 if you want to use current timeframe.
Note: You can use the integer representation of the timeframe (period in minutes) or you can use the
timeframes constants:

PER!OD_N1 1 1 minute.
PER!OD_N5 5 5 minutes.
PER!OD_N15 15 15 minutes.
PER!OD_N30 30 30 minutes.
PER!OD_H1 60 1 hour.
PER!OD_H+ 2+0 + hour.
PER!OD_D1 1++0 Daily.
PER!OD_W1 10080 Weekly.
PER!OD_NN1 +3200 Nonthly.
0 (zero) 0 Timeframe used on the chart.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
188 of 258 6/14/2006 5:36 PM

Example:
Print("Bar count on the 'EUROUSD' symbol with PERIOD_H1 is",iBars("EUROUSD",PERIOD_H1));

iBarShift:

Syntax:
int iBarShift( string symbol, int timeframe, datetime time, bool exact=false)

Description:
The iBarShift function takes the open time of the bar for a specified symbol and timeframe and searches
for this bar and returns it if found otherwise it returns -1.
If you want the iBarShift function to return the nearest bar to the given open time set the exact parameter
to true.

Parameters:
string symbol:
The symbol (currency pair) of the chart you want to get its bars number.
Use NULL if you want to use current symbol.
int timeframe:
The timeframe (in integers, ex: 1,5,30,60 etc) of the chart you want to get its bars number.
Use 0 if you want to use current timeframe.
datetime time:
The open time of the bar you want to search for
bool exact:
The search mode, use exact =false (default) and and the function will return -1 if the open time not found.
And use exact =true and the function will return the nearest bar to the given open time.

Example:
datetime some_time=D'2004.03.21 12:00';
int shift=iBarShift("EUROUSD",PERIOD_M1,some_time);
Print("shift of bar with open time ",TimeToStr(some_time)," is ",shift);

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
189 of 258 6/14/2006 5:36 PM
iClose:

Syntax:
double iClose( string symbol, int timeframe, int shift)

Description:
The iClose function returns the Close price for the given bar (the shift parameter is the bar number) of the
given symbol and timeframe. The function returns 0 if the history data not loaded.
Note: It's very important (and always error's source) to know that the current bar is 0 and the previous
bar is 1 etc.
Note: If you want to get the Close price (of a bar) of the current chart (symbol and timeframe) use
Close[int shift] function.

Parameters:
string symbol:
The symbol (currency pair) of the chart you want to get its bars number.
Use NULL if you want to use current symbol.
int timeframe:
The timeframe (in integers, ex: 1,5,30,60 etc) of the chart you want to get its bars number.
Use 0 if you want to use current timeframe.
int shift:
The index of the bar you want to get its Close price.

Example:
Print("Current Close price for USDCHF H1: ",iClose("USDCHF",PERIOD_H1,i));


iHigh:

Syntax:
double iHigh( string symbol, int timeframe, int shift)
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
190 of 258 6/14/2006 5:36 PM

Description:
The iHigh function returns the High price for the given bar (the shift parameter is the bar number) of the
given symbol and timeframe. The function returns 0 if the history data not loaded.
Note: If you want to get the High price (of a bar) of the current chart (symbol and timeframe) use High[int
shift] function.

Parameters:
string symbol:
The symbol (currency pair) of the chart you want to get its bars number.
Use NULL if you want to use current symbol.
int timeframe:
The timeframe (in integers, ex: 1,5,30,60 etc) of the chart you want to get its bars number.
Use 0 if you want to use current timeframe.
int shift:
The index of the bar you want to get its High price.

Example:
Print("Current High price for USDCHF H1: ",iHigh("USDCHF",PERIOD_H1,i));


iLow:

Syntax:
double iLow( string symbol, int timeframe, int shift)

Description:
The iLow function returns the Low price for the given bar (the shift parameter is the bar number) of the
given symbol and timeframe. The function returns 0 if the history data not loaded.
Note: If you want to get the Low price (of a bar) of the current chart (symbol and timeframe) use Low[int
shift] function.

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
191 of 258 6/14/2006 5:36 PM
Parameters:
string symbol:
The symbol (currency pair) of the chart you want to get its bars number.
Use NULL if you want to use current symbol.
int timeframe:
The timeframe (in integers, ex: 1,5,30,60 etc) of the chart you want to get its bars number.
Use 0 if you want to use current timeframe.
int shift:
The index of the bar you want to get its Low price.
Example:
Print("Current Low price for USDCHF H1: ",iLow("USDCHF",PERIOD_H1,i));


iOpen:

Syntax:
double iOpen( string symbol, int timeframe, int shift)

Description:
The iOpen function returns the Open price for the given bar (the shift parameter is the bar number) of the
given symbol and timeframe. The function returns 0 if the history data not loaded.
Note: If you want to get the Open price (of a bar) of the current chart (symbol and timeframe) use
Open[int shift] function.

Parameters:
string symbol:
The symbol (currency pair) of the chart you want to get its bars number.
Use NULL if you want to use current symbol.
int timeframe:
The timeframe (in integers, ex: 1,5,30,60 etc) of the chart you want to get its bars number.
Use 0 if you want to use current timeframe.
int shift:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
192 of 258 6/14/2006 5:36 PM
The index of the bar you want to get its Open price.

Example:
Print("Current Open price for USDCHF H1: ",iOpen("USDCHF",PERIOD_H1,i));


iTime:

Syntax:
datetime iTime( string symbol, int timeframe, int shift)

Description:
The iTime function returns the Open Time of the given bar (the shift parameter is the bar number) of the
given symbol and timeframe.
Note: If you want to get the bar Open Time (of a bar) of the current chart (symbol and timeframe) use
Time[int shift] function.

Parameters:
string symbol:
The symbol (currency pair) of the chart you want to get its bars number.
Use NULL if you want to use current symbol.
int timeframe:
The timeframe (in integers, ex: 1,5,30,60 etc) of the chart you want to get its bars number.
Use 0 if you want to use current timeframe.
int shift:
The index of the bar you want to get its Open Time.

Example:
Print("The Open Time of the current bar for USDCHF H1: ",iTime("USDCHF",PERIOD_H1,i));

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
193 of 258 6/14/2006 5:36 PM

iVolume:

Syntax:
double iVolume( string symbol, int timeframe, int shift)

Description:
The iVolume function returns the Tick Volume value of the given bar (the shift parameter is the bar
number) of the given symbol and timeframe.
Note: Volume is simply the number of shares (or contracts) traded during a specified time frame (e.g.,
hour, day, week, month, etc).
Note: In MQL if you want to check if the tick is the first tick of the new bar you can check Volume[0] it
will be 0 if it's the first tickof the new bar. Example:
//---- go trading only for first tiks of new bar
if(Volume[0]>1) return;
Note: If you want to get the Tick Volume value (of a bar) of the current chart (symbol and timeframe) use
Volume[int shift] function.

Parameters:
string symbol:
The symbol (currency pair) of the chart you want to get its bars number.
Use NULL if you want to use current symbol.
int timeframe:
The timeframe (in integers, ex: 1,5,30,60 etc) of the chart you want to get its bars number.
Use 0 if you want to use current timeframe.
int shift:
The index of the bar you want to get its Tick Volume value.

Example:
Print("Current Tick Volume for USDCHF H1: ",iVolume("USDCHF",PERIOD_H1,i));


Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
194 of 258 6/14/2006 5:36 PM
Highest:

Syntax:
int Highest( string symbol, int timeframe, int type, int count=WHOLE_ARRAY, int start=0)

Description:
The Highest function calculate the Highest value of the specified type (Close price, Open price, High price
etc) for a specified bars of the given symbol and timeframe.
You use the type parameter to determine the type of the values to be calculated and the parameters count
and start determine the bars to be calculated.

Parameters:
string symbol:
The symbol (currency pair) of the chart you want to get its bars number.
Use NULL if you want to use current symbol.
int timeframe:
The timeframe (in integers, ex: 1,5,30,60 etc) of the chart you want to get its bars number.
Use 0 if you want to use current timeframe.
int type:
The type of values (Series array) to be calculated, it can be one of these types:
Constant Value Description
MODE_OPEN 0 Open price.
MODE_LOW 1 Low price.
MODE_HIGH 2 High price.
MODE_CLOSE 3 Close price.
MODE_VOLUME 4 Volume.
MODE_TIME 5 Bar Open time.

int count:
How many bars you want to calculate its Highest value, use this parameter with start parameter to
determine the range of bars to be calculated. The default value is WHOLE_ARRAY which means all the
bars (values in the series array).
int start:
The bar to start the calculation from, the default value is 0 which means to start from the current bar.

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
195 of 258 6/14/2006 5:36 PM
Example:
double val;
// calculating the highest value in the range from 5 element to 25 element
// indicator charts symbol and indicator charts time frame
val=High[Highest(NULL,0,MODE_HIGH,20,4)];


Lowest:

Syntax:
int Lowest( string symbol, int timeframe, int type, int count=WHOLE_ARRAY, int start=0)

Description:
The Lowest function calculate the Lowest value of the specified type (Close price, Open price, High price
etc) for a specified bars of the given symbol and timeframe.
You use the type parameter to determine the type of the values to be calculated and the parameters count
and start determine the bars to be calculated.

Parameters:
string symbol:
The symbol (currency pair) of the chart you want to get its bars number.
Use NULL if you want to use current symbol.
int timeframe:
The timeframe (in integers, ex: 1,5,30,60 etc) of the chart you want to get its bars number.
Use 0 if you want to use current timeframe.
int type:
The type of values (Series array) to be calculated.
int count:
How many bars you want to calculate its Highest value, use this parameter with start parameter to
determine the range of bars to be calculated. The default value is WHOLE_ARRAY which means all the
bars (values in the series array).
int start:
The bar to start the calculation from, the default value is 0 which means to start from the current bar.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
196 of 258 6/14/2006 5:36 PM
Example:
double val=Low[Lowest(NULL,0,MODE_LOW,10,10)];

Now we have the tools to access the price data of the other charts, the question is: Is this enough to write
our expert advisor that deals with other currency pairs? No!
In the coming lesson we are going to know the most important function needed to write this kind of expert
advisors; the MarketInfo() function.
I hope you find it a useful lesson!
Windows functions
Hi folks,
We are going to study today a set of functions that responsible of handling the chart windows. These
functions are infrequently used (expect WindowsTotal(), WindowFind() and ScreenShot functions) but as
a MQL4 programmer you have to know them.
These are the Windows functions set:

BarsPerWindow:

Syntax:
int BarsPerWindow( )
Description:
The BarsPerWindow function returns the number of bars visible for the user on the chart.
Note: Resizing the chart window or changing the chart period changes this number.
Parameters:
The function doesn't take any parameters.
Example:
// work with visible bars.
int bars_count=BarsPerWindow();
int bar=FirstVisibleBar();
for(int i=0; i<bars_count; i++,bar--)
{
// ...
}
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
197 of 258 6/14/2006 5:36 PM
caption=FirstVisibleBar()
type=int
Function returns index of the first visible bar.
// work with visible bars.
int bars_count=BarsPerWindow();
int bar=FirstVisibleBar();
for(int i=0; i<bars_count; i++,bar--)
{
// ...
}

PriceOnDropped:

Syntax:
double PriceOnDropped( )
Description:
The PriceOnDropped function returns the price of the currency of the chart from the point you dragged
and release the expert advisor or the script at. When you click the expert advisor or the script in the
navigator window and hold the left button mouse then drag it and release the left mouse buttons at any
point on the chart; the PriceOnDropped returns the price at this point.
This function works only with the expert advisors and script and doesn't work with the custom indicators.
Parameters:
The function doesn't take any parameters.
Example:
double drop_price=PriceOnDropped();
datetime drop_time=TimeOnDropped();
//---- may be undefined (zero)
if(drop_time>0)
{
ObjectCreate("Dropped price line", OBJ_HLINE, 0, drop_price);
ObjectCreate("Dropped time line", OBJ_VLINE, 0, drop_time);
}

TimeOnDropped:

Syntax:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
198 of 258 6/14/2006 5:36 PM
datetime TimeOnDropped( )
Description:
The TimeOnDropped function returns the time of on the chart where you dragged and release the expert
advisor or the script at. This function too works only with the expert advisors and script and doesn't work
with the custom indicators.
Parameters:
The function doesn't take any parameters.
Example:
double drop_price=PriceOnDropped();
datetime drop_time=TimeOnDropped();
//---- may be undefined (zero)
if(drop_time>0)
{
ObjectCreate("Dropped price line", OBJ_HLINE, 0, drop_price);
ObjectCreate("Dropped time line", OBJ_VLINE, 0, drop_time);
}

ScreenShot:

Syntax:
bool ScreenShot( string filename, int size_x, int size_y, int start_bar=-1, int chart_scale=-1, int
chart_mode=-1)
Description:
The ScreenShot function save a screen shot of the current chart. It saves the screen shot as GIF file in one
of two folder:
If you used the function in the live mode it'll save the screen shot in terminal_dir\experts\files and its
subdirectories. If you used the function in the testing mode it'll save the screen shot in
terminal_dir\tester\files and its subdirectories.
The function returns True if it successfully saved the screen shot and false if it failed.
Parameters:
The function takes 6 parameters.
string filename:
The file name that the function will save the screen shot to. You can combine the file name with a
subdirectory to tell the function where to save the file.
int size_x:
The width of the screen shot.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
199 of 258 6/14/2006 5:36 PM
int size_y:
The height of the screen shot.
int start_bar=-1:
The index of the first bar you want to include in your screen shot. 0 means the first visible bar on the
chart. The default vaule is -1 which means the end-of-chart screen shot will be taken.
int chart_scale=-1:
The scale (Zoom In and Zoom Out) of the chart screen shot that will be taken. It ranges from 0 to 5. The
default value is -1 which means the function will use the current scale of the chart.
int chart_mode=-1
The mode of the chart screen shot that will be taken. it can be one of these values:
CHART_BAR (0)
CHART_CANDLE (1)
CHART_LINE (2)
The default value is -1 which means the function will use the chart mode.

Example:
int lasterror=0;
//---- tester has closed one or more trades
if(IsTesting() && ExtTradesCounter<TradesTotal())
{
//---- make screenshot for further checking
if(!ScreenShot("shots\\tester"+ExtShotsCounter+".gif",640,480))
lasterror=GetLastError();
else ExtShotsCounter++;
ExtTradesCounter=TradesTotal();
}

WindowFind:

Syntax:
int WindowFind(string name)
Description:
The WindowFind function searches the chart sub windows for the indicator short name passed to it and
returns the window index if found and -1 otherwise!
Note: The indicators name can be set using the function IndicatorShortName().
Note: If the indicator search for his name in the init() function using WindowFind() function it always
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
200 of 258 6/14/2006 5:36 PM
returns -1.
Parameters:
The function takes only one parameter.
string name:
The name of the indicator short name you want to search for and return its window index.
Example:
int win_idx=WindowFind("MACD(12,26,9)");

WindowHandle:

Syntax:
int WindowHandle(string symbol, int timeframe)
Description:
The WindowHandle function searches all the opened chart for the symbol (currency pairs) and timeframe
passed to it and returns the window handle of the chart window if found and -1 otherwise.
Parameters:
The function takes two parameters:
string symbol:
The symbol name you want to search for and return its window index.
int timeframe:
The timeframe you want to search for and return its window index.
Note: The chart window you are searching must have the symbol name and the timeframe to return the
window handle. if the one of the two conditions is found and other not found the return value is -1.

Example:
int win_handle=WindowHandle("EURUSD",PERIOD_H1);
if(win_handle!=0)
Print("Window with EURUSD,H1 detected. Rates array will be copied immediately.");

WindowIsVisible:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
201 of 258 6/14/2006 5:36 PM

Syntax:
bool WindowIsVisible(int index)
Description:
The WindowIsVisible function returns true if the chart sub-window index passed to it is visible to the user
and false otherwise.
Parameters:
The function takes only one parameter:
int index:
The index of the chart sub-window you want to check its visibility.
Example:
int maywin=WindowFind("MyMACD");
if(maywin>-1 && WindowIsVisible(maywin)==true)
Print("window of MyMACD is visible");
else
Print("window of MyMACD not found or is not visible");

WindowOnDropped:

Syntax:
int WindowOnDropped()
Description:
The WindowOnDropped function returns the index of the window you dragged and released the expert
advisor, indicator or the script on.
Parameters:
The function doesn't take any parameters.
Example:
if(WindowOnDropped()!=0)
{
Print("Indicator 'MyIndicator' must be applied to main chart window!");
return(false);
}

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
202 of 258 6/14/2006 5:36 PM
WindowsTotal:

Syntax:
int WindowsTotal()
Description:
The WindowsTotal function returns the count of windows (sub-windows and main window) on the chart.
Parameters:
The function doesn't take any parameters.
Example:
Print("Windows count = ", WindowsTotal());

WindowXOnDropped:

Syntax:
int WindowXOnDropped()
Description:
The WindowXOnDropped function returns the x-axis coordinate in pixels of the point you dragged and
released the expert advisor, indicator or the script on.
Parameters:
The function doesn't take any parameters.
Example:
Print("Expert dropped point x=",WindowXOnDropped()," y=",WindowYOnDropped());

WindowYOnDropped:

Syntax:
int WindowYOnDropped()
Description:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
203 of 258 6/14/2006 5:36 PM
The WindowYOnDropped function returns the Y-axis coordinate in pixels of the point you dragged and
released the expert advisor, indicator or the script on.
Parameters:
The function doesn't take any parameters.
Example:
Print("Expert dropped point x=",WindowXOnDropped()," y=",WindowYOnDropped());
Lesson 17 - Your First Script
It was a long path for you to reach this lesson, Congratulations!
You learnt the basics of MQL4 language then you wrote your first indicator and your first
expert advisor.
I hope you enjoyed the journey and interested to continue the road with me.
Today we will create our first script which will simply set the stoploss and takeprofit
values for all the already opened orders on the chart.
It’s useful if you are lazy to set manually your stoploss and takeprofit values from the
Modify or Delete Orders window for every order.
What are we waiting for? Let’s script!
What’s a MQL4 script?
The scrip is a program you run once to execute an action and it will be removed
immediately after the execution.
Unlike the expert advisors which will be called every time in a new tick arrival, the script
will be executed only for once.
And unlike the indicators which have the ability to draw lines on the chart, the script has
no access to indicator functions.
In short the script is an expert advisor which you can run only once.
Let's create our first script!
Wizards again!
With the help of the New Program wizard we will create the backbone of our scrip.
Bring the New Program wizard by choosing New from File menu or by clicking
CTRL+N hot keys (Figure 1).
We are going to create a script, so choose Scrip program in the wizard and click next.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
204 of 258 6/14/2006 5:36 PM
That will bring the second step wizard (Figure 2).
Fill the Name, Author and Link fields with what you see in the figure 2 (or whatever you
want). Then click finish.
Figure 1 – New Program wizard
Figure 2 – Step 2
By clicking Finish button the wizard will write some code for you and left the places to
write your own code, this is the code we have got from the wizard.
//+------------------------------------------------------------------+
//| My_First_Script.mq4 |
//| Copyright Coders Guru |
//| http://www.forex-tsd.com |
//+------------------------------------------------------------------+
#property copyright "Copyright Coders Guru"
#property link "http://www.forex-tsd.com"
//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
int start()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
Note: As you can easily notice from the above code that the wizard hasn’t added the init()
and deinit() functions and only added the start() function.
That’s because it’s rare to find a script needs to execute code in the program initialization
and de-initialization because the start() function itself will be executed for once.
But that’s not mean you can’t add init() and deinit() functions in a script. You can add
them if you want.
Now, we have to add our code to make our script more useful.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
205 of 258 6/14/2006 5:36 PM
This is the code we have added to the above wizard’s generated code (our added code
marked by the bold font):
//+------------------------------------------------------------------+
//| My_First_Script.mq4 |
//| Copyright Coders Guru |
//| http://www.forex-tsd.com |
//+------------------------------------------------------------------+
#property copyright "Copyright Coders Guru"
#property link "http://www.forex-tsd.com"
#property show_inputs
#include <stdlib.mqh>
extern double TakeProfit=250;
extern double StopLoss=35;
//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
int start()
{
//----
int total,cnt,err;
total = OrdersTotal();
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()==OP_BUY) // long position is opened
{
OrderModify(OrderTicket(),OrderOpenPrice(),
Bid-Point*StopLoss,Bid+Point*TakeProfit,0,Green);
err=GetLastError();
Print("error(",err,"): ",ErrorDescription(err));
Sleep(1000);
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
206 of 258 6/14/2006 5:36 PM
}
if(OrderType()==OP_SELL) // short position is opened
{
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*StopLoss,
Ask-Point*TakeProfit,0,Red);
err=GetLastError();
Print("error(",err,"): ",ErrorDescription(err));
Sleep(1000);
}
}
//----
return(0);
}
//+------------------------------------------------------------------+
Let’s crack the code line by line as we used to do.
//+------------------------------------------------------------------+
//| My_First_Script.mq4 |
//| Copyright Coders Guru |
//| http://www.forex-tsd.com |
//+------------------------------------------------------------------+
#property copyright "Copyright Coders Guru"
#property link "http://www.forex-tsd.com"
Here the wizard has written the comment block which contains the script name we have
been chosen, the copyright and link we have been typed.
Then two directive properties have been added according to the date we have entered,
these are the copyright and link properties.
#property show_inputs
We have added the show_inputs directive property to our script.
Without this property the script will not accept inputs from the user therefore will not
prompt an input window to the user as the one showed in figure 3.
In our script the user can set the TakeProfit and StopLoss values from the inputs window
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
207 of 258 6/14/2006 5:36 PM
or he can leave the default values we have set in our code.
Note: If you intend to write a script which doesn’t need inputs from the user, it’s
preferred to remove show_inputs directive property.
Figure 3 – Script Input window
#include <stdlib.mqh>
Later in our code we are going to use the function ErrorDescription which returns a
string description of the passed error number. This function is included in the file
“stdlib.mqh”, so we have included this file to our program using the include directive.
That means the content of the “stdlib.mqh” is a part of our code now and we can freely
use the ErrorDescription function.
extern double TakeProfit=250;
extern double StopLoss=35;
Here we have declared two extern variables which the user can set them from the script
inputs window (Figure 2) or he can leave the default values.
We will use these variables in our start() function to set the takeprofit and stoploss values
of all the already opened order.
int start()
{
//----
int total,cnt,err;
total = OrdersTotal();
....
}
We are inside the start() function which will be called only one time when you attach the
script to you chart.
We have declared three integer variables using a single line declaration method.
Then we assigned the return value of the OrdersTotal function to the total variable.
As you remember OrdersTotal function returns the number of opened and pending
orders.
for(cnt=0;cnt<total;cnt++)
{
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
208 of 258 6/14/2006 5:36 PM
....
}
Here we enter a for loop starts from 0 and ends to the total of already opened and pending
orders. We will use the loop variable cnt with the OrderSelect function to select every
opened order by its index. In every cycle of the loop we increase the cnt variable by 1.
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
We have selected the order by its index using the function OrderSelect and the loop
variable cnt.
We have to use the OrderSelect function before calling OrderType in the coming line.
(Please review Appendix 2 – Trading functions).
if(OrderType()==OP_BUY) // long position is opened
{
....
}
The OrderType function returns the type of selected order that will be one of:
OP_BUY, OP_SELL, OP_BUYLIMIT, OP_BUYSTOP, OP_SELLLIMIT or
OP_SELLSTOP.
In the above if block we have checked the type of order to find is it a Buy order or not.
If it's a Buy order, the code inside the block will be executed.
OrderModify(OrderTicket(),OrderOpenPrice(),
Bid-Point*StopLoss,Bid+Point*TakeProfit,0,Green);
It's a Buy order type, so we want to modify the values of stoploss and takeprofit to the
values of StopLoss and TakeProfit variables the user has been set.
We use the OrderModify function which modifies the properties of a specific opened
order or pending order with the new values you pass to the function.
We used these parameters:
ticket: We've got the current selected order ticket with OrderTicket function.
price: We've got the open price of the current selected order with OrderOpenPrice
function.
stoploss: Here we have set the stoploss value of the current selected order to the value of
the subtraction of the current bid price and the StopLoss value the user has been set.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
209 of 258 6/14/2006 5:36 PM
takeprofit: Here we have set the takeprofit value of the current selected order to the
value of the addition of the current bid price and the TakeProfit value the user has been
set.
expiration: We haven't set an expiration date to our order, so we used 0.
arrow_color: We have set the color of the arrow to Green.
err=GetLastError();
Print("error(",err,"): ",ErrorDescription(err));
Sleep(1000);
We have assigned the returned value of the GetLastError function to the err variable.
The GetLastError returns the number of the last error occurred after an operation
(OrderModify in our case).
But we want to print not only the error number but the description of the error, so we
have used the ErrorDescription function to get the string description of the error number
and we have used the print function to output this message to the expert log.
Then we have used the Sleep function to give the terminal and our script the time to take
their breath for one second (1000 milliseconds).
Note: Sleep function suspends the execution of the program for a specified interval, this
interval passed to the function in milliseconds.
if(OrderType()==OP_SELL) // short position is opened
{
....
}
In the above if block we have checked the type of order to find is it a Sell order or not.
If it's a Sell order, the code inside the block will be executed.
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*StopLoss,
Ask-Point*TakeProfit,0,Red);
It's a Sell order type, so we want to modify the values of stoploss and takeprofit to the
values of StopLoss and TakeProfit variables the user has been set.
We use the OrderModify function again with these parameters:
ticket: We've got the current selected order ticket with OrderTicket function.
price: We've got the open price of the current selected order with OrderOpenPrice
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
210 of 258 6/14/2006 5:36 PM
function.
stoploss: Here we have set the stoploss value of the current selected order to the value of
the addition of the current ask price and the StopLoss value the user has been set.
takeprofit: Here we have set the takeprofit value of the current selected order to the
value of the subtraction of the current ask price and the TakeProfit value the user has
been set.
expiration: We haven't set an expiration date to our order, so we used 0.
arrow_color: We have set the color of the arrow to Red.
err=GetLastError();
Print("error(",err,"): ",ErrorDescription(err));
Sleep(1000);
The same as above explained lines.
return(0);
It's the time to terminate our script by using return function.
Let's compile our script by pressing F5 hot key, as soon as you compile the script it will
appear in the navigator window in the script category (Figure 4)
Note: The wizard has created the file "My_First_Script.mq4" and has placed it in the
"experts\scripts" folder for us.
You have to put all of you scripts in this folder and compile them before using them in
the terminal.
Figure 4 – Execute your script
To execute the script simply point it with your mouse and double click it, or click the left
mouse button and a menu as showed in figure 4 will appear then choose Execute On
Chart.
The inputs window (Figure 3) will appear and you can set new values for StopLoss and
TakeProfit or leave the default values.
I hope you enjoyed the lesson and found the first script we have created a useful one.
I welcome very much your questions and suggestions.
Coders’ Guru
Lesson 18 - Working with templates
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
211 of 258 6/14/2006 5:36 PM
We have created our first indicator, expert advisor and script in the previous lessons.
Every time we decide to create our program whatever the kind of the program (indicator,
expert or script) we have to write it from scratch.
This is a useful thing for MQL4 beginners, but it’s time consuming for advanced
programmers.
That’s why MQL4 has the feature of creating templates based programs.
Today we will create an indicator based on MACD template shipped with MetaTrader.
So, let’s template!
What are the MQL4 templates?
The MQL4 templates are text files contain instructions (commands) for MetaEditor to
generate a new program based on these instructions. MetaEditor will read these
instructions and use them to generate the appropriated lines of code.
We use the templates to duplicate the frequently used codes and save our coding time.
By using the templates you can create indicators, experts and scripts based on your
favorite indicators, experts and scripts and save the time of writing the code from scratch.
Today we are going to duplicate the MACD indicator and we will not add to it anything
that’s because we are not in the indicator creating lesson but we are in the template
lessons.
Inside look:
We are going to give the template file a look before digging into our creation of our first
template based indicator.
Note: The template files are stored in the experts\templates path.
And have the ".mqt" file extension.
Here’s the content of the “MACD.mqt” template which we will use it today creating our
template based indicator:
Note: We have indented some of content and colored them to make it clearer but you can
give the original file an inside look.
<expert>
type=INDICATOR_ADVISOR
separate_window=1
used_buffers=2
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
212 of 258 6/14/2006 5:36 PM
<param>
type=int
name=FastEMA
value=12
</param>
<param>
type=int
name=SlowEMA
value=26
</param>
<param>
type=int
name=SignalSMA
value=9
</param>
<ind>
color=Silver
type=DRAW_HISTOGRAM
</ind>
<ind>
color=Red
</ind>
</expert>
#header#
#property copyright "#copyright#"
#property link "#link#"
#indicator_properties#
#extern_variables#
#mapping_buffers#
//---- indicator buffers
double ExtSilverBuffer[];
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
213 of 258 6/14/2006 5:36 PM
double ExtRedBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
#buffers_used#;
//---- drawing settings
#indicators_init#
//----
SetIndexDrawBegin(1,SignalSMA);
IndicatorDigits(5);
//---- indicator buffers mapping
SetIndexBuffer(0, ExtSilverBuffer);
SetIndexBuffer(1, ExtRedBuffer);
//---- name for DataWindow and indicator subwindow label
IndicatorShortName("MACD("+FastEMA+","+SlowEMA+","+SignalSMA+")");
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence |
//+------------------------------------------------------------------+
int start()
{
int limit;
int counted_bars=IndicatorCounted();
//---- check for possible errors
if(counted_bars<0) return(-1);
//---- last counted bar will be recounted
if(counted_bars>0) counted_bars--;
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
214 of 258 6/14/2006 5:36 PM
limit=Bars-counted_bars;
//---- macd counted in the 1-st buffer
for(int i=0; i<limit; i++)
ExtSilverBuffer[i]=iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i)-
iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i);
//---- signal line counted in the 2-nd buffer
for(i=0; i<limit; i++)
ExtRedBuffer[i]=iMAOnArray(ExtSilverBuffer,Bars,SignalSMA,0,MODE_SMA,i)
;
//---- done
return(0);
}
//+------------------------------------------------------------------+
If you give the above code a look you can notice that the most of the code is a normal
MQL4 code with two new kinds of different code.
The first kind of code (Ex: <expert> and <param>) looks like the HTML tags; these are
the template tags.
And the second kind of code (Ex: #header# and #link#) looks like the MQL4 directives;
these are the template commands:
MQL4 template tags:
The template file starts with tags very like the Html and XML tags.
There is a start tag and a closing tag. The closing tag uses a slash after the opening
bracket. For example <expert> is the start tag and </expert> is the closing tag.
The text between the brackets is called an element. For example:
type=int
name=FastEMA
value=12
There are three tags in MQL4 template:
expert tag:
This is main tag and the other two tags are belonging to it.
In this tag we write the type of program, the indicator chart window, the number of buffer
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
215 of 258 6/14/2006 5:36 PM
used, the bottom border for the chart and the top border for the chart of the indicator.
These are the elements used in the expert tag:
type: The type of program. Possible values are EXPERT_ADVISOR,
INDICATOR_ADVISOR, SCRIPT_ADVISOR.
separate_window: The chart window type.
used_buffers: The number of used buffers.
ind_minimum: The fixed bottom border of indicator window.
ind_maximum: The fixed top border of indicator window.
param tag:
We use this tag to create external variables. For every variable we use a param tag.
These are the elements used in the param tag:
type: The data type of the variable.
name: The variable name.
value: The default value of the variable.
ind tag:
We use this tag to set the parameters of every indicator (drawing line) we use in our
program.
These are the elements used in the ind tag:
type: The indicator drawing shape style. Possible values are DRAW_LINE,
DRAW_HISTOGRAM, DRAW_SECTION, DRAW_ARROW.
color: The indicator color.
arrow: The character for displaying the DRAW_ARROW indicator. "Wingdings" font is
used for displaying the characters.
MQL4 template commands:
They are lines of code starts and ends with # symbol. And these lines of code will be
replaced with the corresponded lines with code in the generation process.
Note: MetaEditor reads these lines and replace them in the place they found and generate
the MQ4 file.
These are the template commands:
#header#: This line will be replaced with the program header block (comments with file
name, author name and the company name).
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
216 of 258 6/14/2006 5:36 PM
#copyright#: This line will be replaced with your company name.
#link#: This line will be replaced with your website link.
#indicator_properties#: This line will be replaced with the properties of the indicator.
#extern_variables#: This line will be replaced with external variables used in your
program with their types and default values.
#buffers_used#: This line will be replaced with the number of buffer used if any.
#indicators_init#: This line will be replaced with the initialization of the indicators
(using the function SetIndexStyle).
Creating our MACD template based indicator.
Now, let’s create our template based indicator by hitting our File menu and choose New
or clicking CTRL+N. That will bring the New Program wizard (Figure 1).
This time we will choose “Create from template” option and from the drop list we will
choose “Indicator – MACD”.
Figure 1 – New program wizard
Then we will hit Next button which brings the second step wizard (Figure 2).
MetaEditor has filled the fields with Author name and the Link (reading them from the
windows registry) and left the Name field blank which we typed in it
"MACD_From_Template"
In the Parameters list the MetaEditor has red our template file and filled the list with the
external variables and its default values.
Figure 2 – Second step wizard
Hitting Next button will bring the third step wizard (figure 3) which contains the indicator
parameters.
As you guessed MetaEditor has red our template file and generated the values of the
indicator properties.
Now click the finish button and you will see the magic of the templates.
Figure 3 – Third step wizard
What have we got?
The wizards have generated a new indicator for us based on MACD template.
Code ready to compile, ready to run:
//+------------------------------------------------------------------+
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
217 of 258 6/14/2006 5:36 PM
//| MACD_From_Template.mq4 |
//| Copyright Coders Guru |
//| http://www.forex-tsd.com |
//+------------------------------------------------------------------+
#property copyright "Copyright Coders Guru"
#property link "http://www.forex-tsd.com"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Silver
#property indicator_color2 Red
//---- input parameters
extern int FastEMA=12;
extern int SlowEMA=26;
extern int SignalSMA=9;
//---- buffers
//---- indicator buffers
double ExtSilverBuffer[];
double ExtRedBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- drawing settings
SetIndexStyle(0,DRAW_HISTOGRAM);
SetIndexStyle(1,DRAW_LINE);
//----
SetIndexDrawBegin(1,SignalSMA);
IndicatorDigits(5);
//---- indicator buffers mapping
SetIndexBuffer(0, ExtSilverBuffer);
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
218 of 258 6/14/2006 5:36 PM
SetIndexBuffer(1, ExtRedBuffer);
//---- name for DataWindow and indicator subwindow label
IndicatorShortName("MACD("+FastEMA+","+SlowEMA+","+SignalSMA+")");
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence |
//+------------------------------------------------------------------+
int start()
{
int limit;
int counted_bars=IndicatorCounted();
//---- check for possible errors
if(counted_bars<0) return(-1);
//---- last counted bar will be recounted
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
//---- macd counted in the 1-st buffer
for(int i=0; i<limit; i++)
ExtSilverBuffer[i]=iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i)-
iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i);
//---- signal line counted in the 2-nd buffer
for(i=0; i<limit; i++)
ExtRedBuffer[i]=iMAOnArray(ExtSilverBuffer,Bars,SignalSMA,0,MODE_SMA,i)
;
//---- done
return(0);
}
//+------------------------------------------------------------------+
Compile the code and enjoy your new MACD indicator.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
219 of 258 6/14/2006 5:36 PM
I welcome very much your questions and suggestions.
Coders’ Guru
Appendix 1 - BARS
MQL4 COURSE
By Coders’ guru
(Appendix 1)
Bars
----------------------------
I have got a lot of questions about the mystery of the bars count.
I’m going to describe everything about Bars in this appendix.
What’s a BAR?
The bar is the dawning unit on the chart which you can specify by choosing the period of
the timeframe.
For example: The 30 minutes timeframe will draw a bar every 30 minutes.
MetaTrader (and other platforms) uses the values of to high, low, open and close prices to
draw the bar start and end boundaries. (Figure 1)


Figure 1 - Bar chart dawning
How the bars indexed in MQL4?
MQL4 indexes the bars from 0 (for the current bar) then 1, 2, 3 etc to the count of the bars.
So, if you want to work with the current bar you use the index 0.
And the index of the previous bar (of the current bar) is 1.
And the index 100 is the bar 100 in the history (100 bars ago).
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
220 of 258 6/14/2006 5:36 PM
And the index of last bar is the count of all bars on chart.
MQL4 BARS count functions:
In MQL4 there is a variety of functions working with the count of bars:
int Bars
This function returns the number of the bars of the current chart.
Note that, changing the timeframe will change this count.
int iBars( string symbol, int timeframe)
This function returns the number of bars on the specified currency pairs symbol and timeframe.
Assume you are working on 30M timeframe and you want to get the count of Bars on 1H
time frame, you use this line:
iBars(NULL, PERIOD_H1));
Note: If you used it like this:
iBars(NULL,0));
It returns the same number as Bars function.
int IndicatorCounted()
When you are writing your indicator, you know now how to get the number of bars.
You use this number in your calculation and line dawning.
But it’s useful to know if you have counted the bar before or it’s the first time you count it.
That’s because, if you have counted it before you don’t want to count it again and want to
work only with the new bars.
In this case you use the function IndicatorCounted(), which returns the number of bars
have been counted by your indicator.
At the first run of your indicator this count will be zero, that’s because your indicator
didn’t count any bars yet.
Afterwards, it will equal to the count of Bars – 1. That’s because the last bar not counted
yet (Figure 2).

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
221 of 258 6/14/2006 5:36 PM

Figure 2 – Program output
Let’s write a small program to show you what’s going on.
//+------------------------------------------------------------------+
//| Bars.mq4 |
//| Codersguru |
//| http://www.forex-tsd.com |
//+------------------------------------------------------------------+
#property copyright "Codersguru"
#property link "http://www.forex-tsd.com"
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
//----
return(1);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
222 of 258 6/14/2006 5:36 PM
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
//----
Alert( "counted_bars = " , IndicatorCounted()); //The count of bars
have been counted
Alert( "Bars = " , Bars); //The count of the bars on the chart
Alert( "iBars = " , iBars(NULL,0)); //the same as Bars function
Alert( "First Bar Open = " , Open[Bars-1]); //Open price of the
first bar
Alert( "Last Bar Open = " , Open[0]); //Open price of the last bar
(current bar)
//----
return(0);
}
//+------------------------------------------------------------------+
Note: This program produces the image you have seen in figure 2
I hope the Bars count is clear now.
I welcome very much the questions and the suggestions._
See you
Coders’ Guru

Appendix 2 - Trading Functions
MQL4 COURSE
By Coders’ guru
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
223 of 258 6/14/2006 5:36 PM
(Appendix 2)
Trading Functions
--------------------
In this appendix you will find the description of the 25 MQL4 trading functions.
I decided to write this appendix before writing the third part of “Your First Expert Advisor” lesson
because you have to know these important functions before cracking the remaining of the code.
OrderSend:
Syntax:

int OrderSend( string symbol, int cmd, double volume, double price, int slippage, double stoploss, double
takeprofit, string comment=NULL, int magic=0, datetime expiration=0, color arrow_color=CLR_NONE)

Description:

The OrderSend function used to open a sell/buy order or to set a pending order.
It returns the ticket number of the order if succeeded and -1 in failure.
Use GetLastError function to get more details about the error.
Note: The ticket number is a unique number returned by OrderSend function which you can use later as a
reference of the opened or pending order (for example you can use the ticket number with OrderClose
function to close that specific order).
Note: GetLastError function returns a predefined number of the last error occurred after an operation
(for example when you call GetLastError after OrderSend operation you will get the error number
occurred while executing OrderSend).
Calling GetLastError will reset the last error number to 0.

You can find a full list of MQL4 errors numbers in stderror.mqh file.
And you can get the error description for a specific error number by using ErrorDescription function
which defined at stdlib.mqh file.
Parameters:
This function takes 11 parameters:
string symbol:
The symbol name of the currency pair you trading (Ex: EURUSD and USDJPY).
Note: Use Symbol() function to get currently used symbol and OrderSymbol function to get the symbol of
current selected order.
int cmd:
An integer number indicates the type of the operation you want to take; it can be one of these values:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
224 of 258 6/14/2006 5:36 PM
Constant Value Description
OP_BUY 0 Buying position.
OP_SELL 1 Selling position.
OP_BUYLIMIT 2 Buy limit pending position.
OP_SELLLIMIT 3 Sell limit pending position.
OP_BUYSTOP 4 Buy stop pending position.
OP_SELLSTOP 5 Sell stop pending position.
Note: You can use the integer representation of the value or the constant name.
For example:
OrderSend(Symbol(),0,…) is equal to OrderSend(Symbol(),OP_BUY,…) .
But it's recommended to use the constant name to make your code clearer.
double volume:
The number of lots you want to trade.
double price:
The price you want to open the order at.
Use the functions Bid and Ask to get the current bid or ask price.
int slippage:
The slippage value you assign to the order.
Note: slippage is the difference between estimated transaction costs and the amount actually paid.
slippage is usually attributed to a change in the spread. (Investopedia.com).
double stoploss:
The price you want to close the order at in the case of losing.
double takeprofit:
The price you want to close the order at in the case of making profit.
string comment:
The comment string you want to assign to your order (Figure 1).
The default value is NULL which means there's no comment assigned to the order.
Note: Default value of a parameter means you can leave (don’t write) it out, and MQL4 will use a
predefined value for this parameter.
For example we can write OrderSend function with or without comment parameter like this:
OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Ask-25*Point,Ask+25*Point,"My order comment",12345,0,Green);
Or like this:
OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Ask-25*Point,Ask+25*Point,12345,0,Green);
int magic:
The magic number you assign to the order.
Note: Magic number is a number you assign to your order(s) as a reference enables you to distinguish
between the different orders. For example the orders you have opened by your expert advisor and the
orders have opened manually by the user.

Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
225 of 258 6/14/2006 5:36 PM

Figure 1 - Comment

datetime expiration:
The time you want your pending order to expire at.
The default time is 0 which means there's no exportation.

Note: The time here is the server time not your local time, to get the current server time use CurTime
function and to get the local time use LocalTime function.

color arrow_color:
The color of opening arrow (Figure 2), the default value is CLR_NONE which means there's no arrow will
be drawn on the chart.

Figure 2 – Arrows color

Example:

int ticket;
if(iRSI(NULL,0,14,PRICE_CLOSE,0)<25)
{
ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,Ask-25*Point,Ask+25*Point,"My order #2",16384,0,Green);
if(ticket<0)
{
Print("OrderSend failed with error #",GetLastError());
return(0);
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
226 of 258 6/14/2006 5:36 PM
}
}

Arrays
Hi folks,
The subject of Arrays in any programming language is a big mystery to any new comer. MQL4 is not
exception.
Today we are going to reveal the mystery behind the Array in general and in MQL4 in particular.
What are the Arrays?
In our life we usually group similar objects into units, in the programming we also need to group together
the data items of the same type. We use Arrays to do this task.
Arrays are very like the list tables, you group the items in the table and access them by number of the row,
but rows in the Arrays called Indexes.
The rows in the Arrays start from 0 not from 1 like anything else. So the index of the first item in an array
is 0 and the index of the second item is 1 and the index of the third item is 2 etc.
Note: In some of programming language the Arrays index starts from 1, it called 1 indexed arrays, but in
MQL4 and the most of programming languages the Arrays index start from 0 (0 indexed Arrays).
Figure 1 – one dimension array of 10 integers
Array dimensions:
In the most of cases the Array has one dimension like the description above, but in some case the Array
has more than one dimension (In MQL4 the maximum dimension is four dimensions).
Multi-dimensional arrays are very like multi-column tables, where the first column is the first dimension
of the Array and the second column is the second dimension of the Array etc.
Creating an Array:
The arrays must to be declared (like the variables) before using it in the code. Declaring an array means
creating it by giving it a name (identifier), type and size.
In MQL4 we are creating the Arrays like this:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
227 of 258 6/14/2006 5:36 PM
int myarray[50];
In the code above we declared one-dimensional array.
int keyword indicates that the array is an array of integers.
myarray is the name of the array (identifier).
[] telling the compiler that we are declaring an array not an integer variable.
50 is the size of the array.
We have now a one-dimensional array of 50 integers
double myarray[5][40];
The line above is the way to declare two-dimensional of seven arrays each of them consisting of 40
doubles.
Initializing the Array:
Initializing an array (or a variable) means setting its value at the same declaration line.
Look at this code which initializes one- dimensional array of 6 integers:
int myarray [6] = {1,4,9,16,25,36};
The list of array element have to be enclosed between curly braces {} then be assigned to the array.
The number of elements has to be equal to the array size. If you provided number of elements lesser than
the array size the last elements of arrays will be filled with zeros. And if you provided number greater
than the array size, MQL4 will ignore these elements and set the array to the first elements.
For example the following code will fill the last element of the array with zero because the size of array is 6
elements and we provided it 5 elements:
int myarray [6] = {1,4,9,16,25}; //5 elements only for 6 size array.
Alert ("myarray[0] " + myarray[0]);
Alert ("myarray[1] " +myarray[1]);
Alert ("myarray[2] " +myarray[2]);
Alert ("myarray[3] " +myarray[3]);
Alert ("myarray[4] " +myarray[4]);
Alert ("myarray[5] " +myarray[5]);
The code above will produce will fill the array with the elements you see in figure 2.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
228 of 258 6/14/2006 5:36 PM
Figure 2 - assigned elements lesser than array size
int myarray [6] = {1,4,9,16,25,36,55}; //7 elements for 6 size array.
Alert ("myarray[0] " + myarray[0]);
Alert ("myarray[1] " +myarray[1]);
Alert ("myarray[2] " +myarray[2]);
Alert ("myarray[3] " +myarray[3]);
Alert ("myarray[4] " +myarray[4]);
Alert ("myarray[5] " +myarray[5]);
The code above will produce will fill the array with the elements you see in figure 3.
Figure 3 - assigned elements greater than array size.
Assigning elements to an Array:
You’ve created an array and want to fill it with elements. You can do that in two ways, the first way we
have explained above is initializing the array with the elements in the declaration line.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
229 of 258 6/14/2006 5:36 PM
If you didn’t initialize the array yet, don’t worry. You can assign the elements of the array in two ways:
1- Assigning the elements of the array using the element index.
In this method you assign element by element using the index of the element, The first element is 0 index
and the second is 1 index etc.
Look at this code:
int myarray [6] ;
myarray[0] = 1;
myarray[1] = 4;
myarray[2] = 9;
myarray[3] = 16;
myarray[4] = 25;
myarray[5] = 36;

Alert ("myarray[0] " + myarray[0]);
Alert ("myarray[1] " + myarray[1]);
Alert ("myarray[2] " + myarray[2]);
Alert ("myarray[3] " + myarray[3]);
Alert ("myarray[4] " + myarray[4]);
Alert ("myarray[5] " + myarray[5]);

In the code above we declared an array without initializing it. Then we set each element with a line of
code.
2- Assigning the element of one filled array to an empty array:
In this method you have already filled array and you assign it to another array. The assigned to array
must be the same size of the assigned from one.
Look at this code:
int mysourcearray [6] = {1,4,9,16,25,36};
int mycopyarray[6] ;
mycopyarray[0] = mysourcearray [0];
mycopyarray[1] = mysourcearray [1];
mycopyarray[2] = mysourcearray [2];
mycopyarray[3] = mysourcearray [3];
mycopyarray[4] = mysourcearray [4];
mycopyarray[5] = mysourcearray [5];

Alert ("mycopyarray[0] " + mycopyarray[0]);
Alert ("mycopyarray[1] " + mycopyarray[1]);
Alert ("mycopyarray[2] " + mycopyarray[2]);
Alert ("mycopyarray[3] " + mycopyarray[3]);
Alert ("mycopyarray[4] " + mycopyarray[4]);
Alert ("mycopyarray[5] " + mycopyarray[5]);
Note: You can use MQL4 ArrayCopy function which copies one array to another one. But the ArrayCopy
is not the scope of our today article and we will discuss the MQL4 Arrays Function in another article.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
230 of 258 6/14/2006 5:36 PM
Accessing the elements of the Array:
When you create an array and fill it with the elements, you can access the elements of the array by the
index number of each element.
The first element in the array has the index 0 and the second has the index 1 etc.
Look at this code:
int myarray [6] = {1,4,9,16,25,36 };
Alert ("The first element at myarray is: " + myarray[0]);
Alert ("The second element at myarray is: " + myarray[1]);
Alert ("The third element at myarray is: " + myarray[2]);
Alert ("The fourth element at myarray is: " + myarray[3]);
Alert ("The fifth element at myarray is: " + myarray[4]);
Alert ("The sixth element at myarray is: " + myarray[5]);
In the above code myarray[0] is the first element in the array and myarray[1] is the second element etc.
The last element in this array is myarray[5]. (Figure 4).
Figure 4 - accessing the elements or the array
You can type code like this to access the third array element:
int third_element;
third_element = myarray[2];
Alert(third_element); //9
Hope that the Arrays is understandable subject now. And see you in other article.
Coders Guru
MQL4 Array Functions
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
231 of 258 6/14/2006 5:36 PM
Hi folks,
We have talked about the Arrays in a previous article and we covered all the aspects of the Arrays in
general and in MQL4 in particular. But MQL4 concerned more about the arrays and for that it built a set
of functions handling the arrays.
Today will talk about this set of build-in MQL4 functions one by one.

ArrayBsearch:
Syntax:
int ArrayBsearch( double array[], double value, int count=WHOLE_ARRAY, int start=0, int
direction=MODE_ASCEND)
Description:
The ArrayBsearch function searches an array for the occurrence of a value. The function returns the
index of the first occurrence of the value if the value is found in the array and returns the nearest one if
the value is not found.
The function searches only the first dimension of the array and cannot be used with the arrays of strings
or serial numbers.
Note: You have to sort the numeric arrays using ArraySort() function before performing binary search.
Parameters:
double array[]
The numeric array you want to search it.
double value
The value you are searching for in the array.
int count
The count of elements in the array you want to search them. By default the function searches the whole of
the array (WHOLE_ARRAY or 0).
int start
The index you want to start from your searching. By default, the search starts on the first element (0).
int direction
The searching direction; It can be one of the following values:
MODE_ASCEND: forward direction searching;
MODE_DESCEND: backward direction searching.
Example:
datetime daytimes[];
int shift=10,dayshift;
// All the Time[] timeseries are sorted in descendant mode
ArrayCopySeries(daytimes,MODE_TIME,Symbol(),PERIOD_D1);
if(Time[shift]>=daytimes[0]) dayshift=0;
else
{
dayshift=ArrayBsearch(daytimes,Time[shift],WHOLE_ARRAY,0,MODE_DESCEND);
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
232 of 258 6/14/2006 5:36 PM
if(Period()<PERIOD_D1) dayshift++;
}
Print(TimeToStr(Time[shift])," corresponds to ",dayshift," day bar opened
at", TimeToStr(daytimes[dayshift]));
ArrayCopy:
Syntax:
int ArrayCopy( object& dest[], object source[], int start_dest=0, int start_source=0, int
count=WHOLE_ARRAY)
Description:
The ArrayCopy function copies an array to another array. The source and destination arrays must be of
the same type, but arrays with type double[], int[], datetime[], color[], and bool[] can be copied as arrays
with same type.
The function returns the number of the elements has been copied.
Parameters:
object& dest[]
The destination array - the array you want to copy to.
object source[]
The source array - the array you want to copy from.
int start_dest
The starting index for the destination array. By default, start index is 0.
int start_source
The starting index for the source array. By default, start index is 0.
int count
The count of elements that should be copied. By default, all the elements of the source array
(WHOLE_ARRAY).
Example
double array1[][6];
double array2[10][6];
// fill array with some data
ArrayCopyRates(array1);
ArrayCopy(array2, array1,0,Bars-9,10);
// now array2 has first 10 bars in the history
ArrayCopyRates:
Syntax:
int ArrayCopyRates( double& dest_array[], string symbol=NULL, int timeframe=0)
Description:
The ArrayCopyRates function copies the rate from the chart RateInfo array to a two-dimensional
array where the second dimension has these elements.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
233 of 258 6/14/2006 5:36 PM
0 – time;
1 – open;
2 – low;
3 – high;
4 – close;
5 - volume.
Note: The numbers in front of the above rate are the index in the array.
Parameters:
double& dest_array[]
The array you want to copy the chart rate info to.
string symbol
The symbol name of the currency pair you want to get the rate info. Default (NULL) means the current
currency used in the chart.
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
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
234 of 258 6/14/2006 5:36 PM
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.
Use 0 if you want the current timeframe of the chart.
Example:
double array1[][6];
ArrayCopyRates(array1,"EURUSD", PERIOD_H1);
Print("Current bar ",TimeToStr(array1[0][0]),"Open", array1[0][1]);
ArrayCopySeries:
Syntax:
int ArrayCopySeries( double& array[], int series_index, string symbol=NULL, int timeframe=0)
Description:
The ArrayCopyRates function copies a series array to another array. The function returns the number of
the elements has been copied.
Parameters:
double& array[]
The array you want to copy to.
int series_index
The type of the series array you want to copy. It can be any of following values:
Constant
Value
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
235 of 258 6/14/2006 5:36 PM
Description
MODE_OPEN
0
Open price.
MODE_LOW
1
Low price.
MODE_HIGH
2
High price.
MODE_CLOSE
3
Close price.
MODE_VOLUME
4
Volume, used in Lowest() and Highest() functions.
MODE_TIME
5
Bar open time, used in ArrayCopySeries() function.
Note: If the series_index is MODE_TIME, the first distension array must be a datetime array.
string symbol
The symbol name of the currency pair you want to get the rate info. Default (NULL) means the current
currency used in the chart.
int timeframe
The chart periodicity you want to use. Use 0 if you want the current timeframe of the chart.
Example:
datetime daytimes[];
int shift=10,dayshift;
// All the Time[] timeseries are sorted in descendant mode
ArrayCopySeries(daytimes,MODE_TIME,Symbol(),PERIOD_D1);
if(Time[shift]>=daytimes[0]) dayshift=0;
else
{
dayshift=ArrayBsearch(daytimes,Time[shift],WHOLE_ARRAY,0,MODE_DESCEND);
if(Period()<PERIOD_D1) dayshift++;
}
Print(TimeToStr(Time[shift])," corresponds to ",dayshift," day bar opened at ",
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
236 of 258 6/14/2006 5:36 PM
TimeToStr(daytimes[dayshift]));
ArrayDimension:
Syntax:
int ArrayDimension( int array[])
Description:
The ArrayDimension function returns the dimensions count of the given array.
Parameters:
int array[]
The array you want to retrieve its dimensions count.
Example:
int num_array[10][5];
int dim_size;
dim_size=ArrayDimension(num_array);
// dim_size is 2
ArrayGetAsSeries:
Syntax:
bool ArrayGetAsSeries( object array[])
Description:
The ArrayGetAsSeries function checks the elements of given array and retruns true if the array is a series
array (array elements indexed from last to first) and false otherwise.
Parameters:
int array[]
The array you want to check its elements.
Example:
if(ArrayGetAsSeries(array1)==true)
Print("array1 is indexed as a series array");
else
Print("array1 is indexed normally (from left to right)");
ArrayInitialize:
Syntax:
int ArrayInitialize( double& array[], double value)
Description:
The ArrayInitialize function sets all the elements of the given numeric array to the same value. The
function returns the count of the elements in the created array.
Parameters:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
237 of 258 6/14/2006 5:36 PM
double& array[]
The numeric array you want to initialize.
double value
The value you want to set all the elements of the array to.
Example:
//---- setting all elements of array to 2.1
double myarray[10];
ArrayInitialize(myarray,2.1);
ArrayIsSeries:
Syntax:
bool ArrayIsSeries( object array[])
Description:
The ArrayIsSeries function checks the given array if it’s a series array (time, open, close, high, low, or
volume) or not. The function returns true if the array is a series array and false otherwise.
Parameters:
object array[]
The array you want to check.
Example:
if(ArrayIsSeries(array1)==false)
ArrayInitialize(array1,0);
else
{
Print("Series array cannot be initialized!");
return(-1);
}
ArrayMaximum:
Syntax:
int ArrayMaximum( double array[], int count=WHOLE_ARRAY, int start=0)
Description:
The ArrayMaximum function searches the elements of the given array for the maximum value. The
function returns the index of the maximum value
Parameters:
double array[]
The array you want to search.
int count
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
238 of 258 6/14/2006 5:36 PM
The count of elements in the array you want to search them. By default the function searches the whole of
the array (WHOLE_ARRAY or 0).
int start
The index you want to start from your searching. By default, the search starts on the first element (0).
Example:
double num_array[15]={4,1,6,3,9,4,1,6,3,9,4,1,6,3,9};
int maxValueIdx=ArrayMaximum(num_array);
Print("Max value = ", num_array[maxValueIdx]);
ArrayMinimum:
Syntax:
int ArrayMinimum ( double array[], int count=WHOLE_ARRAY, int start=0)
Description:
The ArrayMinimum function searches the elements of the given array for the minimum value. The
function returns the index of the minimum value
Parameters:
double array[]
The array you want to search.
int count
The count of elements in the array you want to search them. By default the function searches the whole of
the array (WHOLE_ARRAY or 0).
int start
The index you want to start from your searching. By default, the search starts on the first element (0).
Example:
double num_array[15]={4,1,6,3,9,4,1,6,3,9,4,1,6,3,9};
int maxValueIdx=ArrayMaximum(num_array);
Print("Max value = ", num_array[maxValueIdx]);
ArrayRange:
Syntax:
int ArrayRange( object array[], int range_index)
Description:
The ArrayRange function returns the count of the elements of the given dimension of the given array.
Note: Because the arrays in MQL4 are zero-based array, the size of the array is the largest index + 1.
Parameters:
object array[]
The array you want to check.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
239 of 258 6/14/2006 5:36 PM
int range_index
The dimension you want to check.
Example:
int dim_size;
double num_array[10,10,10];
dim_size=ArrayRange(num_array, 1);
ArrayResize:
Syntax:
int ArrayResize( object& array[], int new_size)
Description:
The ArrayResize function sets a new size for the first dimension of the given array. The function returns
the count of the elements of the resized array if it successfully resized the array and 0 otherwise.
Parameters:
Object& array[]
The array you want to resize.
int new_size
The new size.
Example:
double array1[][4];
int element_count=ArrayResize(array, 20);
// element count is 80 elements
ArraySetAsSeries:
Syntax:
bool ArraySetAsSeries( double& array[], bool set)
Description:
The ArraySetAsSeries function reverses the index order of the given array to a series array. The function
returns true in success and false otherwise.
Parameters:
double & array[]
The array you want to reverse its elements.
bool set
The series flag to set (true) or drop (false).
Example:
double macd_buffer[300];
double signal_buffer[300];
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
240 of 258 6/14/2006 5:36 PM
int i,limit=ArraySize(macd_buffer);
ArraySetAsSeries(macd_buffer,true);
for(i=0; i<limit;
i++) macd_buffer[i]=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i)-iMA(NULL,0,26,0,MODE_EMA,PRICE_CLOSE,i);
for(i=0; i<limit; i++)
signal_buffer[i]=iMAOnArray(macd_buffer,limit,9,0,MODE_SMA,i);
ArraySize:
Syntax:
int ArraySize( object array[])
Description:
The ArraySize function returns the size of the given array.
Parameters:
object array[]
The array (any type) you want to get its size.
Example:
int count=ArraySize(array1);
for(int i=0; i<count; i++)
{
// do some calculations.
}
ArraySort:
Syntax:
int ArraySort( double& array[], int count=WHOLE_ARRAY, int start=0, int sort_dir=MODE_ASCEND)
Description:
The ArraySort function sorts the first dimension of the given numeric array.
Note: Series arrays can't be sorted by this function.
Parameters:
double& array[]
The numeric array you want to sort.
int count
The count of elements in the array you want to sort them. By default the function sorts the whole of the
array (WHOLE_ARRAY or 0).
int start
The index you want to start from your sorting from. By default the sort starts from the first element (0).
int sort_dir
The sorting direction; It can be one of the following values:
MODE_ASCEND: sort ascending;
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
241 of 258 6/14/2006 5:36 PM
MODE_DESCEND: sort descending.
Example:
double num_array[5]={4,1,6,3,9};
// now array contains values 4,1,6,3,9
ArraySort(num_array);
// now array is sorted 1,3,4,6,9
ArraySort(num_array,MODE_DESCEND);
// now array is sorted 9,6,4,3,1

I hope you enjoyed the article!
Coders Guru
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
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
242 of 258 6/14/2006 5:36 PM
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
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
243 of 258 6/14/2006 5:36 PM
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 |
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
244 of 258 6/14/2006 5:36 PM
//| 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);
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
245 of 258 6/14/2006 5:36 PM
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:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
246 of 258 6/14/2006 5:36 PM
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
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
247 of 258 6/14/2006 5:36 PM
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.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
248 of 258 6/14/2006 5:36 PM
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.
External functions
Hi folks,
Today we are going to talk about a very important development issue; The external functions in MQL4.
We all know the normal functions in MQL4, if you don’t know what are the functions (or you forgot) I’ll
repeat some my speech about the functions I told you in my MQL4 Functions lesson.
What are the MQL4 functions anyway?
The function is very like the sausage machine, you input the meat and spices in the machine from one side
and it outputs the sausage.
The meat and the spices are the function parameters and the sausage is the function output (return value).
The machine itself is the function body.
There’s only one difference between the functions and the sausage machine that some of functions will
return nothing (nothing in MQL4 called void).
Let’s take an example:
double //type of sausage -return value type
my_func(double a , double b , double c) //function name and parameters list (meat & spices)
{
return (a*b+c); //sausage outputs - returned value
}
As you see above the function starts with the type of the returned value "double" followed by the function
name which followed by parentheses. Inside the parentheses you put the meat and the spices, sorry, you
put the parameters of the function.
Here we have put three parameters double a, double b and double c.
Then the function body starts and ends with braces. In our example the function body will produce the
operation (a*b+c).
The return keyword is responsible about returning the final result.
You call the above function like this:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
249 of 258 6/14/2006 5:36 PM
double result = my_func(1.5 , 2 , 5.9);

As you see in the above line of code, you first declared a double variable to hold the returning value of our
function. Then you assigned to that variable the function calling. You called the function by writing the
function name then passed to it between the brackets the proper parameters (three double values in our
case).
When MQL4 see the function name, it will take the provided parameters and goes to the function body to
execute the code inside that body and return with the value and place it at the same point of the function
calling.
This was a summery explaining of the MQL4 function. What about the external functions in MQL4?
External functions:
External functions are functions reside at external files not the source file you are writing right now.
You can use these function by importing them from the external files to your code.
Those external files can be one of two kinds of files:
1- MQL4 executable files (ex4):
You can use the functions reside at an already compiled MQL4 program called library programs. The file
must be located at the MetaTrader 4\experts\libraries path and must be compiled (.ex4) before importing
the functions you want from them. We will know everything about using the functions reside at these types
of MQL4 programs in this article. The creating of this type of program is the subject of another article.
2- Windows Dlls:
DLLs (Dynamic Link Libraries) are programs written in an advanced programming language (like Visual
basic or C++) for Microsoft Windows operating system. They are very like the normal programs like the
Microsoft Word or FireFox browser but they mostly have no user interface and the other important
difference that they can loaded from more than one application.
They are mostly contains shared function which can be used with all the windows application.
Using DLLs from MQL4 give the language a very strong advantage and enables it to make a lot of things
another applications can do.
For example you can use the windows winsock DLL to send and receive data through the internet. The
options are very wide and even dangerous.
We will know everything about using the functions reside at windows DLLs in this article. The creating of
these DLLs is out scope of our MQL4 development field.
Using external functions from a library file:
I’ve create a library file in the purpose of this article (The steps creating of this file is out or article’s
scope). Download the file if you want and save it the libraries path then compile it:
icon mylib.zip (309 B)
//+------------------------------------------------------------------+
//| mylib.mq4 |
//| Copyright Coders Guru |
//| http://www.metatrader.info |
//+------------------------------------------------------------------+
#property copyright "Copyright Coders Guru"
#property link "http://www.metatrader.info"
#property library
//+------------------------------------------------------------------+
//| My functions |
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
250 of 258 6/14/2006 5:36 PM
//+------------------------------------------------------------------+
int MyExtFunction(int value,int value2)
{
return(value+value2);
}
//+------------------------------------------------------------------+
In the above code we have created a normal function MyExtFunction which we will import it from
another MQL4 program and use it. The MyExtFunction function takes two integers parameters and
returns the value of those two numbers addition.
Let’s create a simple program which imports and uses the external function MyExtFunction.
Download this file if you want and place it in the scripts folder then compile it:
icon Exteranl functions 1.zip (406 B)
//+------------------------------------------------------------------+
//| Exteranl functions 1 .mq4 |
//| Copyright Coders Guru |
//| http://www.metatrader.info |
//+------------------------------------------------------------------+
#property copyright "Copyright Coders Guru"
#property link "http://www.metatrader.info"
#import "mylib.ex4"
int MyExtFunction(int value,int value2);
#import
//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
int start()
{
//----
int result = MyExtFunction(10,20);
Alert ( result);
//----
return(0);
}
//+------------------------------------------------------------------+
In the code above to use an external function resides in a MQL4 library file we have taken two steps:
1- Importing the external function from the library.
2- Using (calling) the function like any MQL4 function.
Importing the external function:
To be able to use the external function from your code you have to import it to your code.
Importing the function takes three lines of code as you see above:
#import "mylib.ex4"
This is the first import line, we use the #import keyword followed by the library name, the line doesn't end
with semi-colon.
int MyExtFunction(int value,int value2);
Then in the second line you declare the function very like the normal functions by writing the type of
returned value followed by the function name then the parameters of the function and their types.
Without this declaration your program will not know anything about the external function. You can
import as many function as you want, in this case you write every function in a separate line.
The declaration line must ends with semi-colon.
#import
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
251 of 258 6/14/2006 5:36 PM
To tell the compiler of MQL4 that you have finished your importing you have to write another line
contains the #import keyword, but in this case without an external file.

Note: You use only one #import line to end all the opened import lines, for example:
#import "mylib.ex4"
int MyExtFunction(int value,int value2);
#import "mylib2.ex4"
double MyExtFunction2(double value3);
#import
Calling the external function:
If you have written right import block lines like the above description, you can call the external function
very like calling any normal function in MQL4 program. In our program we called the MyExtFunction
like this:
int result = MyExtFunction(10,20);
Alert ( result);
We passed the numbers 10 and 20 to the function and assigned the returned value to the integer variable
result. The Alert function will pop up the result variable like figure 1.
Using external functions from a DLL file:
Importing an external function from a DLL file is the same as importing them from a library file. The only
difference is the close import line, in the case of importing an external function from a DLL you have not
to write the #import line.
Let's take an example:
Download the file if you want and save it the scripts path then compile it:
icon Exteranl functions 2.zip (439 B)
//+------------------------------------------------------------------+
//| Exteranl functions 2.mq4 |
//| Copyright Coders Guru |
//| http://www.metatrader.info |
//+------------------------------------------------------------------+
#property copyright "Copyright Coders Guru"
#property link "http://www.metatrader.info"
#import "user32.dll"
int MessageBoxA(int hWnd,string lpText,string lpCaption,int uType);
//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
int start()
{
//----
int result = MessageBoxA(NULL,"Helo world!","MQL4 Messagebox",0);
//----
return(0);
}
//+------------------------------------------------------------------+
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
252 of 258 6/14/2006 5:36 PM
As you can notice in the program above the import lines are the same as the using external function from a
library except the closing #import line.
In the above code we used a function of user32.dll the very important windows DLL, and called it in the
code very like any normal function.
The MessageBoxA function will pop up a message box like the one in figure 2.
Figure 2 - Message box
MQL2 to MQL4 conversion and vice versa!
Hi folks,
In these series of articles I’ll try to remove the stumbling blocks from the road of the programmers who
want to convert MQL2 programs to MQL4 and vice versa.
A lot of people find that the MQL2 and the MQL4 are different worlds, because the syntax of MQL2 is
based on EasyLanguage while the syntax of MQL4 is very like the C syntax (Besides the new added
features to the MQL4 language).
But I think that, although it’s hard to convert between the two languages but it’s not an impossible task.
That’s because the both of the two languages talking about the same thing; about creating a program for
MetaTrader, so, they are not two separated worlds but they are two faces of the same coin.
We can’t set a series of lessons to study MQL2 like which we assigned to MQL4 but you will know a lot of
MQL2 principals while you are skimming these conversion articles.
We will take somewhat a practical approach studding the difference between the two languages, that’s by
studding a real example of a program wrote in the both language and observing the conversion operation
has been occurred.
Let’s converting!
Our example program:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
253 of 258 6/14/2006 5:36 PM
We are going to work in these articles with an indicator called “3D Oscilator”.
Download the MQL2 source code: icon 3D Oscilator_MQL2.zip (974 B)
Download the MQL4 source code: icon 3D Oscilator_MQL4.zip (1009 B)
Note: The 3D Oscilator has been created in MQL2 by Luis Damiani and converted to MQL4 by Ricardo.
Ramdass.

Loading the 3D Oscilator(s) in the MT4 and MT3 terminals:
If you are a lucky person like me and have the both of MT4 and MT3 installed in your machine, you can
compile the 3D Oscilator and load it in the Terminals. (If you don't have MT3 yet, you can download it
from the MetaQuotes download section: http://www.metaquotes.net/downloads/).
To compile the MQL4 version:

1- Place the “3D Oscilator.mq4” file in the Indicators path.
2- Double click it to open it in MetaEditor.
3- Press F5 to compile the program (produced file extension is .ex4).
4- Open MetaTrader and from the Navigator window navigate to the Custom Indicators section and
double click the 3D Oscilator.
5- When you get the Properties window (Figure 1) click OK.
Figure 1 - Properties window in MetaTrader 4
To compile the MQL2 version:
The same steps as MQL4, but you will get a Properties window like this:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
254 of 258 6/14/2006 5:36 PM
Figure 2 - Properties window in MetaTrader 3
Figures 3 and 4 shows how the indicator looks like in the both platforms:
Figure 3 - How the indicator appears MetaTrader 4
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
255 of 258 6/14/2006 5:36 PM

Figure 4 - How the indicator appears MetaTrader 3

Cracking the MQL2 program:
We are going to crack the MQL2 program section by section and line by line to convert it to the MQL4
program.
/*[[
Name := 3D Oscilator
Author := Luis Damiani
Separate Window := Yes
First Color := lime
First Draw Type := Line
First Symbol := 217
Use Second Data :=yes
Second Color := RoyalBlue
Second Draw Type := Line
Second Symbol := 218
]]*/
The section above is the description section where you put the name of the program, the author name,
window type of the indicator, the indicator line properties and symbols etc.
The section when converted to MQL4 it will be dispersed in the program and not in a gathered section like
MQL2.
In this section you can find the following commands:
Name: The name of the program.
Author: The author name of the program.
Separate Window: Plot the indicator in the main chart window (No) or in a separate window.
First Color: The color of the first line (Second, Third etc).
First Draw Type: The type of the drawing line; it maybe: Line, Histogram or Symbol (Second, Third etc).
First Symbol: The symbol number from Wingdings table of the drawing line (Second, Third etc).
Use Second Data: Yes means that the indicator calculation results in 2 charts, and not the only one.
Minimum Chart Limits: If the indicator is shown in a separate window this command sets the minimum
value drawn on the chart.
Maximum Chart Limits: the maximum value drawn on the chart.
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
256 of 258 6/14/2006 5:36 PM

Let's see how we converted these lines to MQL4:
Name := 3D Oscilator
The Name of the program usually wrote in the comment section in MQL4 along with the Author name
and the website Link.
//+------------------------------------------------------------------+
//| 3D Oscilator.mq4 |
//| |
//| |
//+------------------------------------------------------------------+

Author := Luis Damiani
The Author name wrote in the comment section and in the copyright property directive:
#property copyright "Author - Ricardo. Ramdass - Conversion only"
Separate Window := Yes
The equivalent line in MQL4 is the indicator_separate_window property:
property indicator_separate_window
First Color := lime
The color of the line in MQL4 set by the indicator_colorN property, where the N is is the number of the
line, for example:
#property indicator_color1 //First line color
#property indicator_color2 //Second line color
#property indicator_color8 //Eighth line color
In MQL4 we have to add extra line before the indicator_color property, this is the indicator_buffers
property which sets the number of the buffers used in the program, the buffers used for the calculations of
the indicators and for drawing lines.
In our program we will use two lines and will not use any buffers for calculation. So we have to set 2
buffers:

#property indicator_buffers 2
And to set the color of the first line we used this line of code:
#property indicator_color1 Yellow
First Draw Type := Line
To set the drawing type of the line in MQL4 you use SetIndexStyle() function and you have to use it inside
the Init() function.
In our program we used code like this:
Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
257 of 258 6/14/2006 5:36 PM
int init() {
....
SetIndexStyle(0,DRAW_LINE);
....
}
SetIndexStyle:
void SetIndexStyle( int index, int type, int style=EMPTY, int width=EMPTY, color clr=CLR_NONE)
This function will set the style of the drawn line.
The index parameter of this function ranges from 1 to 7 (that’s because the array indexing start with 0
and we have limited 8 lines). And it indicates which line we want to set its style.
The type parameter is the shape type of the line and can be one of the following shape type’s constants:
DRAW_LINE (draw a line)
DRAW_SECTION (draw section)
DRAW_HISTOGRAM (draw histogram)
DRAW_ARROW (draw arrow
DRAW_NONE (no draw)
The style parameter is the pen style of drawing the line and can be one of the following styles’ constants:
STYLE_SOLID (use solid pen)
STYLE_DASH (use dash pen)
STYLE_DOT (use dot pen)
STYLE_DASHDOT (use dash and dot pen)
STYLE_DASHDOTDOT (use dash and double dots)
Or it can be EMPTY (default) which means it will be no changes in the line style.
The width parameter is the width of line and ranges from 1 to 5. Or it can be EMPTY (default) which
means the width will not change.
The clr parameter is the color of the line. It can be any valid color type variable. The default value is
CLR_NONE which means empty state of colors.
MQL4 Special functions init(), deinit() and start():
Functions are blocks of code which like a machine takes inputs and returns outputs.In MQL4 there are
three special functions which you can't name your functions the same names and have special jobs in
MQL4
init():
Every program will run this function before any of the other functions, you have to put here you
initialization values of you variables.
start():
Here’s the most of the work, every time a new quotation have received your program will call this
function.
deinit():
This is the last function the program will call before it shutdown, you can put here any removals you want.


Mql - Metatrader Development Course http://www.metatrader.info/book/print/34
258 of 258 6/14/2006 5:36 PM
Alerts

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

To write your MQL4 code and as anything else in world, you can choose one of two ways, the hard way and the easy way. 1- The hard way: The hard way is using your favorite text editor and the command prompt to compile your program. Notepad is not bad choice, but do not forget two things: 1- To save the file you have created in plain text format. 2- To save the file as .mp4 (that’s to be easy to reopen it with MetaEditor), but you can save it as any extension you prefer. After saving your program there is an extra step to make your code comes out to the light. It’s the Compiling step. Compiling means to convert the human readable script that you have just wrote to the machine language that your computer understands. MetaTrader has been shipped with its own compiler (the program which will convert your script to the machine language) called MetaLang.exe. Metalang.exe is a console program which takes two parameters and output an .ex4 file (the file which Metatrader understands). The first parameter is “options” parameter and the only option available is –q quit The second parameter is the full path to your .mql file. The syntax will be in this format. metalang [options…] filename Example: 1- Find your metalang.exe path, it will be the same path of MetaTrader (here my path is D:\Program Files\MetaTrader 4). 2- Create a batch file and name it compile.bat (or any name you prefer). 3- Write these lines into the bat file then save it: cd D:\Program Files\MetaTrader 4 metalang -q "D:\Program Files\MetaTrader 4\my_first_mql4_script.mq4" (Don’t forget to change the path to you MetaTrader installed path). 4- Run the batch file and if you are lucky person like me you will get a screen like figure 1.

2 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

Figure 1 Metalang compiler As you see you will get the output file “my_first_mql4_script.ex4” 2-The easy way: Metatrader has been shipped with a good IDE (integrated development editor) called MetaEditor which has these features: 1- A text editor has the feature of highlighting different constructions of MQL4 language while you are writing/reading code. 2- Easy to compile your program, just click F5 and the MetaEditor will make all the hard work for you and produces the “ex4” file. Besides it’s easy to see what the wrong in your program is (in the Error Tab – see figure 2). 3- Built-in a dictionary book which you can access by highlight the keyword you want to know further about it then press F1.

3 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

Figure 2 MetaEditor 4 In the coming lessons we will know more about MetaEditor. Today I just came to say hello, tomorrow we will start the real works and will study the Syntax of MQL4. I welcome very much the questions and the suggestions. See you Coders’ Guru Note: MetaTrader, the MetaTrader logo and MetaEditor are trademarks or registered trademarks of MetaQuotes Software Crop.

Lesson 2 - SYNTAX
Hi folks, We are talking today about the SYNTAX rules of MQL4. And as I told you before, If you are programming in C (or its superset C++) then you know a lot of MQL4 before even I start my lessons. That’s because the syntax of MQL4 is very like of the syntax of C.

The dictionary means of the word SYNTAX of a programming language is: “The set of allowed reserved words and their parameters and the correct word order in the expression is called

4 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

the syntax of language”. “Wikipedia”

So, when we are studying the syntax of the language we are studying its grammar and writing rules which consist of: · · · · Format Comments Identifiers Reserved words

Let’s slice the cake.

1-

Format:

When you write your code, you can freely use any set of spaces, tabs and empty lines you want to separate your code and your line of code to make them readable and eyes pleasing.

For example all of these lines are valid in MQL4:

double MacdCurrent, MacdPrevious, SignalCurrent;

double MacdCurrent, MacdPrevious, SignalCurrent;

double

MacdCurrent,

MacdPrevious,

SignalCurrent;

5 of 258

6/14/2006 5:36 PM

MetaQuotes Software Corp." This is the valid “Controlling compilation”: #property copyright "Copyright © 2004. MetaQuotes Software Corp.metatrader.Mql . For example the next lines are invalids: 6 of 258 6/14/2006 5:36 PM .. Identifiers or Keywords. “extren” and “int” here are Keywords .Metatrader Development Course http://www. the first line is more readable and easy to understand." 2- You can’t use new line or space in the middle of Constant values. You will know more in the next lessons. as you see.info/book/print/34 But. And as everything in the world there are exceptions to the rule: 1- You can’t use new line in the “Controlling compilation” remember this is an exception. You will know more about “Controlling compilation” in next lesson but just For example the next line of code is invalid and the MQL4 compiler will complain: #property copyright "Copyright © 2004. “MA_Period” is an Identifier and “13” is a Constant value. For example this line is valid: extern int MA_Period=13.

info/book/print/34 extern int MA_Period=1 3. Assume that you write a program in the summer and in the winter you want to read it.metatrader.Mql .Metatrader Development Course http://www. For example: //This is a comment extern int MA_Period=13. extern int MA_Period=1 3. MQL4 (& C/C++) uses two kinds of comments styles: 1- Single line comments The Single line comment starts with “//” and ends with the new line. You use Comments to write lines in your code which the compiler will ignore then but it clears your code and makes it understandable. any programming language has its style of writing comments. Notice the tab between 1 and 3. ex tern int MA_Period=13.you can’t understand all these puzzled lines. Without comments -even you are the code’s creator. 2.Comments: To make the programming world easier. 7 of 258 6/14/2006 5:36 PM .

And you can comment more than line or more by putting “/*” at the start of the first line.Mql .info/book/print/34 extern int MA_Period=13.metatrader. For example: /* this is multi line comment*/ You can also nest single line comment inside multi lines comment like that: /* this is multi line comment*/ //another comment nested here. //This is another comment 2- Multi-line comments The multi-line comment start with “/*” and ends with “*/”.Metatrader Development Course http://www. This is a valid comment too: 8 of 258 6/14/2006 5:36 PM . and “*/” at the end of the last line.

For example MA_Period here is an identifier: extern int MA_Period=13. 3- You can’t use any reserved words as an Identifier. constants and functions.Metatrader Development Course http://www. So.Mql . 2- The Identifier must begin with a letter (capital or small) or the underlining symbol _.metatrader. There are few rules and restrictions for choosing those names: 1- The length of the Identifier must not exceed 31 characters. 9 of 258 6/14/2006 5:36 PM .info/book/print/34 extern int /*HELLO! I’m a comment*/ MA_Period=13. 3- Identifiers: An identifier is the name you choose to your variables. But this is invalid comment: extern int //test MA_Period=13. it can’t be started with a number or another symbol except the underlining symbol.

Metatrader Development Course http://www. This is the list of the reserved words (from the MQL4 guide): Data types bool color datetime double Memory classes extern static Operators Break Case continue Default false true Other 10 of 258 6/14/2006 5:36 PM . So.Reserved words: There are “words” which the language uses them for specific actions.metatrader.Mql .info/book/print/34 You will see the list of the reserved words too soon. So. they are reserved to the language usage and you can’t use them as an identifier name or for any other purpose. 4- The identifiers’ names are case sensitive. MA_PERIOD not the same as ma_period or MA_Period Let’s take some examples: Name1 _Name1 1Name ~Name1 N~ame1 Valid Valid Invalid (don’t start with number) Invalid (you can only use underline symbol) Invalid (you can only use underline symbol) i_love_my_country_and_my_country_loves_all_the_world Invalid (you can’t exceed the 31 characters length) Color color Valid Invalid (you can’t use reversed word. and color is one of them) 4.

this name is the variable constant. The box size is memory storage area required in bytes. this process is known as declaration. When we create a variable we are telling the computer that we want him to assign a specified memory length (in bytes) to our variable. To help you think of this as a picture. a letter or a large number is not going to occupy the same space in memory. double continue = 0.MQL4 Data types What’s the Data type mean? Any programming language has a set of names of the memory representation of the data. For example if the memory holds numbers between -2147483648 to 2147483647. Variables? Variables are the names that refer to sections of memory into which data can be stored. imagine that memory is a series of different size boxes. the box must be given a name. It helps if you give a box a meaningful name that relates to the type of information which make it easier to find the data. int extern =20.Metatrader Development Course http://www.metatrader. When we set the value of the box you have created in the same line you declared the variable. the most of the programming languages will name this data as “Integer” data type. since storing a simple number. In the declaration process you use a word tell the computer what’s the kind and size of the box you want to use.info/book/print/34 int string void Else For If Return Switch While For example the next lines of code are invalid: extern int datetime =13. 11 of 258 6/14/2006 5:36 PM .Mql . Lesson 3 . this process is known as initialization. Data is placed into a box by assigning the data to the box. so the computer will ask us what’s the kind of data and how much the length of the data? That is the Data type for. this word known as keyword. In order to use a box to store data.

Mql . 2134. -230 12 of 258 6/14/2006 5:36 PM .info/book/print/34 For example if we said this line of code to the computer: int MyVaraible=0. In MQL4. 0. int ß Declaration MyVaraible ß Variable’s constant. In the previous example we have used: int ß Keyword int ß Integer data type. For example the next numbers are Integers: 12. is a number that can start with a + or a .Metatrader Development Course http://www. MQL4 presents the integer in decimal or hexadecimal format. 3. =0 ß Initialization We will know more about variables in a coming lesson.sign and is made of digits. That’s mean we are asking the computer to set a block of 4 bytes length to our variable named “MyVaraiable”. And its range value is between -2147483648 to 2147483647.metatrader. these are the kinds of Data types: Integer (int) Boolean (bool) Character (char) String (string) Floating-point number (double) Color (color) Datetime (datetime) 1- Integer An integer.

1.true. 6. false. And it occupies 1 bit of the memory. 3. 7. 0 and 1). 4.Mql .False. 0X7C7 We use the keyword int to create an integer variable. For example.info/book/print/34 0x0A. Boolean named like this in the honor of the great mathematician Boole George.Metatrader Development Course http://www. true and false (or their numeric representation. and uses digits (0. 0x12. 0xA3. We use the keyword bool to create a boolean variable. the decimal numeral 79 can be written as 4F in hexadecimal. Decimal and Hexadecimal: Decimal notation is the writing of numbers in the base of 10. 2- Boolean Boolean variable is a data type which can hold only two values. In MQL4. and with one of the sign symbols + (plus) or − (minus) to indicate sign. 5. For example: int intInteger = 0. int intHexIntger=0x12. 0x2f.TRUE and True are equals. These digits are frequently used with a decimal point which indicates the start of a fractional part. int intAnotherIntger = -100. 2. 13 of 258 6/14/2006 5:36 PM . 0X12. 0Xa3.metatrader. 8 and 9) to represent numbers.FALSE. Hexadecimal is a numeral system with a base of 16 usually written using the symbols 0–9 and A–F or a–f.

Here we use something called Escape Sequence to present those special characters. For example: 'a' . 3- Character MQL4 names this Data type “Literal”. and special key elements defined in the ASCII (American Standard Code for Information Interchange) set. numeric. A character is one of 256 defined alphabetic. bool bFlag = 1. bool bBool=FALSE.info/book/print/34 For example: bool I = true. 14 of 258 6/14/2006 5:36 PM . '$' .metatrader. And that by prefixing the character with the backslash character (\). 'Z' We use the keyword int to create a character variable.Mql . Characters have integer values corresponding to location in the ASCII set. Some characters called Special Characters can’t present directly inside the single quotes because they have a reserved meanings in MQL4 language. For example: int chrA = 'A'.Metatrader Development Course http://www. int chrB = '$'. You write the character constant by using single quotes (') surrounding the character.

starting at index 0. A NULL character is a special character (represented by the ASCII code 0) used to mark the end of this type of string. See figure 1 for a simple representation of the string constant “hello” in the characters array. It does not matter if there are unused array locations after that.in your string constant by prefixing it with the backslash (\). carriage return new line horizontal tab reverse slash single quote double quote hexadecimal ASCII-code 4String \r \n \t \\ \' \" \xhh The string data type is an array of characters enclosed in double quote ("). a NULL character is placed in the next array location. int chrB = '\n'. //slash character //new line This is the list of Escape Sequence characters used in MQL4. We use the keyword string to create a string variable.Mql .info/book/print/34 For example: int chrA = '\\'. Figure 1 – Characters array MQL4 limits the size of the string variable to 255 characters and any character above 255 characters will generate this error: (too long string (255 characters maximum)). After the last character of data.metatrader. 15 of 258 6/14/2006 5:36 PM . The array of characters is an array which holds one character after another. You can use any special character -mentioned above.Metatrader Development Course http://www.

metatrader. //Notice the use of (") character.".-115. a number that can contain a fractional part beside the integer part separated with (. And you can write these values in decimal or hexadecimal format. We use the keyword double to create a floating-point variable. Between the two signal quotations you set the value of the red.Ex: 3.) dot). 15 and 0.5. 2.8e308.0. with you coders guru”. And you can assign the Integer value of the color to the color variable. string str3 = "1234567890".By the color name: For the well know colors (called Web Colors Set) you can assign the name of the color to the color variable. \"Forex-tsd forum\".0001. 5- Floating-point number (double) Floating point number is the Real Number (that is. double dblNumber3 = 1/4. string str2 = "Copyright © 2005.By the integer value: Every color in the Web Colors Set has its integer value which you can write it in decimal or hexadecimal format. 6- Color Color data type is a special MQL4 data type.Metatrader Development Course http://www.Mql . see the list of the Web Colors Set. green and blue (know as RGB value of the color). 3. GG is green value and RR is the red value. which holds a color appears on the MetaTrader chart when you create your own Expert Advisor or Custom Indictor and the user can change it from the property tab of your Expert Advisor or Custom Indictor. For example: // symbol constants 16 of 258 6/14/2006 5:36 PM . For example: double dblNumber1 = 1000000000000000. You can set the Color variable constant in three ways: 1. And its range value is between 2.75.2e-308 to 1. The hexadecimal color format looks like this: 0xBBGGRR where BB is the blue value. These values have to be between: 0 to 255.By Character representation (MQL4 named it this name): In this method you use the keyword (C) followed by two signal quotations ('). double dblNumber3 = 5.info/book/print/34 For example: string str1 = "Hello world1.

128.0x00.Mql .Metatrader Development Course http://www. color clr1= C'128. color clr1=32768. For example: color clr1= Red.128' // gray C'0x00.128.128' .info/book/print/34 C'128.metatrader.0xFF' // blue // named color Red Yellow Black // integer-valued representation 0xFFFFFF 16777215 0x008000 32768 // white // white // green // green We use the keyword color to create a color variable. Web Colors Set Black Maroon SeaGreen LightSeaGreen Goldenrod DarkOrange DeepSkyBlue LightSlateGray IndianRed MediumPurple DarkGreen Indigo DarkGoldenrod DarkViolet MediumSpringGreen Orange Blue DeepPink MediumOrchid PaleVioletRed DarkSlateGray MidnightBlue DarkSlateBlue FireBrick LawnGreen Gold Magenta MediumTurquoise GreenYellow Coral Olive DarkBlue Sienna CadetBlue Yellow Red DodgerBlue MediumAquamarine CornflowerBlue Green MediumBlue DarkOrchid Chartreuse Gray Turquoise DarkSeaGreen DarkGray Teal Brown Chocolate YellowGreen Lime SlateGray RoyalBlue Tomato DarkOliveGreen SaddleBrown DarkTurq MediumVioletRed MediumSeaGreen SandyBrown MediumSla 17 of 258 6/14/2006 5:36 PM .

Mql . which holds a date and time data.Metatrader Development Course http://www. minutes.01 00:00' // New Year D'1980.19 12:00:00'.07. For example: D'2004. datetime dt1= D'2005. You set the Datetime variable by using the keyword (D) followed by two signal quotations (').01. For example: datetime dtMyBirthDay= D'1972. 18 of 258 6/14/2006 5:36 PM . Datetime constant can vary from Jan 1. hour.19 12:30:27' D'19.2004 00:00:00' We use the keyword datetime to create a datetime variable.22 04:30:00'.1980 12' D'01.19 12:00:00' //equal to D'01.2004' //equal to D'1980. month.info/book/print/34 DarkSalmon Plum PaleGreen Moccasin LemonChiffon Lavender LavenderBlush BurlyWood Khaki Thistle LightPink Beige MistyRose MintCream HotPink LightGreen PowderBlue Gainsboro AntiqueWhite OldLace Snow Salmon Aquamarine PaleGoldenrod PeachPuff PapayaWhip WhiteSmoke White Violet Silver PaleTurquoise Pink Cornsilk Seashell LightCoral LightGrey Bisque LightYellow Ivory LightSkyBlue LightStee LightGold 7- Datetime Datetime data type is a special MQL4 data type.1980 12:30:27' D'19. 2037.07. date.01. and seconds.07.01.07. Between the two signal quotations you write a character line consisting of 6 parts for value of year. 1970 to Dec 31.10.10.metatrader.

When the expressions combined together it makes a statement. And when the statements combined together it makes a function and when the functions combined together it makes a program.z and w.Mql .-. So. If I told you that (+. In the remaining of this lesson we are going to talk about the kinds operators used in MQL4.Metatrader Development Course http://www. you will remember very fast what’s the operator means. Puzzled? Let’s illustrate it in an example: x = (y*z)/w. I know the operations. The whole line is an expression.metatrader.info/book/print/34 Lesson 4 . I hear you saying “OK.MQL4 Operations & Expressions What’s the meaning of Operations & Expressions? You know the operations very well.y. Review the SYNTAX lesson) together with the Operations produce the Expressions. /) are the basic arithmetical operators.*. here are identifiers. let’s start with the basic arithmetical operators: 1- Arithmetical operators: In MQL4 there are 9 Arithmetical operations 19 of 258 6/14/2006 5:36 PM . x.* and / are the operators. could you tell me what’s the meaning of the expression?” Identifiers (do you remember them? If not. =.

A = B . Divide B on C and assign the result to A. Increase A by 1 (ex: if A =1 make it 2). A = -A.info/book/print/34 This is the list of them with the usage of each: Operator + +* / % ++ -- Name Addition operator Subtraction operator Sign changer operators Multiplication operator Division operator Modulus operator Increment operator Decrement operator Example A = B + C.Metatrader Development Course http://www. Multiply B and C and assign the result to A. A--. (ex: 10%2 will produce 0. 2.Mql .metatrader. B=A*5. A is the reminder of division of B on C. Subtract C from B and assign the result to C. Note: You can’t combine the increment and decrement operator with other expressions. A++. A = B * C. A =A % C. Description Add A to B and assign the result to C. Decrease 1 from A (ex: if A =2 make it 1). Change the sign of A from positive to negative. For example you can’t say: A=(B++)*5.Assignment operators: The purpose of any expression is producing a result and the assignment operators setting the left operand with this result. A = B / C. For example: 20 of 258 6/14/2006 5:36 PM . But you can write it like that: A++.C. 10%3 will produce 1).

21 of 258 6/14/2006 5:36 PM . (=) here is the assignment operator.Metatrader Development Course http://www. Assign B to A. ^= XOR Assignment operator A ^= B. Divide A on B and assign the result to A. A += B. &= A &= B. It shifts the bits of A right by the number of bits specified in B.metatrader. Multiply A and B and assign the result to A. Get the reminder of division of A on B and assign the result to A. A *= B. Description It’s equal to: A = A + B.Mql . A <<= B.B. A /= B. >>= <<= A >>= B. It’s equal to: A = A % B. It’s equal to: A = A * B. In MQL4 there are 11 assignments operations This is the list of them with the usage of each: Operator = += -= *= /= Name Assignment operator Additive Assignment operator Subtractive Assignment operators Multiplicative Assignment operator Divisional Assignment operator Modulating Assignment operator Left Shift Assignment operator Right Shift Assignment operator AND Assignment operator Example A = B.info/book/print/34 A = B * C. Looks at the binary representation of the values of A and B and does a bitwise AND operation on them. It shifts the bits of A left by the number of bits specified in B. |= OR Assignment operator A |= B. Add B to A and assign the result to A. A -= B. It’s equal to: A = A / B. Here we multiply B and C and assign the result to A. %= A %= B. Looks at the binary representation of the values of A and B and does a bitwise OR operation on them. Looks at the binary representation of the values of two A and B and does a bitwise exclusive OR (XOR) operation on them. Subtract B from A and assign the result to A. It’s equal to: A = A .

4 <= 4 //true //false //true.info/book/print/34 3. A >= B. A != B. In MQL4 there are 6 Relational operations This is the list of them with the usage of each: Operator == != < > <= >= Name Equal operator Not Equal operator Less Than operators Greater Than operator Less Than or Equal operator Greater Than or Equal operator Example A == Bi.Logical operators: Logical operators are generally derived from Boolean algebra. 4. True if A is less than B else False. The truth value of a concept in Boolean value can have just one of two possible values: true 22 of 258 6/14/2006 5:36 PM . True if A does not equal B else False. A < B.Relational operators: The relational operators compare two values (operands) and result false or true only. It’s is like the question “Is John taller than Alfred? Yes / no?” The result will be false only if the expression produce zero and true if it produces any number differing from zero. True if A is less than or equals B else False.metatrader.Mql . For example: 4 == 4. True if A is greater than or equals B else False. A <= B.Metatrader Development Course http://www. Description True if A equals B else False. 4 < 4. True if A is greater than B else False. which is a mathematical way of manipulating the truth values of concepts in an abstract way without bothering about what the concepts actually mean. A > B.

otherwise.metatrader.Metatrader Development Course http://www. then the right hand value is not considered. the value is 1.info/book/print/34 or false. otherwise the value of the expression is 1. except that they work on a smaller scale -binary representations of data. otherwise. The following operators are available in MQL4: Operator & Name AND operator Example A & B. 23 of 258 6/14/2006 5:36 PM . ^ ~ EXCLUSIVE-OR operator COMPLEMENT operator A ^ B. MQL4 names the Logical operators as Boolean operators MQL4 uses the most important 3 logical operators. if it is applied to a zero value. it returns 0. If the left hand value is non-zero. Compares two bits and generates a result of 1 if either or both bits are 1. Not operator is applied to a non-zero value then the value is zero. | OR operator A | B. || OR operator A || B. If the left hand value is zero.Mql . it returns 0. ! NOT operator !A. 5. Used to invert all of the bits of the operand. Compares two bits and generates a result of 1 if the bits are complementary. Description Compares two bits and generates a result of 1 if both bits are 1. If both of the values are zero then the value of the expression is 0 otherwise the value of the expression is 1. otherwise. it returns 0. && AND operator A && B. This is the list of them with the usage of each: Operator Name Example Description If either of the values are zero the value of the expression is zero. then the right hand value is not considered.Bitwise operators: The bitwise operators are similar to the logical operators. ~A.

metatrader. The function arguments separator operator -comma (. Moves the bits to the right.) We will know more about the Arrays and Functions in the next lessons. the division operator has a higher precedence than does the addition operator. Thus. << The SHIFT LEFT operator A << B. For example. Moves the bits to the left. Each move to the left effectively multiplies op1 by 2. so just remember these 3 operators as “Other operators”.info/book/print/34 >> The SHIFT RIGHT operator A >> B. Each move to the right effectively divides op1 in half. discards the far left bit. 6. and assigns the leftmost bit a value of 0. Operators with a higher precedence get evaluated first.Metatrader Development Course http://www. the two following statements are equivalent: x + y / 100 x + (y / 100) //unambiguous. recommended 24 of 258 6/14/2006 5:36 PM . the order is determined by the precedence assigned to the operators in use within the expression.Other operators: There are some operators which used in MQL4 and don’t belong to one of the previous categories: 123- The array indexing operator ([]). and assigns the rightmost bit a value of 0.Mql . Note Both operands associated with the bitwise operator must be integers. The function call operator (()). Operators Precedence: If you don't explicitly indicate the order in which you want the operations in a compound expression to be performed. discards the far right bit.

a rule must govern which is evaluated first.metatrader. () Function call From left to right [] Array element selection ! Negation From left to right ~ Bitwise negation - Sign changing operation * Multiplication From left to right / Division % Module division + Addition From left to right - Subtraction << Left shift From left to right >> Right shift < Less than From left to right 25 of 258 6/14/2006 5:36 PM . The following table shows the precedence assigned to the operators in the MQL4. This practice will make your code easier to read and to maintain. you should be explicit and indicate with parentheses () which operators should be evaluated first. Operators on the same group have equal precedence. Assignment operators are evaluated right to left. The operators in this table are listed in precedence order: The higher in the table an operator appears. Operators with higher precedence are evaluated before operators with a relatively lower precedence. All binary operators except for the assignment operators are evaluated from left to right.Mql .info/book/print/34 When writing compound expressions. the higher its precedence.Metatrader Development Course http://www. When operators of equal precedence appear in the same expression.

Metatrader Development Course http://www.metatrader.Mql .info/book/print/34 <= Less than or equals > Greater than >= Greater than or equals == Equals From left to right != Not equal & Bitwise AND operation From left to right ^ Bitwise exclusive OR From left to right && Logical AND From left to right || Logical OR From left to right 26 of 258 6/14/2006 5:36 PM .

info/book/print/34 = Assignment From right to left += Assignment addition -= Assignment subtraction *= Assignment multiplication /= Assignment division %= Assignment module >>= Assignment right shift <<= Assignment left shift &= Assignment bitwise AND |= Assignment bitwise OR ^= Assignment exclusive OR . For example: 27 of 258 6/14/2006 5:36 PM .Mql .Metatrader Development Course http://www.Loops & Decisions (Part1) Welcome to the fifth lesson in my course about MQL4. Comma From left to right Lesson 5 . The normal flow control of the program you write in MQL4 (And in others languages as well) executes from top to bottom. A statement is a line of code telling the computer to do something.metatrader. A statement by a statement.

Such controls consist of Loops and Decisions. The programs you write like -the human. Statements cause such jumps is called Control Statements. In MQL4 there are two kinds of loops: The for Loop -------------------------- The for loop considered the easiest loop because all of its control elements are gathered in one place. LOOPS ----------------- Loops causing a section of your program to be repeated a certain number of times.decides what to do in response of circumstances changing.info/book/print/34 Print("Hello World"). But the top bottom execution is not the only case and it has two exceptions. and that's make it the source of 90% of errors. In these cases the flow of control jumps from one part of the program to another.Mql . The for loop executes a section of code a fixed number of times. They are the loops and the decisions. And this repetition continues while some condition is true and ends when it becomes false. When the loop end it passes the control to next statement follow the loop section. return 0. For example: 28 of 258 6/14/2006 5:36 PM .Metatrader Development Course http://www.metatrader. A semicolon at end of the statement is a crucial part of the syntax but usually easy to forget.

j++) These three expressions are the initialization expression.metatrader.Metatrader Development Course http://www. the test expression and the increment expression: j=0 ß initialization expression j<15 ß test expression J++ ß increment expression The body of the loop is the code to be executed the fixed number of the loop: Print(j). j<15. j++) Print(j). And its purpose to give the loop variable an initial value (0 in our example). for(j=0. 29 of 258 6/14/2006 5:36 PM . That's because the for statement and the loop body are together considered to be a program statement. How does this work? The for statement consists of for keyword. The initialization expression: The initialization expression is executed only once.info/book/print/34 int j. when the loop first starts.Mql . This executes the body of the loop in our example for 15 times. Note: the for statement in not followed by a semicolon. followed by parentheses that contain three expressions separated by semicolons: for(j=0. j<15.

i<15.metatrader. In our example the body loop will continue printing i (Print(i)) while the case j<15 is true. The Test expression: The test expression always a relational expression that uses relational operators (please refer to relational operators in the previous lesson). while the inside declaration makes only the for loop to know about the variable. You can use more that one initialization expression in for loop by separating them with comma (.j=0. j<15.info/book/print/34 You can declare the loop variable outside (before) the loop like our example: int j. The outside declaration method makes every line in the code block to know about the variable. except the Scope of each variable (you will know more about the variable declaration and scopes in the Variables lesson). It evaluated by the loop every time the loop executed to determine if the loop will continue or will stop. for(i=0 . int j.) like this: int i. j++) The previous two lines of code are equal.i++) Print(i).Metatrader Development Course http://www. Or you can make the declaration inside the loop parentheses like this: for(int j=0. It will continue if the result of the expression is true and will stop if it false.Mql . For example the 30 of 258 6/14/2006 5:36 PM .

9. And when j reaches 15 the loop will stops and the control passes to the statement following the loop. 31 of 258 6/14/2006 5:36 PM .10.5.8.13 and 14. The Increment expression: The increment expression changes the value of the loop variable (j in our example) by increase it value by 1.11.4.Mql . Figure 1 .metatrader.3. testing the test expression and executing the body of the loop.1.Flow chart of the for loop Like the initialization expression.Metatrader Development Course http://www.6.7.12.info/book/print/34 j = 0.) like this: int i. Figure 1 shows a flow chart of the for loop. It executed as the last step in the loop steps. in the increment expression you can use more than one increment expression in the for loop by separating them with comma (.2. after initializing the loop variable.

9.2.5. But you can only use one test expression.13. we used only one statement in the body of the loop.11.i>0. this is not always the case.i--) Print(i).10. the program will execute the first 32 of 258 6/14/2006 5:36 PM .j=0. for(i=15. every time it decreases i by 1 and check the test expression (i>0).i++.1. PlaySound("alert.8. Another notice about the increment expression.j++) Print(i).info/book/print/34 int j. for(i=0 .12.i<. You can use multi statements in the loop body delimited by braces like this: for(int i=1.3.Mql . } In the above code the body of the loop contains two statements. The program will produce these results: 15.i<.Metatrader Development Course http://www.i++) { Print(i).6.i<=15. Multi statement in the loop body: In our previous examples. but it can perform and operation it like for example decrements the loop variable like this: int i.metatrader.14.wav").i<15.4. it’s not only can increase the variable of the loop.7. The above example will initialize the i to 15 and start the loop.

} The above example will execute the loop until i reaches 10.1. while the continue statement will get you back to the top of the loop (parentheses).9.Metatrader Development Course http://www.4.i<15.3.info/book/print/34 statement then the second one every time the loop executed.6.i<15.metatrader. For example: for(int i=0. The Continue Statement: The break statement takes you out the loop.i++) { if((i==10) break. The Break Statement: When the keyword presents in the for loop (and in while loop and switch statement as well) the execution of the loop will terminate and the control passes to the statement followed the loop section. i++) { if(i==10) continue.Mql .2.5. Don’t forget to put a semicolon at the end of every statement. For example: for(int i=0. Print(i). Print(i) 33 of 258 6/14/2006 5:36 PM .8. The code will produce these values: 0.7. in that case the break keyword will terminate the loop.

14.12.9.info/book/print/34 } The above example will execute the loop until i reaches 10. The while Loop --------------------- The for loop usually used in the case you know how many times the loop will be executed. in that case the continue keyword will get the loop back to the top of the loop without printing i the tenth time.metatrader.13. while(i<15) { Print(i)..Metatrader Development Course http://www.2.8. The while loop like the for loop has a Test expression.6.3.11.1. The code will produce these values: 0.7. What happen if you don’t know how many times you want to execute the loop? This the while loop is for. for example: for(.) This loop is like while loop with a test expression always set to true.5. This is an example: int i=0. Latest note: You can leave out some or all of the expressions in for loop if you want.4. But it hasn’t Initialization or Increment expressions.Mql . 34 of 258 6/14/2006 5:36 PM . We will introduce the while loop to you right now.

you can not declare or initialize it inside the parentheses of the while loop like the for loop.Metatrader Development Course http://www.Mql . How the above example does work? The while statement contains only the Test expression. In the example the loop will execute till i reaches 16 in this case i<15=false and the loop ends. Figure 2 shows a flow chart of the while loop.metatrader. but the body of the loop must contain some statement that changes the loop variable.info/book/print/34 i++. otherwise the loop would never end. The i++ statement here is not the increment expression as you may think. and it will examine it every loop. 35 of 258 6/14/2006 5:36 PM . if it’s false the loop will end and the control passes to the statement followed the loop section. } In the example you will notice the followings: The loop variable had declared and initialized before the loop. if it’s true the loop will continue.

These are the kinds of decisions statements available in MQL4: The if Statement -------------------------------- The if statement is the simplest decision statement. Here the if keyword has followed by parentheses. inside the parentheses the Test expression ( x < 100). in the case of using multi statements you have to delimit them by braces. here’s an example: if( x < 100 ) Print("hi").Mql . depending on the value of an expression. these are the similar aspects: 1.info/book/print/34 Figure 2 .. we have talked about the Loops. The second way is the Decisions. And we have seen that the Loops are one of two ways we use to change the normal flow of the program execution -from top to bottom. In the previous lesson. I hope you enjoyed the previous lessons. 2. Decisions in a program cause a one-time jump to a different part of the program.metatrader.) is while(true) Lesson 6 . 3. The similar copy of for(. You can single or multi statements in the body of the loop in both of them.Loops & Decisions (Part2) Welcome to the sixth lesson in my course about MQL4. You can use break statement and continue in both of them.Metatrader Development Course http://www. 36 of 258 6/14/2006 5:36 PM .Flow chart of the while loop I told you before that the while loop is like the for loop.

Metatrader Development Course http://www. For example: if(current_price==stop_lose) { Print("you have to close the order"). Figure 1 shows the flow chart of the if statement: Figure 1 .Flow chart of the if statement Multi Statements in the if Body: Like the loops.wav"). the body of if can consist of more than statement delimited by braces. the control passes to the statement follows the if block.info/book/print/34 when the result of test expression is true the body of the if will execute (Print("hi").metatrader. PlaySound("warning.) . 37 of 258 6/14/2006 5:36 PM .Mql .and if it is false.

ifs inside ifs.Metatrader Development Course http://www. Here's an example: for(int i=2 . PlaySound("warning.wav").Mql .info/book/print/34 } Notice the symbol == in the Test expression. loops inside ifs. and so on. Notice: you will notice that there are no braces around the loop body. when you forget and use the assignment operator =. i<10 .. This is a source of a lot of errors.metatrader. Nesting: The loops and decision structures can be basted inside one another. i++) if(i%2==0) { Print("It's not a prime nomber").. The if. you can nest ifs inside loops. operations & expressions. this is because the if statement and the statements inside its body. it's one of the Relational Operators you have studied in the lesson 4. are considered to be a single statement. } In the previous example the if structure nested inside the for loop.else Statement ------------------------------------------ 38 of 258 6/14/2006 5:36 PM .

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

The if statement let's you to do something if a condition is true, suppose we want to do another thing if it's false. That's the if...else statement comes in. It consist of if statement followed by statement or a block of statements, then the else keyword followed by another statement or a block of statements.

Like this example:

if(current_price>stop_lose) Print("It’s too late to stop, please stop!"); else Print("you playing well today!");

If the test expression in the if statement is true, the program one message, if it isn’t true, it prints the other.

Figure 2 shows the flow chart of the if…else statement:

Figure 2 - Flow chart of the if..else statement

39 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

Nested if…else Statements

You can nest if…else statement in ifs statements, you can nest if…else statement in if…else statement, and so on.

Like this:

if(current_price>stop_lose) Print("It’s too late to stop, please stop!"); if(current_price==stop_lose) Print("It’s time to stop!"); else Print("you playing well today!");

There’s a potential problem in nested if…else statements, you can inadvertently match an else with the wrong if.

To solve this case you can do one of two things:

1-

you can delimited the if…else pairs with braces like this:

if(current_price>stop_lose) { Print("It’s too late to stop, please stop!"); if(current_price==stop_lose) Print("It’s time to stop!"); else Print("you playing well today!");

40 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

}

2- If you can’t do the first solution (in the case of a lot of if…else statements or you are lazy to do it) take it as rule. Match else with the nearest if. (Here it’s the line if(current_price==stop_lose)).

The switch Statement ------------------------------------------

If you have a large decision tree, and all the decisions depend on the value of the same variable, you can use a switch statement here. Here’s an example:

switch(x) { case 'A': Print("CASE A"); break; case 'B': case 'C': Print("CASE B or C"); break; default: Print("NOT A, B or C"); break; }

In the above example the switch keyword is followed by parentheses, inside the parentheses you’ll find the

41 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

switch constant, this constant can be an integer, a character constant or a constant expression. The constant expression mustn’t include variable for example: case X+Y: is invalid switch constant.

How the above example works?

The switch statement matches the constant x with one of the cases constants. In the case x=='A' the program will print "CASE A" and the break statement will take you the control out of the switch block.

In the cases x=='B' or x=='C', the program will print "CASE B or C". That’s because there’s no break statement after case 'B':.

In the case that x != any of the cases constants the switch statement will execute the default case and print "NOT A, B or C".

Figure 3 shows the flow chart of the switch statement

42 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

Figure 3 - Flow chart of the switch statement

Lesson 7 - Functions
Welcome to the world of MQL4 Functions. The functions in any language take two phases: Learning them which sometimes a boring thing. Using them which always a lifeboat.

Let’s start the seventh lesson.

What’s the meaning of functions?

43 of 258

6/14/2006 5:36 PM

Metatrader Development Course http://www.returned value As you see above. Return keyword: The return keyword terminate the function (like the break keyword does in the loop).info/book/print/34 The function is very like the sausage machine. Here we have put three parameters double a. Let’s take some examples: double // type of the sausage – return value my_func (double a. double b. Like the next 44 of 258 6/14/2006 5:36 PM . double c. you put the parameters of the function. you input the meat and the spices and it outs the sausage. Then the function body starts and ends with braces. } // sausage outs . In our example the function body will produce the operation (a*b + c). The machine itself is the function body. There’s only one difference between the functions and your sausage machine. The meat and the spices are the function parameters. Notice: Not all the functions use the return keyword. double b. Inside the parentheses you put the meat and spices. and this means to terminate the function and return the result of the expression.metatrader. And it can be without expression and its only job in this case is to terminate the function. the sausage is the function return value. and it gives the control to the function caller (we will know it soon). the function starts with the type of the returned value “double” followed by the function name which followed by parentheses.Mql . The return keyword can include an expression inside its parentheses like the above example return (a*b + c). sorry. some of the functions will return nothing (nothing in MQL4 called void). especially if there’s no return value. double c) // function name and parameters list (meat & spices) { return (a*b + c). The return keyword is responsible about returning the final result.

Metatrader Development Course http://www. These kinds of functions in some programming language called “Methods”. but MQL4 calling them functions. Assume you have a function which collects the summation of two integers. int second_number) { return(first_number+ second_number).Mql .info/book/print/34 example: void // void mean there’s no sausage – returned value. Function call: We know very well now what the function is (I hope)? How to use the functions in your MQL4? There’s an extra steps after writing your function to use the function in you program. This is the function: int collect (int first_number. } The function above will not return value. but you want to use it. This step is calling it (using it). but it will print the parameter s you provided.metatrader. When the function has no return value you use “void” as the funciotn returns type. } You know how the previous function works. my_func (string s) // function name and parameters list (meat & spices) { Print(s). You use it like this: 45 of 258 6/14/2006 5:36 PM .

MQL4 when see your function name. easy right? Nesting functions inside function: You can nest function (or more) inside the body of another function. here you declared a variable (sum) to hold the function return value and gave the function its two parameters (a. But how did it know? The magic line is int sum = collect(a. Print (sum).b). Print(sum).Metatrader Development Course http://www. 46 of 258 6/14/2006 5:36 PM . it will take you parameters and go to the function and it will return –soon.info/book/print/34 int a = 10. You basically called the function. void means there’s no return vale (do you still remember?).b). int b = 15.with the result and place them in same line.Mql . int sum = collect(a. For example: We will use the collect function described above inside another new function which its job is printing the result of the collection: void print_collection (int first_number. int second_number) { int sum = collect(first_number. It’s very like copying all the lines of the function instead of the place you called the function in.b). } Here we called the collect function inside the print_collection function body and printed the result.metatrader. That’s because the caller line is treated like any normal statement (it’s actually a statement). The example above will print 25 (is it a magic). second_number).

When your program finishes its job or you close the chart window or change the financial symbol or the chart periodicity or shutdown MetaTrader terminal. The box size is memory storage area required in bytes. this word known as keyword.Mql . We will know a lot about these functions in our real world lessons when we write our own Expert advisor and Custom Indictor. Data is placed into a box by assigning the data to the box. When we create a variable we are telling the computer that we want him to assign a specified memory length (in bytes) to our variable. imagine that memory is a series of different size boxes. the box must be given a name. every program begins with the function “init()” (initialize) and it occurs when you attach your program(Expert advisor or Custom indicator) to the MetaTrader charts or in the case you change the financial symbol or the chart periodicity. the function "deinit()" (de-initialize) will occur.info/book/print/34 MQL4 Special functions init(). That’s mean we are asking the computer to set a block of 4 bytes length to our variable named “MyVaraiable”. When we set the value of the box you have created in the same line you declared the variable. For example if we said this line of code to the computer: int MyVaraible=0. this process is known as initialization. this name is the variable constant. so the computer will ask us what’s the kind of data and how much the length of the data? That is the Data type for. To help you think of this as a picture. The third function (which is the most important one) “start()” will occur every time new quotations are received . Lesson 8 . In order to use a box to store data. you spend 90 of your programming life inside this function.Variables in MQL4 What are the variables mean? As I told you the secret before. a letter or a large number is not going to occupy the same space in memory.Metatrader Development Course http://www. since storing a simple number. In the declaration process you use a word tell the computer what’s the kind and size of the box you want to use. the variables are the names that refer to sections of memory into which data can be stored. And its job is initializing the main variables of your program (you will know about the variables initialization in the next lesson). deinit() and start(): In MQL4. 47 of 258 6/14/2006 5:36 PM . this process is known as declaration.metatrader. It helps if you give a box a meaningful name that relates to the type of information which make it easier to find the data.

variable not defined. color and datetime) with the name you chose to the variable. bool. for example MyVaraible=0.metatrader. double. To know what’s the variable. 1 error(s). You can initialize the variable at the same line of the declaration like the example: int MyVaraible=0. these are the kinds of Data types: Integer (int) Boolean (bool) Character (char) String (string) Floating-point number (double) Color (color) Datetime (datetime) I’ve copied the previous few lines from the DATA TYPES lesson for you. If you used it without declaration the MQL4 compiler will complain and will tell you something like this:'MyVaraible' . string. And before the declaration you can’t use the MyVariable in your code. Initialization: Initializing the variable means to assign a value to it. By using the keywords you have learned in the DATA TYPES lesson (int. now how do to declare the variables: Declaration: Declaring a variable means to introduce it to the world and specify its type.info/book/print/34 In the previous example we have used: int ß Keyword int ß Integer data type. 0 warning(s). char. int ß Declaration MyVaraible ß Variable’s constant. Here you declared a variable named MyVaraible which is an integer type.Mql . =0 ß Initialization We will know more about variables in a coming lesson.Metatrader Development Course http://www. For example: int MyVaraible. And you can declare the variable in one place and initialize it in another place like this: 48 of 258 6/14/2006 5:36 PM . In MQL4.

Local variable means they are not seen to outside world where they had declared. Local and Global. double my_func (double a. double c) { return (a*b + c + Global_Variable). } Here the variable Global_Variable declared outside the function (function level declaration) so.info/book/print/34 int MyVaraible. and they are the variables which had declared outside any block of code and can be seen from any part of your code. double c) { int d .Mql . double b. which part of code will know about the variable and can use it. it can be seen by all the functions in you program. The second kind of the scopes is the Global variables. because d is not seen to the next line of the function because it’s outside it. For example: double my_func (double a.metatrader.c and d are local variables. and the variables declared inside the loop or decisions block of code are local to those blocks and can be seen or used outside them. For example the variables declared inside function are local to the function block of code.b. which can be used only inside the function block of code ( any thing beside the braces) and can’t be used by outside code.Metatrader Development Course http://www. Scopes of variables: There are two scopes of the variables. 49 of 258 6/14/2006 5:36 PM . So we can’t write a line after the function above saying for example: d=10. return (a*b + c). For example: int Global_Variable. Scope means. double b. } In the above example the variables a. … … MyVaraible=5. But keep in your mind this fact: the declaration must be before the initialization.

info/book/print/34 The Global variables will automatically set to zero if you didn’t initialize them. MA_method. make it extern variable.. For example: extern color Indicator_color = C'0x00. those kinds of variables are used to define input date of the program.Metatrader Development Course http://www.Preprocessors What are the Preprocessors mean? 50 of 258 6/14/2006 5:36 PM .0xFF'. Look at Figure 1. Lesson 9 . Apply_to and Style are variables defined using the “extern” keyword so they appear in the property sheet. Figure 1: Property sheet of MA indicator Here the variables Period.Mql . // blue int init() { . Shift. Extern variables: The keyword “extern” used to declare a special kind of variables. } Here the variable Indicator_color had defined as an extern variable which you will see it the first time you attach your indicator (or EA) to the MetaTrader chart and which you can change it from the properties sheet windows.. which you can set them form the property of your Expert advisor or Custom indicator.0x00. Any variable you want the user of your program be able to change and set.metatrader.

Mql . And you can notice too that the line didn’t end with semi-colon but it ended with a carriage-return character (new line).define directive: define directive used to generate a constant. The constant is very like the variable with only one different.h” in the place you wrote the include keyword before processing your code. for example you can’t start the constant name with a number or exceeds 31 characters.h> that’s mean you telling the compiler to include the content of the file “win32. 51 of 258 6/14/2006 5:36 PM .Metatrader Development Course http://www. you set its value only once and you can not change its value in your code like the variable. For example: #define my_constant 100 As you can notice in the above example there’s no assignment symbol (=) but only space between the constant name (my_constant ) and its value (100). The compiler will replace each occurrence of constant name in your source code with the corresponding value.info/book/print/34 Preprocessors are the instructions you give to the compiler to carry them out before starting (processing) your code. For example if you used the preprocessor directive #include <win32. In MQL4 there are four of preprocessors directives: 1. So you can use the above constant in your code like that: sum = constant1 * 10. The name of constant obeys the same rules you had learnt about choosing the identifier names (lesson 2 SYNTAX). The value of the content can be any type you want.metatrader.

For example: #property link "http://www. where N lies between 1 and 8 before script run message box with confirmation appears before script run its property sheet appears.metatrader. which you can set them in your program.Metatrader Development Course http://www.info/book/print/34 2. They are the properties of your program which you can set them using the compiler directive “property” and the compiler will write them in the settings of your executable program (ex4 file).property directive: There are predefined constants called “Controlling Compilation” included in the MQL4 language.Mql .com" #property copyright "Anyone wants to use" This is the list of the MQL4 predefined constants: Constant link copyright stacksize indicator_chart_window indicator_separate_window indicator_buffers indicator_minimum indicator_maximum indicator_colorN indicator_levelN show_confirm show_inputs Type string string int void void int int int color double void void Description a link to the company website the company name stack size show the indicator in the chart window show the indicator in a separate window the number of buffers for calculation. where N lies between 1 and 8 predefined level N for separate window custom indicator. up to 8 the bottom border for the chart the top border for the chart the color for displaying line N.forex-tsd. disables show_confirm property 52 of 258 6/14/2006 5:36 PM .

But there are differences between them.h and don’t search the current directory.info/book/print/34 3- include directive: When you asking the compiler to include a file name with the “include” directive.h” and reads all of its content and copy them in the same place of the include statement. For example: #include <win32.Metatrader Development Course http://www. You use import only with MQL4 executables files (.dll) to import their functions to your program.metatrader. You can use include at anywhere you want but it usually used at the beginning of the source code. it’s very like when you copy the entire file content and paste it in the place of the line you write include. 4- import directive: It’s like include directive in the aspect of using outside file in your program. you have to use quotes instead of angle brackets like this: #include “mylib. terminal_directory\experts\include) to search for the file win32.Mql . If the file you want to include located at the same path of your code.h” In the both cases if the file can’t be found you will get an error message. Tip: It’s a good programming practice to write the frequently used code in a separate file and use include directive to put it in your code when you need (just an advice). 53 of 258 6/14/2006 5:36 PM .ex4) or library files (.h> In the above example you telling the compiler to open the file “win32. Note: in the above example you enclosed the file name with Angle brackets () and that’s mean you telling the compiler to use the default directory (usually.

int hDC).metatrader. int uType. And –finally. When you import functions from “ex4” file you haven’t to declare their functions to be ready for use.string lpCaption.string lpCaption.string lpText.Your First Indicator (Part3) Welcome to the third part of “Your First Indicator” lesson.string lpText. In the previous lesson we studied the code of our first indicator line by line and we reached the function dinit().info/book/print/34 For example: #import "user32.Mql .dll” file requires you to declare the functions you want to use like this: int MessageBoxA(int hWnd. ReleaseDC(int hWnd. #import "melib.int wLanguageId). int uType). int MessageBoxExA(int hWnd. int uType).dll" int MessageBoxA(int hWnd.Metatrader Development Course http://www.we will 54 of 258 6/14/2006 5:36 PM .ex4" #import "gdi32. You must end the import directives with a blank import line #import (without parameters). I hope you’ve came from the previous lessons with a clear idea about what we have done. While importing the functions from a “.dll" int int #import GetDC(int hWnd). Today we are going to study start() function and its content. Lesson 12 .string lpText. And only the functions you has declared you can use in your code.string lpCaption.

metatrader.Mql . //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---.indicators SetIndexStyle(0. IndicatorShortName(short_name).forex-tsd. string short_name = "Your first indicator is running!".forex-tsd. //---return(1).ExtMapBuffer1). } //+------------------------------------------------------------------+ //| Custor indicator deinitialization function | //+------------------------------------------------------------------+ 55 of 258 6/14/2006 5:36 PM .com | //+------------------------------------------------------------------+ #property copyright "Codersguru" #property link "http://www. Are you ready? Let’s hack the code line by line: Our Code: //+------------------------------------------------------------------+ //| My_First_Indicator.com" #property indicator_separate_window #property indicator_buffers 1 #property indicator_color1 Red //---. SetIndexBuffer(0.Metatrader Development Course http://www.info/book/print/34 compile and run our first Indicator.buffers double ExtMapBuffer1[].DRAW_LINE).mq4 | //| Codersguru | //| http://www.

dResult = dHigh . int pos=Bars-counted_bars.dLow. ExtMapBuffer1[pos]= dResult .info/book/print/34 int deinit() { //---//---return(0).check for possible errors if (counted_bars<0) return(-1).last counted bar will be recounted if (counted_bars>0) counted_bars--. //---. pos--. dResult.metatrader. dLow .Metatrader Development Course http://www. } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { int counted_bars=IndicatorCounted(). //---. //---. double dHigh . } //---return(0).Mql .main calculation loop while(pos>=0) { dHigh = High[pos]. } 56 of 258 6/14/2006 5:36 PM . Comment("Hi! I'm here on the main chart windows!"). dLow = Low[pos].

every time the start() function has been called. This number must be 0 or greater if there’s no errors have been occurred. where 0 means no error and any number else means an error has been occurred. } As I told you before. That’s because it’s the most important MQL4 Special functions.Metatrader Development Course http://www. We have got the number of counted_bars in the previous line of code by using IndicatorCounted() function. __ if (counted_bars<0) return(-1).info/book/print/34 //+------------------------------------------------------------------+ int start() {. start() function returns an integer value like all of the MQL4 special function. On the contrary of the init() and deinit function. __ if (counted_bars>0) counted_bars--. _ Here. In the first launch of your indicator this count will be 0 because the indicator didn’t calculate any bars yet. we have defined the variable counted_bars as an integer type. we will spend 90% of programming life inside the braces of start() function.. If it’s less than 0 that’s means we have an error and we have to terminate the start() function using the return statement.metatrader. return(0). int IndicatorCounted() This function will return an integer type value holds the count of the bars which our indicator has been calculated them.Mql . And after that it will be the count of total bars on the chart -1.. and we have assigned to it the returned value of the function IndicatorCounted(). 57 of 258 6/14/2006 5:36 PM . (Please see the function Bars below). int counted_bars=IndicatorCounted(). start() will not be called (by the terminal client) only one time. But every time a new quotation arrives to MetaTrader terminal client.

Metatrader Development Course http://www. That’s by subtracting the counted_bars from the count of total bars on the chart.Mql ._ You will get this error: 'Bars' . That’s because we want to recount the last bar again._ _ _ __ __ _ _ _ _ _ _ _ _ __ _ _ 58 of 258 6/14/2006 5:36 PM . Note: We can write the expression counted_bars-. is it a variable? Another example will proof for you that they are not variables: If you type and compile this line of code: Bars=1. Close. Variable means a space in memory and data type you specify. For example Bars collects and returns the number of the bars in chart.info/book/print/34 _ We are checking here if the counted_bars are greater than 0. If that’s true we decrease this number by subtracting 1 from it. we are declaring the variable pos to hold the number of times our calculation loop will work (see while loop later in this lesson).unexpected token That’s because they are not variables hence you can’t assign a value to them.Operations & Expressions) for decreasing the value of counted_bars by 1. It’s a good time to discuss Bars() function and its brother.metatrader. _ Here. Pre-defined MQL4 variables: Ask. High. And I’ll proof to you why they are functions. Time and Volume are functions although MQL4 called them Pre-defined variables. Bid. we get the total bars count using Bars() function. Function means do something and return some value. the next line of code is a valid line and will not generate and error in compiling: Alert(Bars(1)). Another proof.like this: _ _______ _ int pos=Bars-counted_bars. Bars. Open. So. Low. We use the decrement operator (please review Lesson 4 .

double Open[] This function returns a double type value holds the opening price of the referenced bar. double Ask This function (used in your Expert Advisors) returns a double type value holds the buyer’s price of the currency pair. Where it’s the lowest price from prices observed during a trade period. For example: Low [0] will return the lowest price of the current bar.27/133. double Bid This function (used in your Expert Advisor) returns a double type value holds the seller’s price of the currency pair. Where closing price is the price at the end of a trade period For example: Close[0] will return the closing price of the current bar. double High[] This function returns a double type value holds the highest price of the referenced bar.32 the left part is called the bid price (that is a price at which the trader sells). 59 of 258 6/14/2006 5:36 PM .Mql . the second (the right part) is called the ask price (the price at which the trader buys the currency).info/book/print/34 You can’t pass parameter to a variable.metatrader. Where opening price is the price at the beginning of a trade period (year. int Bars This function returns an integer type value holds count of the total bars on the current chart. USD/JPY = 133. let’s discuss every function. hour etc) For example: Open[0] will return the opening price of the current bar. double Low[] This function returns a double type value holds the lowest price of the referenced bar.Metatrader Development Course http://www. I’m so sorry for the lengthiness. Note: For example. double Close[] This function returns a double type value holds the closing price of the referenced bar. month. Where it’s the highest price from prices observed during a trade period. parameters passed only to the functions. week. For example: High [0] will return the highest price of the current bar. day.

Expert log Figure 3 . dResult. double dHigh .. dLow . Comment("Hi! I'm here on the main chart windows!"). For example: Volume [0] will return this average for the current bar.. int Digits This function returns an integer value holds number of digits after the decimal point (usually 4)..metatrader. void Alert( . We declared three double type variables which we will use them later. ) This function takes the values passed to it (they can be any type) and print them on the left top corner of the chart (figure 1).. This line of code uses the Comment function to print the text “Hi! I'm here on the main chart windows!” on the left top corner of the main chart (figure1). void Print ( . For example: Time [0] will return the open time of the current bar. usually one day. There are two similar functions: void Comment( .Mql . double Point This function returns a double value holds point value of the current bar (usually 0.Metatrader Development Course http://www.. ) This function takes the values passed to it (they can be any type) and print them to the expert log (figure 2).Alerts 60 of 258 6/14/2006 5:36 PM ..info/book/print/34 double Volume[] This function returns a double type value holds the average of the total amount of currency traded within a period of time.0001. ) This function takes the values passed to it (they can be any type) and display them in a dialog box (figure 3) Figure 1 – Comment Figure 2. datetime Time[] This function returns a datetime type value holds the open time of the referenced bar. Notice the way we used to declare the three of them at the same line by separating them by coma.

The last line of the loop is a decrement expression which will decrease the loop variable pos by 1 every time the loop runs.dLow. Press F5 or choose Compile from file menu. by assigning it to the drawn buffer array ExtMapBuffer1[]. The result of subtracting dLow from dHigh will be assigned to the variable dResult. ExtMapBuffer1[pos]= dResult . And assign to the variable dLow the value of the lowest price of the current loop variable.Mql . it’s the time to enter the loop for calculating our indicator points to draw them. In the loop body we assign to the variable dHigh the value of the highest price of the current loop variable. Before we enter the loop we have got the number of times the loop will work by subtracting the counted_bars from the total count of the bars on chart. The number of times the loop will work called Loop variable which it’s pos variable in our example. And when this variable reaches -1 the loop will be terminated. Then we using the dResult to draw or indicator line. That will generate the executable file “My_First_indicator. we can compile our indicator.Metatrader Development Course http://www. We use the loop variable as a current bar of the calculation for example High[pos] will return the highest price of the pos bar. Finally. Any value we assign to the array ExtMapBuffer1[] will be drawn on the chart (because we have assign this array to the drawn buffer using SetIndexBuffer function).ex4” which you can load in your terminal client. pos--. dResult = dHigh .info/book/print/34 while(pos>=0) { dHigh = High[pos]. dLow = Low[pos]. } Now. To load your indicator click F4 to bring the terminal client. Then From the Navigator 61 of 258 6/14/2006 5:36 PM .metatrader.

want to drink a cup of tea or even take a short vacation. The second solution is using a program to automate your trades. If this employee is an expert. The indicators –in general. And be prepared to your first Expert Advisor in the next lesson(s). You have to consider one of these solutions: You may rent someone to observe the terminal for you and calling your mobile phone every five minutes to tell you what’s going on. Note: The indicator will not do much. I welcome very much your questions and suggestions.Mql . First two steps: 62 of 258 6/14/2006 5:36 PM . he will cost you your capital. And if he is novice one. It can buy.info/book/print/34 window find the My_First_indicator and attach it to the chart (figure4). That’s what the Expert Advisor is for.are very important for the technical analysis of the market in trying to predict the future prices. It enables you to drink a cup of tea and save the salary you gave out to your employee or the bunch of flowers you bring to your assistant wife.Metatrader Development Course http://www. and keep your eyes widely open. but it was very useful for us as programmers. sell and modify the orders for you. he will cost you the pips you earn. buy and modify our orders manually. Coders’ Guru Lesson 13 . If you get tired. The Expert advisor is a program wrote in MQL4 (we are studying MQL4 huh?) uses your favorite indicators and trade methods to automate your orders.metatrader. Today we are going to create our first expert advisor so let’s go. You have to set in front of your terminal. Although this indicator wasn’t useful for us as trader.Your First Expert Advisor (Part 1) In the previous lesson we created our first indicator. but it believed that the subtraction of the highest and lowest of the price gives us the market's volatility. Figure 4 – My_First_Indicator I hope you enjoyed your first indicator. But with the indicators we observe the chart then use our hands to sell.

in our sample we will use My_First_EA.Mql . I think it’s the time to run it. Figure 1 – the first step wizard Step2: When you clicked Next. This field is optional which means you can leave it without setting In our sample we have added three variables: Varaible _ Type _ initial value --------------------------------------TakeProfit _ double _ 350 Lots _ double _ 0. 2. 3. This wizard enables you to set the properties of your expert advisor and to set the external variables you will use in your expert advisor. Type: double click this field to set the data type of the variable.1 TrailingStop _ double _ 35 63 of 258 6/14/2006 5:36 PM .External variables list: This is the list of the external variables you allow the user of your expert advisor to change them from the Expert properties window. From the MetaEditor File menu click New (you can use CTRL+N hotkey or click the New icon in the standard toolbar). In this step you can set these properties: 1. That will pop up the new program wizard which you have seen when you created your first indicator (Figure 1).Metatrader Development Course http://www. Every record has three fields: Name: double click this field to set the name (identifier) of the variable. type your name (I typed mine in the sample).Link to your web site.Author name of the program.Name of your expert advisor. clicking it will add a new record to the external variables list. To add a new variable you click the Add button. This time we will choose the first option “Expert Advisor program” then click Next button. Initial value: double click this field to give your variable initialization value.metatrader. you have got the general properties wizard (Figure 2). 4.info/book/print/34 Step1: If you didn’t open your MetaEditor yet.

This is the code we have got from the wizard: //+------------------------------------------------------------------+ //| My_First_EA.Metatrader Development Course http://www. //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---//---return(0).input parameters extern double TakeProfit=250. Note: you have to put the expert advisors in MetaTrader 4\experts path and the indicators in MetaTrader 4\experts\indicators path. extern double Lots=0.1.metatrader.forex-tsd.0.Mql .com | //+------------------------------------------------------------------+ #property copyright "Coders Guru" #property link "http://www.info/book/print/34 Figure 2 – the second step wizard Now click the Finish button to close the wizard.forex-tsd. } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() 64 of 258 6/14/2006 5:36 PM .com" //---.0. and MetaEditor will bring to you the code created by the wizard and saves the file My_First_EA.mq4 | //| Coders Guru | //| http://www.mq4 in the MetaTrader 4 \experts path. extern double TrailingStop=35. otherwise they will not work.

com" //---.Mql .com | //+------------------------------------------------------------------+ #property copyright "Coders Guru" #property link "http://www.input parameters extern double TakeProfit=250.Metatrader Development Course http://www. the code generated by the wizard is a template for you to add your code without bothering you by typing the main functions from scratch. Now let’s add our own code: //+------------------------------------------------------------------+ //| My_First_EA.0.1.metatrader.0. //+------------------------------------------------------------------+ //| expert initialization function | 65 of 258 6/14/2006 5:36 PM . } //+------------------------------------------------------------------+ As you see above.info/book/print/34 { //---//---return(0). extern double Lots=0.forex-tsd. } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---//---return(0). extern double TrailingStop=35.forex-tsd.mq4 | //| Coders Guru | //| http://www.

//down if(current_dirction != last_direction) //changed { last_direction = current_dirction. } else { return (0). } int Crossed (double line1 . return (last_direction).Metatrader Development Course http://www. if(line1>line2)current_dirction = 1.metatrader.Mql . static int current_dirction = 0. //up if(line1<line2)current_dirction = 2. double line2) { static int last_direction = 0.info/book/print/34 //+------------------------------------------------------------------+ int init() { //---//---return(0). } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---//---return(0). } 66 of 258 6/14/2006 5:36 PM .

PRICE_CLOSE.Lots.MODE_EMA.3. total. return(0).0). "My EA". return(0).8.0.0.0.PRICE_CLOSE.0.metatrader. if(total < 1) { if(isCrossed == 1) { ticket=OrderSend(Symbol(). longEma.Mql .0.Ask.0). ticket.OP_BUY.Green).Ask+TakeProfit*Point.Metatrader Development Course http://www.longEma). } if(TakeProfit<10) { Print("TakeProfit less than 10").12345. int isCrossed = Crossed (shortEma.13. // check TakeProfit } shortEma = iMA(NULL. if(Bars<100) { Print("bars less than 100"). longEma = iMA(NULL.info/book/print/34 } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---int cnt. double shortEma.MODE_EMA.0. total = OrdersTotal(). if(ticket>0) { 67 of 258 6/14/2006 5:36 PM .

SELECT_BY_TICKET.Metatrader Development Course http://www. if(ticket>0) { if(OrderSelect(ticket. } else Print("Error opening BUY order : ".MODE_TRADES)) Print("SELL order opened : ".metatrader.info/book/print/34 if(OrderSelect(ticket. MODE_TRADES).Bid. } return(0).GetLastError()). Bid-TakeProfit*Point.3.Bid.Mql .Violet).GetLastError())."My EA".cnt<total. } if(isCrossed == 2) { ticket=OrderSend(Symbol().OrderOpenPrice()). if(OrderType()<=OP_SELL && OrderSymbol()==Symbol()) { if(OrderType()==OP_BUY) // long position is opened { // should it be closed? if(isCrossed == 2) { OrderClose(OrderTicket(). SELECT_BY_POS.12345.OrderLots().3.OrderOpenPrice()). } else Print("Error opening SELL order : ". return(0). 68 of 258 6/14/2006 5:36 PM .SELECT_BY_TICKET.0. return(0).Lots.Red).OP_SELL.MODE_TRADES)) Print("BUY order opened : ".0. } for(cnt=0.cnt++) { OrderSelect(cnt.

Mql . // close position return(0).0. // exit } // check for trailing stop if(TrailingStop>0) { if(Bid-OrderOpenPrice()>Point*TrailingStop) { if(OrderStopLoss()<Bid-Point*TrailingStop) { OrderModify(OrderTicket().3.info/book/print/34 // close position return(0).Violet).Metatrader Development Course http://www. } } } } else // go to short position { // should it be closed? if(isCrossed == 1) { OrderClose(OrderTicket().Ask.OrderLots().Green). return(0). // exit } // check for trailing stop if(TrailingStop>0) { if((OrderOpenPrice()-Ask)>(Point*TrailingStop)) { 69 of 258 6/14/2006 5:36 PM .BidPoint*TrailingStop.OrderOpenPrice().metatrader.OrderTakeProfit().

Note: Our expert advisor will work with EURUSD pairs in 4 Hours timeframe. use the code provided with lesson in www. click Expert Advisors tab and enable these options: 70 of 258 6/14/2006 5:36 PM .metatrader.Mql . } } } } } } return(0).com . To enable it click Tools _ Option menu (or use CTRL+O hotkey). } //+------------------------------------------------------------------+ Note: don’t copy and paste the code above because it warped and will not work for you.Ask+Point*TrailingStop. So compile the expert advisor by pressing F5 and load it in MetaTrader.Metatrader Development Course http://www. Scared? Don’t be scared of the 160 lines you have seen above.Red).info/book/print/34 if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0)) { OrderModify(OrderTicket(). You can test your expert advisor using two methods: 1. OrderTakeProfit().forex-tsd. Test the Expert Advisor: Before studying our expert advisor code we have to be check is it profitable one or not. I promise it’s an easy task.0.Live trading In live trading testing the results are more accurate but you have to spend days (and maybe months) to know is the expert advisor profitable or not. return(0).OrderOpenPrice(). You have to enable the expert advisor to automate your trades. we will know everything about this code line by line. that’s will bring the Options windows (figure 3).

71 of 258 6/14/2006 5:36 PM . Figure 4 – Expert advisor is enabled 2. let’s now bring its window by pressing F6 (Figure 5). I welcome very much the questions and the suggestions. We will know everything about Strategy tester later. When you get the window enter these options: Symbol: EURUSD.info/book/print/34 Enable Expert Advisors Allow live trading And click Ok button Figure 3 – Enabling expert advisor auto trade You will see the Smile symbol beside the expert advisor name which means your expert advisor is working and ready to trade for you (Figure 4)._ See you Coders’ Guru Lesson 14 . Did you wear your coding gloves? Let’s crack. You will see a progress bar and the two tabs (Settings and Journal) became five tabs. Model: Open price only.Strategy Tester: The second method of testing your expert advisor which is less accurate but will not take time is the Strategy tester.Your First Expert Advisor (Part 2) Welcome to the second part of creating Your First Expert Advisor lesson.metatrader. Note: I have to repeat that our expert advisor is for educational purpose only and will not (or aimed to) make profits. Figure 5 – Strategy tester window Now click Start button to start testing the expert advisor.Metatrader Development Course http://www. In the previous part we have taken the code generated by the new program wizard and added our own code which we are going to crack it today line by line. click it to see your profit. We have a lot to say and to do in the next lesson.Mql . I hope you are ready for the challenge. We interested in Report tab (Figure 6). Period: H4 (4 Hours).

double line2) 72 of 258 6/14/2006 5:36 PM . extern double Lots=0.com" //---. //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---//---return(0). extern double TrailingStop=35.1.metatrader.input parameters extern double TakeProfit=250.com | //+------------------------------------------------------------------+ #property copyright "Coders Guru" #property link "http://www.0. } int Crossed (double line1 .mq4 | //| Coders Guru | //| http://www.forex-tsd.info/book/print/34 The code we have: //+------------------------------------------------------------------+ //| My_First_EA.Mql .forex-tsd. } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---//---return(0).0.Metatrader Development Course http://www.

if(Bars<100) { Print("bars less than 100"). } else { return (0). return(0). //up if(line1<line2)current_direction = 2. ticket. } } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---int cnt. 73 of 258 6/14/2006 5:36 PM . //down if(current_direction != last_direction) //changed { last_direction = current_direction. if(line1>line2)current_direction = 1.Mql . longEma. double shortEma.Metatrader Development Course http://www. return (last_direction). } if(TakeProfit<10) { Print("TakeProfit less than 10"). total.metatrader.info/book/print/34 { static int last_direction = 0. static int current_direction = 0.

12345.3. longEma = iMA(NULL. if(ticket>0) { if(OrderSelect(ticket.0.0. return(0).13.PRICE_CLOSE. Bid-TakeProfit*Point.12345.0.8.Lots.Green).OP_SELL.Mql .PRICE_CLOSE.GetLastError()). } if(isCrossed == 2) { ticket=OrderSend(Symbol().0."My EA".Metatrader Development Course http://www.metatrader.0).0.Red).info/book/print/34 return(0). int isCrossed = Crossed (shortEma. total = OrdersTotal().OrderOpenPrice()).Bid.OrderOpenPrice()). if(total < 1) { if(isCrossed == 1) { ticket=OrderSend(Symbol(). return(0).0.MODE_TRADES)) Print("SELL order opened : ".SELECT_BY_TICKET.Ask+TakeProfit*Point.longEma). "My EA". } else Print("Error opening BUY order : ".GetLastError()).0.OP_BUY.MODE_EMA.Lots.MODE_EMA.0.3. } else Print("Error opening SELL order : ". 74 of 258 6/14/2006 5:36 PM .MODE_TRADES)) Print("BUY order opened : ".0).Ask.SELECT_BY_TICKET. // check TakeProfit } shortEma = iMA(NULL. if(ticket>0) { if(OrderSelect(ticket.

cnt<total.0.metatrader. SELECT_BY_POS. MODE_TRADES).Bid.info/book/print/34 } return(0).OrderLots().OrderTakeProfit(). // close position return(0). } for(cnt=0.Violet). } } } } 75 of 258 6/14/2006 5:36 PM . // exit } // check for trailing stop if(TrailingStop>0) { if(Bid-OrderOpenPrice()>Point*TrailingStop) { if(OrderStopLoss()<Bid-Point*TrailingStop) { OrderModify(OrderTicket().Green).cnt++) { OrderSelect(cnt.Metatrader Development Course http://www. return(0).OrderOpenPrice().BidPoint*TrailingStop. if(OrderType()<=OP_SELL && OrderSymbol()==Symbol()) { if(OrderType()==OP_BUY) // long position is opened { // should it be closed? if(isCrossed == 2) { OrderClose(OrderTicket().Mql .3.

info/book/print/34 else // go to short position { // should it be closed? if(isCrossed == 1) { OrderClose(OrderTicket(). } } } } } } return(0). return(0).3. OrderTakeProfit().OrderOpenPrice(). } //+------------------------------------------------------------------+ The idea behind our expert advisor.OrderLots(). Before digging into cracking our code we have to explain the idea behind our expert 76 of 258 6/14/2006 5:36 PM . // exit } // check for trailing stop if(TrailingStop>0) { if((OrderOpenPrice()-Ask)>(Point*TrailingStop)) { if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0)) { OrderModify(OrderTicket().Metatrader Development Course http://www. // close position return(0).0.Ask.Mql .metatrader.Violet).Ask+Point*TrailingStop.Red).

Mql .0. 77 of 258 6/14/2006 5:36 PM . Our order (buy or sell) will automatically be closed too when the Take profit or the Stop loss points are reached. let’s see it.Metatrader Development Course http://www. We use two EMA indicators.metatrader.input parameters extern double TakeProfit=250. the first one is the EMA of 8 days (sort EMA) and the second one is the EMA of 13 days (long EMA). extern double Lots=0.info/book/print/34 advisor.1. the direction of each lines will determine the order type: If the short EMA is above the long EMA will buy (long). We will know how we implemented the idea of Trialing stop later in this lesson. extern double TrailingStop=35. they are for educational purpose only. If the short EMA is below the long EMA we will sell (short). Entering (Open): Our expert advisor will enter the market when the short EMA line crosses the long EMA line.0. Exiting (Close): Our expert advisor will close the buy order when the short EMA crosses the long EMA and the short EMA is below the long EMA. Any expert advisor has to decide when to enter the market and when to exit. We will open only one order at the same time. Now let’s resume our code cracking. Modifying: Beside entering (opening) and exiting (closing) the market (positions) our expert advisor has the ability to modify existing positions based on the idea of Trailing stop point. Note: using those EMAs or any thought in this lesson is not a recommendation of mine. And will close the sell order when the short EMA crosses the long EMA and the short EMA is above the long EMA. And the idea behind any expert advisor is what the entering and exiting conditions are? Our expert advisor is a simple one and the idea behind it is a simple too. //---. In the above lines we have asked the wizard to declare three external variables (which the user can set them from the properties window of our expert advisor).

this is useful to minimize your lose when the market going against you. //down if(current_direction != last_direction) //changed { last_direction = current_direction. _ The exit point must be set above the current market price. Trailing Stop It’s a kind of stop loss order that is set at a percentage level below (for a long position) or above (for a short position) the market price. static int current_direction = 0. instead of below. Take profit: It’s similar to stop lose in that it’s a limit point you set to your order when reached the order will be closed There are. double line2) { static int last_direction = 0.info/book/print/34 The three variables are double data type. The price is adjusted as the price fluctuates. We will talk about this very important concept later in this lesson. I have to pause again to tell you a little story about those variables. however. Stop losses points are always set below the current asking price on a buy or above the current bid price on a sell. two differences: _ There is no “trailing” point. //up if(line1<line2)current_direction = 2.Metatrader Development Course http://www.Mql . Stop loss: It’s a limit point you set to your order when reached the order will be closed. return (last_direction). We have initialized them to default values (the user can change these values from the properties window. if(line1>line2)current_direction = 1. } 78 of 258 6/14/2006 5:36 PM .metatrader. but it recommended to leave the defaults). Figure 1 – Setting Stop loss and Take profit points int Crossed (double line1 .

metatrader. but you can place it anywhere else. Let’s see how did we write it? int Crossed (double line1 .Mql . The place of the function doesn't matter. _ It will return 1 if the direction has changed (the lines crossed each others) and the first line is above the second line. The first parameter is the value of the first line we want to monitor (the short EMA in our case) and the second parameter is the value of the second we want to (the long EMA). sell. } } As I told you before. _ It will return 0 if there’s no change happened in the last directions saved. it means we want to create Crossed function which takes two double data type parameters and returns an integer. I placed it above start() function. The Crossed function takes two double values as parameters and returns an integer. buy-close and sell-close). You have to declare the function before using (calling) it. For this goal we have created the Crossed function. the idea behind our expert advisor is monitor the crossing of the short EMA and the long EMA lines. double line2) The above line is the function declaration. static int last_direction = 0. Note: You can use this function in your coming expert advisor to monitor any two lines and get the crossing direction. The function will monitor the two lines every time we call it by saving the direction of the two lines in static variables to remember their state between the repeated calls. 79 of 258 6/14/2006 5:36 PM .Metatrader Development Course http://www. And getting the direction of the crossing (which line is above and which line is below) which will determine the type of the order (buy. _ It will return 2 if the direction has changed (the lines crossed each others) and the first line is below the second line.info/book/print/34 else { return (0). When you call this function you have to pass to it two double parameters and it will return an integer to you.

return (last_direction). last_direction = current_direction. and we will know a lot about the very important trading functions.info/book/print/34 static int current_direction = 0.Mql . I welcome very much the questions and the suggestions. In the coming part of this lesson we will know how did we call the function._ 80 of 258 6/14/2006 5:36 PM . Our program will call this function in its start() function body and use the returned value to determine the appropriate action. else { return (0). This value will be 1 if the first line is above the second line and 2 if the first line is below the second line. Here we declared two static integers to hold the current and the last direction of the two lines. } Else (last_direction is equal current_direction) there’s no change in the lines direction and we have to return 0. if(current_direction != last_direction) //changed In this line we compare the two static variables to check for changes between the last call of our function and the current call.metatrader.Metatrader Development Course http://www. To that day I hope you the best luck. we have initialized them to 0 because we don’t want them to work in the first call to the function (if they worked in the first call the expert advisor will open an order as soon as we load it in the terminal). In this case (last_direction not equal current_direction) we have to reset our last_direction by assigning to it the value of the current_direction. If last_direction not equal current_direction that’s mean there’s a change happened in the direction. We are going to use these variables (they are static variables which means they save their value between the repeated calls) to check if there’s a change in the direction of the lines or not. And we will return the value of the last_direction.

//+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---//---return(0). I hope you have cleared your mind for our discovering mission.metatrader.mq4 | //| Coders Guru | //| http://www.0. Today we will continue cracking the remaining code of the expert advisor. } 81 of 258 6/14/2006 5:36 PM .Metatrader Development Course http://www.forex-tsd. extern double Lots=0.input parameters extern double TakeProfit=250. And in the Appendix 2 we have studied the Trading Functions which we will use some of them today in our expert advisor.Mql .com" //---.com | //+------------------------------------------------------------------+ #property copyright "Coders Guru" #property link "http://www.forex-tsd.0. extern double TrailingStop=35. we have introduced our expert advisor and knew the idea behind it. The code we have: //+------------------------------------------------------------------+ //| My_First_EA.info/book/print/34 See you Coders’ Guru Lesson 15 .1.Your First Expert Advisor (Part 3) In the previous two parts of this lesson.

} else { return (0).Metatrader Development Course http://www. if(line1>line2)current_direction = 1. return (last_direction). static int current_direction = 0. } int Crossed (double line1 . double line2) { static int last_direction = 0. //up if(line1<line2)current_direction = 2.Mql . } } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---- 82 of 258 6/14/2006 5:36 PM .metatrader.info/book/print/34 //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---//---return(0). //down if(current_direction != last_direction) //changed { last_direction = current_direction.

} if(TakeProfit<10) { Print("TakeProfit less than 10"). } if(isCrossed == 2) 83 of 258 6/14/2006 5:36 PM .8. if(Bars<100) { Print("bars less than 100").0.0. double shortEma. "My EA". return(0).0.MODE_EMA.Mql . total = OrdersTotal().Ask+TakeProfit*Point. longEma = iMA(NULL. ticket.Ask. } else Print("Error opening BUY order : ". if(total < 1) { if(isCrossed == 1) { ticket=OrderSend(Symbol().OrderOpenPrice()).PRICE_CLOSE.13.0. return(0). if(ticket>0) { if(OrderSelect(ticket.0).longEma).MODE_EMA.3.Metatrader Development Course http://www.MODE_TRADES)) Print("BUY order opened : ". longEma.Lots.metatrader.Green).0. int isCrossed = Crossed (shortEma.OP_BUY.SELECT_BY_TICKET.PRICE_CLOSE.GetLastError()).0).info/book/print/34 int cnt.12345. total.0. return(0). // check TakeProfit } shortEma = iMA(NULL.

SELECT_BY_POS. if(ticket>0) { if(OrderSelect(ticket.metatrader.cnt<total.Bid.cnt++) { OrderSelect(cnt. // close position return(0).Bid. } else Print("Error opening SELL order : ".MODE_TRADES)) Print("SELL order opened : ". } for(cnt=0. } return(0).OrderLots().OP_SELL.Lots.SELECT_BY_TICKET. if(OrderType()<=OP_SELL && OrderSymbol()==Symbol()) { if(OrderType()==OP_BUY) // long position is opened { // should it be closed? if(isCrossed == 2) { OrderClose(OrderTicket().Violet).GetLastError()).3. return(0).12345.0.0.Red). // exit } // check for trailing stop if(TrailingStop>0) { if(Bid-OrderOpenPrice()>Point*TrailingStop) 84 of 258 6/14/2006 5:36 PM .OrderOpenPrice()).3. Bid-TakeProfit*Point.info/book/print/34 { ticket=OrderSend(Symbol()."My EA". MODE_TRADES).Metatrader Development Course http://www.Mql .

info/book/print/34 { if(OrderStopLoss()<Bid-Point*TrailingStop) { OrderModify(OrderTicket().Green).BidPoint*TrailingStop.OrderOpenPrice().Violet). } 85 of 258 6/14/2006 5:36 PM . } } } } else // go to short position { // should it be closed? if(isCrossed == 1) { OrderClose(OrderTicket().OrderTakeProfit().OrderLots(). return(0).Mql . // exit } // check for trailing stop if(TrailingStop>0) { if((OrderOpenPrice()-Ask)>(Point*TrailingStop)) { if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0)) { OrderModify(OrderTicket().Metatrader Development Course http://www. // close position return(0).Ask+Point*TrailingStop.Ask.OrderOpenPrice().0.Red).metatrader.0. return(0). OrderTakeProfit().3.

int ticket. int total. longEma. Note: To declare multi variables in a single line you start the line with the declaration keyword which indicates the type of the variables then separate the variables identifiers (names) with comma. As you remember (I hope) from the previous part we uses the Crossing of short and long EMAs as buying and selling conditions and as closing conditions too. In this line we declared three integer type variables. double shortEma. We will use these variables to hold the value of short EMA and long EMA.Mql . if(Bars<100) { Print("bars less than 100").info/book/print/34 } } } } } return(0). 86 of 258 6/14/2006 5:36 PM . ticket. Again. And we will use the total variable to hold the number of already opened orders. We will use the cnt variable as a counter in our “opened orders checking loop”. } //+------------------------------------------------------------------+ int cnt. You can divide the above line into three lines like that int cnt. We will use the ticket variable to hold the ticket number returned by OrderSend function. We used one line to declare the three of them because they are the same type (You can’t use a single line declaration with dissimilar data types). return(0). we used a single line to declare two double variables.Metatrader Development Course http://www.metatrader. total.

That’s the way we refuse to work with less than 100 bars on the chart. Figure 1 – Experts log if(TakeProfit<10) { Print("TakeProfit less than 10").0). We have got the number of bars on the chart using the Bars function and checked this number to find is it less than 100 or not. We want now to calculate the short and long EMAs of the current bar. longEma = iMA(NULL.metatrader. The TakeProfit variable is an external variable and that’s mean the user can change its default value from the expert advisor properties windows.0).0. // check TakeProfit } We don’t want too to work with insufficient value of TakeProfit.0.MODE_EMA.PRICE_CLOSE. shortEma = iMA(NULL.0.MODE_EMA. Well. If it’s less than 100 we will do two things: We will tell the user what’s the wrong by writing this message to the Experts log "bars less than 100" (Figure 1).PRICE_CLOSE. We use the MQL4 built-in technical indicator function iMA which calculates the moving average indicator.8.info/book/print/34 } We want to work with a normal chart and we assume that the normal chart must have more than 100 bars. If it’s less than 10 we will inform the user what’s the wrong by printing him the message "TakeProfit less than 10". 87 of 258 6/14/2006 5:36 PM .Metatrader Development Course http://www. Then we will terminate the start function by the line retrun(0). That’s because the insufficient numbers of bars will not enable or EMA indicators to work right. We want to protect the user of our expert advisor from his bad choices. everything is OK. return(0).Mql .0. and we will terminate the start function by return(0) statement. We assume that any value less than 10 for the TakeProfi variable will be bad choice and for that we have checked the TakeProfit value the user set to find is it less than 10 or not.13. the bars on the chart were more than 100 bars and the value of TakeProfit the user supplied was more than 10.

metatrader. PERIOD_H1 60 1 hour. If you want to use the current symbol use NULL as a parameter. int shift) Description: The iMA function calculates the moving average indicator and returns its value (double data type). PERIOD_MN1 43200 Monthly. You can use one of these time frame values: Constant Value Description PERIOD_M1 1 1 minute. PERIOD_H4 240 4 hour. PERIOD_M15 15 15 minutes. 88 of 258 6/14/2006 5:36 PM . PERIOD_W1 10080 Weekly. Note: You can use the integer representation of the period or its constant name. Note: A moving average is an average price of a certain currency over a certain time interval (in days. Parameters: This function takes 7 parameters: string symbol: The symbol name of the currency pair you trading (Ex: EURUSD and USDJPY). int applied_price. If you want to use the current timeframe.info/book/print/34 I have to pause here for a couple of minutes to tell you more details about iMA function. int timeframe: The time frame you want to use for the moving average calculation. PERIOD_M30 30 30 minutes. hours. minutes etc) during an observation period divided by these time intervals. int ma_shift. iMA: Syntax: double iMA( string symbol. PERIOD_D1 1440 Daily. use 0 as a parameter.Mql . PERIOD_M5 5 5 minutes.Metatrader Development Course http://www. 0 (zero) 0 Time frame used on the chart. int period. int ma_method. int timeframe.

(high+low+close)/3.0. PRICE_LOW 3 Low price. PRICE_OPEN 1 Open price. is equal to iMA(NULL. (high+low)/2.0. the line: iMA(NULL.Mql .metatrader. It can be one of these values: Constant Value Description MODE_SMA 0 Simple moving average. PRICE_HIGH 2 High price. But it's recommended to use the constant name to make your code clearer. PERIOD_H4. int ma_shift: The number of the bars you want to shift the moving average line relative to beginning of the chart: 0 means no shift (Figure 2) A positive value shifts the line to right (Figure 3) A negative value shifts the line to left (Figure 4) int ma_method: The moving average method you want to use for the moving average calculation.MODE_EMA.0).info/book/print/34 For example.0). It can be one of these values: Constant Value Description PRICE_CLOSE 0 Close price. MODE_EMA 1 Exponential moving average.PRICE_CLOSE.8. 89 of 258 6/14/2006 5:36 PM . int applied_price: The price you want to use for the moving average calculation.8. MODE_LWMA 3 Linear weighted moving average. PRICE_MEDIAN 4 Median price. int period: The number of days you want to use for the moving average calculation.PRICE_CLOSE.240.Metatrader Development Course http://www. MODE_SMMA 2 Smoothed moving average. PRICE_TYPICAL 5 Typical price.MODE_EMA.

It will return 1 if the direction has changed (the lines crossed each others) and the first line is above the second line. Note: The Crossed function takes two double values as parameters and returns an integer.0. Which we can briefly call it 13EMA int isCrossed = Crossed (shortEma.0). Which we can briefly call it 8EMA And assigned to the variable longEma the value of: 13 days closing price based exponential moving average of the current bar. Here we declared an integer variable isCrossed to hold the return value of the function Corssed.0). It will return 2 if the direction has changed (the lines crossed each others) and the first line is below the second line. We assigned to the variable shortEma the value of: 8 days closing price based exponential moving average of the current bar. int shift: The number of bars (relative to the current bar) you want to use for the moving average calculation.MODE_EMA. longEma = iMA(NULL. Use 0 for the current bar. It will return 0 if there’s no change happened in the last directions saved.Mql . Now you know what the above lines means.longEma). The first parameter is the value of the first line we want to monitor (the short EMA in our case) and the second parameter is the value of the second we want to (the long EMA).Metatrader Development Course http://www.8.0.MODE_EMA. (high+low+close+close)/4. We will use this value to open and close orders.13.0. total = OrdersTotal(). The function will monitor the two lines every time we call it by saving the direction of the two lines in static variables to remember their state between the repeated calls.info/book/print/34 PRICE_WEIGHTED 6 Weighted close price.metatrader. Figure 2 : ma_ shift = 0 Figure 3: ma_shift = 10 Figure 4: ma_shift = -10 shortEma = iMA(NULL.0.PRICE_CLOSE. if(total < 1) 90 of 258 6/14/2006 5:36 PM .PRICE_CLOSE.

double price.0. It returns the ticket number of the order if succeeded and -1 in failure. Syntax: int OrderSend( string symbol.Ask+TakeProfit*Point. int slippage. string comment=NULL.SELECT_BY_TICKET. datetime expiration=0. double stoploss. Note: The OrderSend function used to open a sell/buy order or to set a pending order. Note: The OrdersTotal function returns the number of opened and pending orders. } We assigned the OrdersTotal return value to the variable total.GetLastError()). if(isCrossed == 1) { ticket=OrderSend(Symbol(). color arrow_color=CLR_NONE) 91 of 258 6/14/2006 5:36 PM . double takeprofit.Lots. "My EA". int cmd. The if block of code will work only if the total value is lesser than 1 which means there's no already opened order.Metatrader Development Course http://www.metatrader.info/book/print/34 { ……. int magic=0.Ask. If this number is 0 that means there are no orders (market or pending ones) has been opened.0. } In the case the shortEma crossed the longEma and the shortEma is above the longEma we will buy now. if(ticket>0) { if(OrderSelect(ticket.OrderOpenPrice()).MODE_TRADES)) Print("BUY order opened : ".12345.3. We are using the OrderSend function to open a buy order.Green). return(0).Mql . } else Print("Error opening BUY order : ". double volume.OP_BUY. Please review appendix 2 Then we checked this number (total) to find if there was already opened orders or not.

takeprofit: We multiplied the TakeProfit value the user has been supplied by the return value of the Point function and added the result to the Ask price.Metatrader Development Course http://www.Mql .info/book/print/34 Please review appendix 2 These are the parameters we used with our OrderSend function: symbol: We used the Sybmol function to get the symbol name of the current currency and passed it to the OrderSend function. slippage: We used 3 for the slippage value.01 So. expiration: We didn't set an expiration date to our order. cmd: We used OP_BUY because we want to open a Buy position. stoploss: We used 0 for stoploss which mean there's no stoploss for that order. comment: We used "My EA" string for the comment magic: We used the number 12345 for the order magic number.metatrader. so we used 0. Note: Point function returns the point size of the current currency symbol.0001 and if you trade EURJPY the point value should be . price: We used the Ask function to get the current ask price and passed it to the OrderSend function. you have to convert your stoploss and takeprofit values to points before using them with OrderSend or OrderModify functions. arrow_color: 92 of 258 6/14/2006 5:36 PM . For example: if you trade EURUSD the point value = . volume: We used the Lots value that the use has been supplied.

12345.GetLastError()).OP_SELL. the opposite scenario.Red).Mql . if(isCrossed == 2) { ticket=OrderSend(Symbol().0."My EA". } Here. Note: For more details about OrderSelect and OrderOpenPrice.3.metatrader. return(0).Lots. plus the error number returned by the function GetLastError. } else Print("Error opening SELL order : ".Bid. we have to tell the user this bad news by printing him the message: "Error opening BUY order : ". Can you guess what the differences 93 of 258 6/14/2006 5:36 PM . the shortEma crossed the longEma and the shortEma is below the longEma we will sell now. the OrderSend returned a proper ticket number (greater than 0) and the OrderSelect successfully selected the order. so we check it with this line: if(ticket>0) We used the OrderSelect function to select the order by its ticket number that's before we used the OrderOpenPrice function which returns the open price of the selected order. Everything is OK.MODE_TRADES)) Print("SELL order opened : ". We use the OrderSend function to open a Sell order.OrderOpenPrice()).0.SELECT_BY_TICKET. if the OrderSend function returned -1 which means there was an error opening the order. It's the good time to tell the user this good new by printing to him the message "BUY order opened : " plus the opened price of the order. Bid-TakeProfit*Point. And in this case we have to terminate the start function by using return(0).info/book/print/34 We set the color of opening arrow to Green (Because we like the money and the money is green) The OrderSend function will return the ticket number of the order if succeeded.Metatrader Development Course http://www. if(ticket>0) { if(OrderSelect(ticket. please review appendix 2 Else.

We used the OrderSelect to select the order before using OrderOpenPrice. magic is the same. Else. slippage is the same. Everything is OK. arrow_color: We set the color of opening arrow to Red (Because we like the money and the money is green but we want a different color for selling position).Metatrader Development Course http://www.info/book/print/34 between the Buy parameters and Sell parameters in OrderSend are? Right! You deserve 100 pips as a gift. plus the error number and terminate the start 94 of 258 6/14/2006 5:36 PM . We can briefly repeat what will happen after calling the OrderSend with the above parameters: The OrderSend returns the ticket number if succeeded. we tell the user this good news by printing to him the message "Sell order opened : " plus the opened price of the order. These parameters have been changed (that's why you've got the gift): cmd: We used OP_SELL because we want to open a Sell position. volume is the same. comment is the same. We check this number to find is it greater than 0 which means no errors.Mql . expiration is the same. if the OrderSend function returned -1 we tell the user this bad news by printing him the message: "Error opening SELL order : ".metatrader. price: We used the Bid function to get the current bid price and passed it to the OrderSend function. takeprofit: We multiplied the TakeProfit value the user has been supplied by the return value of the Point function and subtracted the result from the Bid price. stoploss is the same. These parameters haven't been changed: symbol is the same.

metatrader.. _ Right! } If the shorEma crossed the longEma upward we open Buy order..I've noticed that there's a line after the last if block of code you have just explained above. I hope you enjoyed the lesson. In the coming part we will crack the remaining of the code and will discuss in details the MetaTrader Strategy Tester. } return(0).. Now we are ready to open Buy and Sell positions.info/book/print/34 function by using return(0). .. I welcome very much your questions and suggestions..Mql .Wait a minute! (You said). } if(isCrossed == 2) { . ... What if they haven't been crossed yet? That's the job of this line. .Where? (I'm saying). (In the case that isCrossed not equal 1 or 2).. If the shorEma crossed the longEma downward we open Sell order. Coders’ Guru 95 of 258 6/14/2006 5:36 PM . . Yes! Great but I have no pips to gift you this time. We terminate the start function if there was no crossing.Metatrader Development Course http://www. Look carefully to these blocks (braces): if(total < 1) { if(isCrossed == 1) { .Here it's: return(0).

AccountCredit()). The profit are loss are calculated only for the closed trades. AccountCompany Syntax: 96 of 258 6/14/2006 5:36 PM . see the examples! Example: Print("Account balance = ". demo account or a real one. so the floating profit/loss is not calculated within the balance! Note: All of the Account Information function don't take parameters.metatrader. the current account margin value and the current account total profit.loss (of closed trades).Metatrader Development Course http://www. AccountBalance Syntax: double AccountBalance() Description: The AccountBalance function returns the balance amount (how much money) of the current account. The calculation of the balance amount is the calculation of the starting capital + profit or .Mql . The account information functions are very useful for applying Money Management techniques by calculating the state of your account balance and margin etc. Let's study these functions in details. AccountCredit Syntax: double AccountCredit() Description: The AccountCredit function returns the credit value of the current account Example: Print("Account number ". Regardless the type of your account. it's very important to have a set of functions to access this account information.info/book/print/34 Account Information functions Hi folks. for example the current account balance. AccountBalance()).

97 of 258 6/14/2006 5:36 PM . the Conversion functions. the same as the name you find in the About dialog which you can open from Help menu. for example USD if you paid your account in US dollars. AccountCompany()).AccountEquity()). AccountCurrency()). Today we are going to talk about a very important set of MQL4 functions. The calculation of the balance equity is the calculation of the starting capital + profit or . Example: Print("Account company name ".Mql .metatrader. The profit are loss are calculated for the opened and the closed trades. Conversion functions Hi folks. Example: Print("Account equity = ". AccountCurrency Syntax: string AccountCurrency() Description: The AccountCurrency function returns the name of the currency you used to open your account with the brokerage company.losses (of all trades).info/book/print/34 string AccountCompany() Description: The AccountCompany function returns the brokerage company name you opened your current account with. Example: Print("account currency is ".Metatrader Development Course http://www. AccountEquity Syntax: double AccountEquity() Description: The AccountEquity function returns the equity amount of the current account.

It will not problem for us if we are going to use this time as a datatime format for example adding to 2 hours to it or substracting it from the local time. In the above code you have assigned an integer to a string variable. not 110 but you will get 10010 (Figure 1). Implicit conversions: Beside the conversions functions we are going to study I have to mention that MQL4 will make implicit conversions from a data type to other data type when you assign a wrong value for this data type. That's because MQL4 has converted the 100 to string and 10 to string then added them to each others as strings. it returns this time in datetime format. Figure 1 Let's study the conversion function available in MQL4! CharToStr: Syntax: 98 of 258 6/14/2006 5:36 PM . For example: When we use the CurTime() function which returns the current server time. If you don't sure of that add this line: Alert(var1+10).info/book/print/34 Why should I use Conversion functions? In many of situations you have a variable in a specific format and you want to use it in another format. What do you think you'll get? No. the Alert() can't convert automatically from datetime data type to string data type which we want the user to see. But if we want to display this time to the user using the Alert() function we will face a problem.Metatrader Development Course http://www. For example: string var1 = 100. In this case we have to use the conversion function TimeToStr(). Alert(var1). MQL4 will convert the number 100 from integer to string.Mql .metatrader.

4). } DoubleToStr: Syntax: string DoubleToStr( double value. int digits) Description: The DoubleToStr function converts from double data type to string type. // value is 1. cnt < 255 . it converts the ASCII char code passed to it to string. it can be ranged from 0 (no digits) to 8 (8 digits). it converts the double value passed to the function to string with the number of digits passed to the function.2346 NormalizeDouble: 99 of 258 6/14/2006 5:36 PM .Metatrader Development Course http://www.info/book/print/34 string CharToStr( int char_code) Description: The CharToStr function converts from Char type to string type. Example: for (int cnt = 1 . Parameters: This function takes two parameters: double value The double value you want to convert it to string. Example: string value=DoubleToStr(1.Mql . cnt++) { Print("ASCII code: " + cnt + ": " + CharToStr(cnt)).metatrader.2345678. int digits The number of digits you want the function to use in converting the double value to string. Parameters: This function takes only one parameter: int char_code The ASCII char code of the character you want to convert it to string.

info/book/print/34 Syntax: double NormalizeDouble( double value. // output: 1. Example: double value=1.5)). Print(NormalizeDouble(value.2345678"). // output: 1. Parameters: This function takes only one parameter: string value The string value you want convert it to double value.2346 100 of 258 6/14/2006 5:36 PM .2345678. it converts the string value passed to the function to a double.Mql .2346 StrToDouble: Syntax: double StrToDouble( string value) Description: The StrToDouble function converts from string data type to double type. Example: double value=StrToDouble("1. int digits The number of digits you want the function to use in rounding the double value. It's like DoubleToStr function but it returns double value instead of string. int digits) Description: The NormalizeDouble function rounds the double value passed to it to the number of digits passed. it can be ranged from 0 (no digits) to 8 (8 digits). Parameters: This function takes two parameters: double value The double value you want to round it.metatrader.Metatrader Development Course http://www. Print(value).

8.Metatrader Development Course http://www. var1=StrToTime("17:35").info/book/print/34 StrToInteger: Syntax: int StrToInteger( string value) Description: The StrToInteger function converts from string data type to integer type.dd hh:mi" Parameters: This function takes only one parameter: string value The string value you want convert it to datatime data type.Mql .8.mm. var1=StrToTime("2003. This string have in one of these formats: "yyyy.12").dd hh:mi" "hh:mi" "yyyy. Example: double value=StrToInteger("1999").mm. the string value passed to the function must be in the format: "yyyy. Parameters: This function takes only one parameter: string value The string value you want convert it to integer value.metatrader.mm. StrToTime: Syntax: datetime StrToTime( string value) Description: The StrToTime function converts from string data type to datetime data type. // returns with current date var1=StrToTime("2003. // returns with midnight time "00:00" 101 of 258 6/14/2006 5:36 PM .dd" Example: datetime var1. it converts the string value passed to the function to an integer. Print(value).12 17:35").

It can be one or combination of these modes: TIME_DATE the result will be in the format "yyyy. what the string format the function will return. It starts from 00:00 January 1.mm.metatrader.Metatrader Development Course http://www.dd". TIME_MINUTES the result will be in the format"hh:mi". int mode Optional parameter determine the mode of conversion. Date and Time Functions Hi folks.mm.Mql . TIME_SECONDS the result will be in the format "hh:mi:ss".TIME_DATE|TIME_SECONDS). int mode=TIME_DATE|TIME_MINUTES) Description: The TimeToStr function converts from datetime data type to string data type. Parameters: This function takes two parameters: datetime value The datatime value you want to convert it to string. 1970. The default value is TIME_DATE|TIME_MINUTES which means the result will be in the format "yyyy.dd hh:mi". 102 of 258 6/14/2006 5:36 PM . the return string value will be in the format "yyyy.dd hh:mi". Example: strign var1=TimeToStr(CurTime().mm.info/book/print/34 TimeToStr: Syntax: string TimeToStr( datetime value.

Between the two signal quotations you write a character line consisting of 6 parts for value of year. let's give the date and time functions a study trip: CurTime: Syntax: datetime CurTime( ) Description: 103 of 258 6/14/2006 5:36 PM .1980 12' //equal to D'1980. There are a lot of useful usages of the date and time function that can't be listed here. You set the datetime variable by using the keyword (D) followed by two signal quotations (').01.19 12:00:00' D'01.2004 00:00:00' We use the keyword datetime to create a datetime variable.10.1980 12:30:27' D'19.01. minutes. Another example with the aid of these functions you can know how long a position has been opened by subtracting the order opened time (returned by the function OrderOpenTime) from the current time (returned by he function CurTime which we are going to study it later).10.01. 2037.01 00:00' // New Year D'1980.07. datetime constant can vary from Jan 1.metatrader.19 12:00:00'.19 12:30:27' D'19. month.07. 1970 to Dec 31. which holds a date and time data. As an example to show the importance of these function you can manage the time your expert advisor will enter the market and exist from the market.info/book/print/34 We are going to study today a very important set of MQL4 functions. the Date and Time Functions.Mql . which are the functions that returns the local (your computer) and server time.22 04:30:00'.07. date.07. hour. For example: D'2004.Metatrader Development Course http://www. datetime dt1= D'2005. datatime data type: datetime data type is a special MQL4 data type.2004' //equal to D'01. Before we dig into studying the date and time function we have to review the datetime data type because it's the cornerstone of understanding how the date and time is calculating in MQL4. Now. and seconds. For example: datetime dtMyBirthDay= D'1972.

31) of the last known server time. 3.info/book/print/34 The CurTime function returns the current server time.. Parameters: This function takes no parameters and return datetime value. DayOfWeek: Syntax: int DayOfWeek( ) Description: The DayOfWeek function returns the current day of the week of the last know server time: 104 of 258 6/14/2006 5:36 PM . Example: if(CurTime()-OrderOpenTime()<360) return(0). 2. Day: Syntax: int Day( ) Description: The Day function returns the current day of the month (1. Example: if(Day()<5) return(0).. The return value of the CurTime function is a datetime data type and it's the number of seconds elapsed from 00:00 January 1. Parameters: This function takes no parameters and return integer value. 4..metatrader.Metatrader Development Course http://www.Back Testing? In the testing mode the server time will be modeled by the tester.. .Mql . 1970. The day is modeled in the testing mode. What if you used this function (and all the date & time functions) in the testing mode . it's not always the exact current server time but it's the last know server time that the terminal has been retrieved it from the server with the last price quotation.

365 (366) ) of the last know server time.. Parameters: This function takes no parameters and return integer value. Example: if(DayOfYear()==245) return(true). Hour: Syntax: int Hour( ) Description: 105 of 258 6/14/2006 5:36 PM . . 2.Mql . if(DayOfWeek()==0 || DayOfWeek()==6) return(0). 3. The day of year is modeled in the testing mode. Parameters: This function takes no parameters and return integer value.Metatrader Development Course http://www. DayOfYear: Syntax: int DayOfYear( ) Description: The DayOfYear function returns the current day of the year (1.info/book/print/34 0 = Sunday 1 = Monday 2 = Tuesday 3 = Wednesday 4 = Thursday 5 = Friday 6 = Saturday The day of week is modeled in the testing mode.metatrader.. Example: // does not work on holidays..

106 of 258 6/14/2006 5:36 PM . Parameters: This function takes no parameters and return datetime value. Example: if(LocalTime()-OrderOpenTime()<360) return(0).Mql .Metatrader Development Course http://www. Example: if(Hour()>=12 || Hour()<17) return(true). Note: The hour returned by the Hour function is the hour of the moment the program start and will not change during the execution of the program. Parameters: This function takes no parameters and return integer value. The minute is modeled in the testing mode.. ..metatrader. 23 ) of the last know server time. LocalTime: Syntax: datetime LocalTime( ) Description: The LocalTime function returns the current local computer time. 2. 1. The local time is modeled in the testing mode as well as the server time. The hour is modeled in the testing mode. . 1. The return value of the LocalTime function is a datetime data type and it's the number of seconds elapsed from 00:00 January 1. 59 ) of the last know server time. Like the Hour function the minute returned by the Minute function is the minute of the moment the program start and will not change during the execution of the program..info/book/print/34 The Hour function returns the current hour (0.. 1970. Minute: Syntax: int Minute( ) Description: The Minute function returns the current minute (0. 2...

info/book/print/34 Parameters: This function takes no parameters and return integer value. 1..metatrader. 59 ) of the minute of the last know server time. The month is modeled in the testing mode. .Mql . Seconds: Syntax: int Seconds( ) Description: The Seconds function returns the current seconds (0. The minute is modeled in the testing mode.. Parameters: This function takes no parameters and return integer value.. Month: Syntax: int Month( ) Description: The Month function returns the current month (0.. Parameters: This function takes no parameters and return integer value. 1. 2. 3. Example: if(Minute()<=15) return("first quarter"). Example: if(Month()<=5) return("the first half year"). Like the Hour and the Minute functions the seconds returned by the Seconds function is the second of the moment the program start and will not change during the execution of the program.Metatrader Development Course http://www. Example: 107 of 258 6/14/2006 5:36 PM . 12 ) of the last know server time.. 2. ..

It extracts the day of the month from the given date Parameters: datetime date: The date (datetime data type) you want to extract the day of the month from. Year: Syntax: int Year( ) Description: The Year function returns the current year of the last know server time. The year is modeled in the testing mode. 3. TimeDay: Syntax: int TimeDay(datetime date) Description: The TimeDay function returns the day of the month (1..31'). Example: // return if the date is within the range from 1 Jan.metatrader.Mql .info/book/print/34 if(Seconds()<=15) return(0). Example: int day=TimeDay(D'2003.. if(Year()==2006 && Month()<5) return(0). // day is 31 TimeDayOfWeek: 108 of 258 6/14/2006 5:36 PM ..12. to 30 Apr. . 2006. 2.Metatrader Development Course http://www. 31) of the given date. Parameters: This function takes no parameters and return integer value.

11. It extracts the day of the week from the given date Parameters: datetime date: The date you want to extract the day of the week from.1..Tuesday TimeDayOfYear: Syntax: int TimeDayOfYear(datetime date) Description: The TimeDayOfYear function returns the day of the year (1. 6) of the given date. . TimeHour: Syntax: 109 of 258 6/14/2006 5:36 PM .metatrader.2').. 365 (366)) of the given date. It extracts the day of the year from the given date Parameters: datetime date: The date you want to extract the day of the year from.. // day is 2 .Mql .info/book/print/34 Syntax: int TimeDayOfWeek(datetime date) Description: The TimeDayOfWeek function returns the day of the week (0.Metatrader Development Course http://www. .. 2. 3. Example: int weekday=TimeDayOfWeek(D'2004.. 2.. Example: int day=TimeDayOfYear(CurTime()).

59) of the given date. TimeMinute: Syntax: int TimeMinute(datetime date) Description: The TimeMinute function returns the minute of the hour (0...1.. 23) of the given date. 2. .Metatrader Development Course http://www. It extracts the minute of the hour from the given date Parameters: datetime date: The date you want to extract the minute of the hour from. 2. 12) of the given date. Example: int m=TimeMinute(CurTime()).. It extracts the 110 of 258 6/14/2006 5:36 PM . . TimeMonth: Syntax: int TimeMonth(datetime date) Description: The TimeMonth function returns the month of the year (1.1. .. It extracts the hours of the day from the given date Parameters: datetime date: The date you want to extract the hour of the day from.info/book/print/34 int TimeHour(datetime date) Description: The TimeHour function returns the hour of the day (0.Mql . 2.. Example: int h=TimeHour(CurTime()).metatrader. 3....

1..Metatrader Development Course http://www. It extracts the seconds of the minute from the given date Parameters: datetime date: The date you want to extract the seconds of the minute from. 2. TimeYear: Syntax: int TimeYear(datetime date) Description: The TimeYear function returns the year of the given date.info/book/print/34 month of the year from the given date Parameters: datetime date: The date you want to extract the month of the year from. 59) of the given date. 111 of 258 6/14/2006 5:36 PM . Example: int m=TimeMonth(CurTime()). TimeSeconds: Syntax: int TimeSeconds(datetime date) Description: The TimeSeconds function returns the seconds of the minute (0. .. Example: if(Seconds()<=15) return(0). It extracts the year from the given date Parameters: datetime date: The date you want to extract the year from.Mql .metatrader..

The most of traders think first in when to buy/sell but the successful ones think first how manage the risk before buying/selling The Money Management briefly is the art of handling the size of the trade Because we are in the development section we are taking another approach of talking about the Money Management.forex-tsd. double TrailingStop=30. HedgingStopLoss=10.info/book/print/34 Example: // return if the date is within the range from 1 Jan. One of the most important keys (if not the most important one) of success trading is the Money Management technique you apply to your trading operations. where you put more money in the good trades and put less money in the bad trades. bool UseStopLoss = false. //+------------------------------------------------------------------+ //| EMA_CROSS_2.com | //+------------------------------------------------------------------+ #property copyright "Coders Guru" #property link "http://www. ContinuesHedging = true. 2006. double double bool bool HedgingTakeProfit=20.com" #define MAGICMA 20060306 //---extern extern extern extern extern extern extern extern Trades limits double TakeProfit=180.EMAs paris extern int ShortEma = 10.. And at the same time how to handle the capital you using in your trading account where you spend more when you have more balance and spend less when you have less balance.Metatrader Development Course http://www. UseHedging = true.forex-tsd.Mql .mq4 | //| Coders Guru | //| http://www. if(Year()==2006 && Month()<5) return(0). to 30 Apr. We have a simple here in MQL4.metatrader. Hope you enjoyed the lesson! Coders Guru Examples: Money Management Hi folks. 112 of 258 6/14/2006 5:36 PM . we are going to talk about a MQL4 code which enable us to apply our Money Managements and Risk controller techniques in the case of writing an expert advisor. The Money Management is how to handle the money you put in one or more trades. //---. double StopLoss=70.

int FromHourTrade = 8. 1). bool UseMoneyManagement = true.0.metatrader. //Use Micro-Account or not int Risk = 10. //Use Money Management or not bool AccountIsMicro = false.0.MODE_EMA. PRICE_CLOSE. //Open trades immediately or wait for cross.Mql . for(int cnt = 0 . cnt++) { OrderSelect(cnt.0. double EmaLongCurrent = iMA(NULL. //down trend if (EmaShortCurrent>EmaLongCurrent)return (2). //10% Time Management bool UseHourTrade = false. else if(Show_Settings && Summarized) Print_Details_Summarized().LongEma. } bool isNewSumbol(string current_symbol) { //loop through all the opened order and compare the symbols int total = OrdersTotal(). double EmaShortCurrent = iMA(NULL.ShortEma. SELECT_BY_POS.Crossing options extern bool ImmediateTrade = true.0. extern bool Show_Settings = true. int ToHourTrade = 18. //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---if(Show_Settings && Summarized == false) Print_Details().0. cnt < total . //Use the originally CounterTrend crossing method or not //---extern extern extern extern //---extern extern extern Money Management double Lots = 1.0. } return (True). PRICE_CLOSE. if (current_symbol == selected_symbol) return (False). //---. MODE_TRADES).LongEma.MODE_EMA.ShortEma. extern bool CounterTrend = true. extern double slippage = 3.0.0. else Comment("").MODE_EMA. 0). } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---//---return(0).Metatrader Development Course http://www. } int Crossed() { double EmaLongPrevious = iMA(NULL. PRICE_CLOSE. //---return(0).info/book/print/34 extern int LongEma = 80. PRICE_CLOSE. double EmaShortPrevious = iMA(NULL. string selected_symbol = OrderSymbol(). //up trend } 113 of 258 6/14/2006 5:36 PM .MODE_EMA. if(ImmediateTrade) { if (EmaShortCurrent<EmaLongCurrent)return (1). 1). extern bool Summarized = false. 0).

if(AccountIsMicro==false) //normal account { if (lotMM < 0. " . else return ("False"). //up trend return (0). + "UseHourTrade=" + BoolToStr(UseHourTrade) + NL.1) lotMM = Lots. } return (lotMM). string NL = "\n".0) + NL.01) lotMM = Lots.metatrader. "AccountIsMicro=" + BoolToStr(AccountIsMicro) + " | ". "UseStopLoss=" + BoolToStr(UseStopLoss) + NL.0) + " | ". "Risk=" + DoubleToStr(Risk.0) + " | "TrailingStop=" + DoubleToStr(TrailingStop. " | ". //Thanks cucurucu if (lotMM > 1.Mql . " | ".0) + " | ". } void Print_Details() { string sComment = "".0) + "%" + NL. sComment sComment sComment sComment sComment sComment = = = = = = sComment sComment sComment sComment sComment sComment + + + + + + sp.0) + "StopLoss=" + DoubleToStr(StopLoss. "ImmediateTrade=" + BoolToStr(ImmediateTrade) + "CounterTrend=" + BoolToStr(CounterTrend) + " | ".0) lotMM = MathCeil(lotMM).0) + " | ". Comment(sComment).5) && (lotMM < 1)) lotMM=0. } string BoolToStr ( bool value) { if(value) return ("True"). } void Print_Details_Summarized() { 114 of 258 6/14/2006 5:36 PM . if (lotMM > 1.5. + "ToHourTrade=" + DoubleToStr(ToHourTrade.Metatrader Development Course http://www. + "UseHourTrade=" + BoolToStr(UseHourTrade) + " | ". sComment = sp. } else //micro account { if (lotMM < 0. "Lots=" + DoubleToStr(Lots.info/book/print/34 if (EmaShortPrevious>EmaLongPrevious && EmaShortCurrent<EmaLongCurrent ) return (1).0) lotMM = MathCeil(lotMM). if (lotMM > 100) lotMM = 100. //down trend if (EmaShortPrevious<EmaLongPrevious && EmaShortCurrent>EmaLongCurrent ) return (2). if (lotMM > 100) lotMM = 100.Bassed on Alex idea! More ideas are coming double LotSize() { double lotMM = MathCeil(AccountFreeMargin() * Risk / 1000) / 100. sp. if ((lotMM > 0. "UseMoneyManagement=" + BoolToStr(UseMoneyManagement) + " | ". //elsewhere } //--. sp. + "FromHourTrade=" + DoubleToStr(FromHourTrade. string sp = "----------------------------------------\n". sComment = sComment sComment = sComment sComment = sComment sComment = sComment sComment = sComment sComment = sComment sComment = sComment if(UseHourTrade) { sComment = sComment sComment = sComment sComment = sComment } else { sComment = sComment } + + + + + + + "TakeProfit=" + DoubleToStr(TakeProfit.

info/book/print/34 string sComment = "". " | ". if(CounterTrend==false) 115 of 258 6/14/2006 5:36 PM .Metatrader Development Course http://www. string sp = "----------------------------------------\n". } if(TakeProfit<10) { Print("TakeProfit less than 10"). " . sp. "MM=" + BoolToStr(UseMoneyManagement) + " | ". + "FHT=" + DoubleToStr(FromHourTrade. if(ImmediateTrade==true) comment = comment + "_Immediate".metatrader. "IT=" + BoolToStr(ImmediateTrade) + " "CT=" + BoolToStr(CounterTrend) + " | | ". total. "L=" + DoubleToStr(Lots. + "UHT=" + BoolToStr(UseHourTrade) + NL.0) + " | "USL=" + BoolToStr(UseStopLoss) + NL. Comment(sComment).Mql . if(Bars<100) { Print("bars less than 100"). ". sComment = sComment sComment = sComment sComment = sComment sComment = sComment sComment = sComment sComment = sComment sComment = sComment if(UseHourTrade) { sComment = sComment sComment = sComment sComment = sComment } else { sComment = sComment } + + + + + + + "TF=" + DoubleToStr(TakeProfit. ticket2.0) + " "TS=" + DoubleToStr(TrailingStop. sComment sComment sComment sComment sComment sComment = = = = = = sComment sComment sComment sComment sComment sComment + + + + + + sp.0) + NL. if(CounterTrend==true) comment = "EMAC_Counter". if(CounterTrend==false) comment = "EMAC_Pro". sComment = sp.0) + " | ". // check TakeProfit } int isCrossed = 0.0) + "%" + NL. } } int cnt. "AIM=" + BoolToStr(AccountIsMicro) + " | ". "R=" + DoubleToStr(Risk. return(0). ticket. string NL = "\n". isCrossed = Crossed (). string comment = "". + "THT=" + DoubleToStr(ToHourTrade.0) + " | ". return(0). + "UHT=" + BoolToStr(UseHourTrade) + " | ". if(ImmediateTrade==false) comment = comment + "Postponed". sp. | ". return(0).0) + "SL=" + DoubleToStr(StopLoss. } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---if (UseHourTrade) { if (!(Hour()>=FromHourTrade && Hour()<=ToHourTrade)) { Comment("Time for trade has not come yet!").

} if(UseMoneyManagement==true) Lots = LotSize().Bid.Mql .MODE_TRADES)) Print("SELL order opened : ".Bid.OP_SELL.cnt++) { OrderSelect(cnt.slippage.MAGIC if(ticket>0) { if(OrderSelect(ticket.MAGI if(ticket>0) { if(OrderSelect(ticket.comment.SELECT_BY_TICKET.Ask+TakeProfit*Po else ticket=OrderSend(Symbol(). return(0).Lots.Bid-TakeProfit*Point.OP_BUY.Lots. if(isCrossed==2) isCrossed=1. //Adjust the lot size total = OrdersTotal().GetLastError()). } return(0).0.OrderO } else Print("Error opening BUY order : ".Ask.Lots).Lots.slippage.comment.OrderTakeProfit return(0).metatrader. SELECT_BY_POS.Ask+TakeProfit*Point.OP_BUY. if(UseHedging) Hedge(ticket.Lots).Bid-Point*TrailingStop.Bid-TakeProfit*P else ticket=OrderSend(Symbol().MODE_TRADES)) Print("BUY order opened : ".GetLastError()).Order } else Print("Error opening SELL order : ". if(UseHedging) Hedge(ticket.slippage.info/book/print/34 { if(isCrossed==1) isCrossed=2.cnt<total.Metatrader Development Course http://www.SELECT_BY_TICKET. MODE_TRADES). } } } 116 of 258 6/14/2006 5:36 PM .Ask-StopLoss*Point. } for(cnt=0.Ask.slippage.Lots. if(OrderType()<=OP_SELL && OrderSymbol()==Symbol() && OrderMagicNumber() == MAGICMA) { if(OrderType()==OP_BUY) // long position is opened { // check for trailing stop if(TrailingStop>0) { if(Bid-OrderOpenPrice()>Point*TrailingStop) { if(OrderStopLoss()<Bid-Point*TrailingStop) { OrderModify(OrderTicket(). return(0).Bid+StopLoss*Point.OrderOpenPrice(). if(total < 1 || isNewSumbol(Symbol())) { if(isCrossed == 1) { if(UseStopLoss) ticket=OrderSend(Symbol().0. } if(isCrossed == 2) { if(UseStopLoss) ticket=OrderSend(Symbol().OP_SELL.

int count =0.SELECT_BY_TICKET.MODE_TRADES)) Print("Hedgin BUY order opened : " } else Print("Error opening Hedgin BUY order : ". } return (count). if(OrderSymbol() == Symbol()) Hedge(OrderTicket(). if(order_type == OP_SELL && order_profit < 0 . order_type. double hlots) { int ticket. } void Hedge (int order_ticket .Mql .Metatrader Development Course http://www. if(OrderSelect(order_ticket. MODE_TRADES).MODE_TRADES)) { order_type = OrderType().OrderLots()).slippage) { 117 of 258 6/14/2006 5:36 PM .OP_BUY.OrderOpenPrice(). } if(order_type == OP_BUY && order_profit < 0 .OrderTakeProfit return(0). SELECT_BY_POS.Ask+He if(ticket>0) { if(OrderSelect(ticket.hlots. for(cnt=0.Ask-HedgingStopLoss*Point. SELECT_BY_POS.slippage. } } return(0).info/book/print/34 } else // go to short position { // check for trailing stop if(TrailingStop>0) { if((OrderOpenPrice()-Ask)>(Point*TrailingStop)) { if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0)) { OrderModify(OrderTicket().slippage) { ticket=OrderSend(Symbol(). order_profit = OrderProfit(). for(int cnt = 0 . MODE_TRADES). } //+------------------------------------------------------------------+ int OrdersCount(string symbol) { int total = OrdersTotal().cnt<total. } } } } } } if(ContinuesHedging && OrdersCount(Symbol()) < 2) { //Print(OrdersCount(Symbol())).GetLastError()). if (symbol == OrderSymbol()) count++.Ask+Point*TrailingStop.metatrader. string hcomment = "EMAC_" + Symbol() + "_Hedging". double order_profit.Ask.SELECT_BY_TICKET.cnt++) { ticket = OrderSelect(cnt. cnt++) { OrderSelect(cnt. cnt < total .

hlots. The example right now is: the program will take the profit when it reaches 200 Pips and start to monitor the drop down of the profit when the profit reaches 150 Pips and prevent the profit to drop again to 100 Pips level.metatrader. Today we are going to take an idea to create Expert Advisor (That the Expert Advisors are for).Mql . suddenly the profit went to 150 then 100 then I'm losing money.Metatrader Development Course http://www. For example: There are 4 opened positions and they make profit. For example: the program will take the profit when it reaches 200 Pips and prevent the profit to drop below to 100 Pips . let's see the idea programicaly. But. The idea: How to protect my profits of all opening orders (if there's any) by the mean I want to take them when they reach a specific amount and close all the trades when the drop down to a specific amount. So.GetLastError()). we want to set another profit point that the program will prevent any drops below it. When the profit goes to specific amount we are going to close all the opened position.Bid+HedgingStopLoss*Point.slippage.Bid-H if(ticket>0) { if(OrderSelect(ticket. The problem: First we want a way to calculate the profit of all opened positions. Let's convert that to code! 118 of 258 6/14/2006 5:36 PM .info/book/print/34 ticket=OrderSend(Symbol().MODE_TRADES)) Print("Hedgin SELL order opened : } else Print("Error opening Hedgin SELL order : ".SELECT_BY_TICKET.Bid. How to tell the program that the profit went over 100 Pip and we don't want it drop back? We need a third point when the profit reach it the program will start to monitor the profit drop. we want the program too to prevent the profit to drop again. They've made 200 Pip right now. The programming problem now is when to start preventing the profit drop.OP_SELL. Our code today will prevent this situation. } } } Examples: ProfitProtector Expert Advisor! Hi folks.

cnt < total .. for (int cnt = 0 . cnt++) { OrderSelect(cnt.. //your normal code if(ProtectProfit) ProfitProtect(ProfitToProtect). But we are going to study the code aimed to protect the profit. ..//your normal code extern double ProfitToProtect = 200.//your normal code } void ProfitProtect(double profit) { int total = OrdersTotal(). extern double ProtectStarter = 150. These are the pieces of code concerning our idea: . extern double LossToProtect = 100... extern bool ProtectProfit= true.//your normal code int start() { .. } if(MyCurrentProfit>=ProtectStarter) //start protection at this level! ProtectLoss=true..Metatrader Development Course http://www.SELECT_BY_POS.. cnt < total . cnt++) { OrderSelect(cnt..Mql ... We will not study the expert advisor strategy in buying/selling/closing/trailing..SELECT_BY_POS. bool ProtectLoss= false. if(ProtectLoss) LossProtect(LossToProtect)... for (int cnt = 0 . } void LossProtect(double profit) { int total = OrdersTotal()...metatrader. double MyCurrentProfit=0.MODE_TRADES).MODE_TRADES).. if (OrderMagicNumber() == MagicNumber) MyCurrentProfit += OrderProfit().. if(MyCurrentProfit>=profit) CloseAll(). .. 119 of 258 6/14/2006 5:36 PM . double MyCurrentProfit=0.info/book/print/34 The code: Please download the code. I've added the profit protector code to a normal expert advisor of mine.

extern double ProtectStarter = 150. extern double LossToProtect = 100.MODE_TRADES). cnt++) { OrderSelect(0. } } Code study: We have defined our profit point as external variables at the top of the program: extern double ProfitToProtect = 200. void ProfitProtect(double profit) 120 of 258 6/14/2006 5:36 PM .Metatrader Development Course http://www. We have declared this variable outside the start() function to make it in a global scope and we will use this variable to start the profit monitoring. Violet).info/book/print/34 if (OrderMagicNumber() == MagicNumber) MyCurrentProfit += OrderProfit(). extern bool ProtectProfit= true. } if(MyCurrentProfit<=profit) CloseAll().SELECT_BY_POS.Slippage.Ask. And the ProtectStarter is the amount the program start at monitoring the profit to prevent drop down again. if(ProtectProfit) ProfitProtect(ProfitToProtect).metatrader. bool ProtectLoss= false.OrderLots().Slippage. And finally the LossToProtect is the amount of the profit the program prevent the profit to drop below it. if(ProtectLoss) LossProtect(LossToProtect).Mql . If the user has chosen to use our protect (ProtectProfit=True) then the program will call the function ProfitProtect().OrderLots(). Violet). if(OrderType()==OP_SELL) OrderClose(OrderTicket(). for (int cnt = 0 .Bid. Where the the ProfitToProtect is the amount we want the program to take the profit when it is reached. We are going to study this function soon. If the ProtectLoss variable is true (It will be true when the profit reaches the ProtectStarter level) then the program will call the function LossProtect() which we are going to study it soon. } void CloseAll() { int total = OrdersTotal(). if (OrderMagicNumber() == MagicNumber) if(OrderType()==OP_BUY) OrderClose(OrderTicket(). cnt < total . We have added the option to the user to use our profit protector or not with the variable ProtectProfit.

cnt++) { OrderSelect(cnt. Then we get the profit of the order using OrderProfit() and add it to the MyCurrentProfit variable. cnt++) { OrderSelect(0.Mql . 121 of 258 6/14/2006 5:36 PM . } if(MyCurrentProfit<=profit) CloseAll(). void CloseAll() { int total = OrdersTotal(). void LossProtect(double profit) { int total = OrdersTotal(). In every loop we select the order using OrderSelect() function and examine is the MagicNumber of the order is the same as our MagicNumber variable to be sure that we are working only with the positions have been opened with our Expert Advisor.info/book/print/34 { int total = OrdersTotal(). } if(MyCurrentProfit>=ProtectStarter) //start protection at this level! ProtectLoss=true.SELECT_BY_POS. } The ProfitProtect() function takes a double parameter (profit you want to protect).Slippage.SELECT_BY_POS.OrderLots(). if (OrderMagicNumber() == MagicNumber) MyCurrentProfit += OrderProfit().MODE_TRADES). if (OrderMagicNumber() == MagicNumber) if(OrderType()==OP_BUY) OrderClose(OrderTicket(). cnt++) { OrderSelect(cnt. We will use this variable to calculate the profit of the opened positions.SELECT_BY_POS. if true we will call the CloseAll() function which will close all the opened positions. It starts by getting the number of opened orders by calling the function OrdersTotal() then it declares a double variable MyCurrentProfit and initialize it to 0. if true we will enable ProtectLoss.MODE_TRADES).MODE_TRADES). Now we have the total profit stored in the MyCurrentProfit variable. And we have to check the MyCurrentProfit variable against ProfitToProtect variable to find did it reach it or not.Bid. Violet). for (int cnt = 0 . } The LossProtect() function is very like the ProfitProtect() function.Metatrader Development Course http://www. if(MyCurrentProfit>=profit) CloseAll().metatrader. the only difference is it will monitor the MyCurrentProfit value and close all the opened position if it goes below the LossToProtect vlaue. cnt < total . for (int cnt = 0 . double MyCurrentProfit=0. cnt < total . Now we enter in loop from 0 to the count of the opened positions. cnt < total . double MyCurrentProfit=0. We can check it now to find did it reach the ProtectStarter value. if (OrderMagicNumber() == MagicNumber) MyCurrentProfit += OrderProfit(). for (int cnt = 0 .

info/book/print/34 if(OrderType()==OP_SELL) OrderClose(OrderTicket(). How useful the global variables? The main job of the global variables is enabling the inner communication between the experts advisor.Slippage. But the global variables exist when you un-initialize the program and even if you shut down the terminal itself. Assume that you have created two expert advisors: The first expert advisor works on daily time frame and buys the EURUSD when the Moving Averages of the price of the last 10 days crosses upward the Moving Averages of the price of the last 80 days.OrderLots(). We are going to study the Global variables and the MQL4 functions that handle them. And it sells the EURUSD when the Moving Averages of the price of the last 10 days crosses downward the Moving Averages of the price of the last 80 days.metatrader. 122 of 258 6/14/2006 5:36 PM . Violet). } } The CloseAll() function goes through all the opened position and check them against our expert MagicNubmer then close every buy or sell position using OrderClose() function. The terminal can store the global variables for four weeks from the last store. And hope you find it a useful idea! Coders Guru Global variables Hi folks.Mql .Ask. I hope everything is clear. In MQL4 you use the normal variables to store the data temporary and it exists only at the time that program is running and vanishes with the un-initialization of the program.Metatrader Development Course http://www. What are the global variables? The global variables are places to store data between the instances of MQL4 programs and MetaTrader launches too. Today we are going to study a set of MQL4 functions which needs to be clearer for the new comers to the language.

Mql . You don't want the two expert advisors to take conflicted decisions. Any of the two expert advisors doesn't know anything about the other. Our program today will use the global variables to make the changes available to all the charts hold our expert advisor. How can they communicate? They can communicate with the aid of writing/reading global variables.Metatrader Development Course http://www.info/book/print/34 And the second expert advisor works on 1 hour time frame and buys the EURUSD when the Moving Averages of the price of the last 10 hours crosses upward the Moving Averages of the price of the last 80 hours. These are the global variables functions: GlobalVariableCheck: Syntax: bool GlobalVariableCheck (string name) Description: 123 of 258 6/14/2006 5:36 PM . Our example today will use the global variables in a very useful way. Of course the possibilities of using global variables are not limited. And it sells the EURUSD when the Moving Averages of the price of the last 10 hours crosses downward the Moving Averages of the price of the last 80 hours. You don't want the first expert advisor to sell the EURUSD while the second expert advisor is buying the EURUSD. Our example: When you attach an expert advisor to more than one chart/pair and want to change one of the expert advisor inputs values for all the charts you have to change this input for every chart. For instance the first expert advisor can write a global variable when it open sell/buy order while the second expert advisor can read this variable to be sure that it will not open a conflicting orders. If your expert advisor attached to ten pairs it will be a real problem to make the change 10 times.metatrader. Global variables functions: There are 6 functions in MQL4 responsible of handling the global variables.

Parameters: This function takes only one parameter: string name The global variable name the function will check is it exists or not. Example: 124 of 258 6/14/2006 5:36 PM . it returns true if it exists and false if not exists. Example: if(!GlobalVariableCheck("ge_TakeProfit ")) Alert("ge_TakeProfit global variable is not exist").metatrader.Metatrader Development Course http://www. GlobalVariableDel: Syntax: bool GlobalVariableDel (string name) Description: The GlobalVariableDel function deletes the global variable you passed its name and return true in success and false if it failed to delete it. You can use GetLastError to get the error information if any error has been occurred will you calling this function.Mql . You can use GetLastError to get the error information if any error has been occurred will you calling this function.info/book/print/34 The GlobalVariableCheck function checks if there's a global variable with the name passed to. Parameters: This function takes only one parameter: string name The global variable name the function will delete. Note: If the global variable not found the returned value will be 0 while the error code will be 4057 which means global variables processing error.

Example: if(GlobalVariableCheck("ge_TakeProfit")) TakeProfit = GlobalVariableGet("ge_TakeProfit").Mql . you have to use GlobalVariableCheck function before using GlobalVariableGet if your variable maybe 0. Parameters: This function takes only one parameter: string name The global variable name the function will return its stored value. You can use GetLastError to get the error information if any error has been occurred will you calling this function. And if you tried to store any data type other than the double data type. Note: You can store in the global variable and data type but the double data type. GlobalVariableSet: Syntax: 125 of 258 6/14/2006 5:36 PM . So. Note: If the global variable not found the returned value will be 0 while the error code will be 4058 which means global variable not found. This value must to be double data type.Metatrader Development Course http://www.metatrader. MQL4 will try to convert it to double data type.info/book/print/34 Alert(GlobalVariableDel("ge_TakeProfit ")). GlobalVariableGet: Syntax: double GlobalVariableGet (string name) Description: The GlobalVariableGet function returns the value of the global variable name passed to it.

You can use GetLastError to get the error information if any error has been occurred will you calling this function. double value The value of the global variable you want to set (or create).Mql .metatrader. This value must be double (numeric) data type.info/book/print/34 datetime GlobalVariableSet (string name. The returned value is a datetime data type which is the time of the last access time of the global variable if the function successes and if it failed the return value will be 0. GlobalVariableDel: Syntax: bool GlobalVariableDel (string name) Description: The GlobalVariableDel function deletes the global variable you passed its name and return true in success 126 of 258 6/14/2006 5:36 PM . double value) Description: The GlobalVariableSet function sets the variable name passed to it with the value passed to it. Example: Alert(GlobalVariableDel("ge_TakeProfit ")). Parameters: This function takes two parameters: string name The global variable name the function will set its value (or create it and sets its value). If it exists the function will change its old value to the new one.Metatrader Development Course http://www. If the global variable name does not exist the function will create it and set it to the passed value.

Today I'm going to answer all of you in this article. iMaOnArray (Moving average of indicator) Hi folks. You can calculate the moving average of this array. Let's say that we will attach the CCI (Commodity Channel Index) indicator to our chart (Figure 1). What's the moving average of indicator? When you attach an indicator to the chart it uses the price to for it calculation and save (draw) them . I've got a lot messages in the forex-tsd forum asking me how to use iMaOnArray function to get the Moving Average of a specific indicator.metatrader. I'll give you a manual example before going to create our mql4 version. Example: Alert(GlobalVariableDel("ge_TakeProfit ")). You can use GetLastError to get the error information if any error has been occurred will you calling this function.info/book/print/34 and false if it failed to delete it.Metatrader Development Course http://www. Note: If the global variable not found the returned value will be 0 while the error code will be 4057 which means global variables processing error. 127 of 258 6/14/2006 5:36 PM . Parameters: This function takes only one parameter: string name The global variable name the function will delete.Mql .

We can do that by dragging the Moving Average indicator to the window holds the CCI indicator and choose the Apply to: Previous Indicator's Data (Figure 2).metatrader. And that's what you get (Figure 3) How to do that programicly? If you are interested in getting the moving average of any indicator like the above manual setup. you can 'trigger' your MetaEditor and write this code: 128 of 258 6/14/2006 5:36 PM .info/book/print/34 Now we want to get the moving average of the CCI.Metatrader Development Course http://www.Mql .

bar). double ExtMapBuffer2[]. bar<limit.Bars.DRAW_LINE).0. } int start() { int bar. bar<limit.mq4 | //| Coders Guru | //| http://www.DRAW_LINE.MODE_DIGITS)).metatrader. SetIndexStyle(1. limit. SetIndexBuffer(0.Metatrader Development Course http://www. for(bar=0. 129 of 258 6/14/2006 5:36 PM .STYLE_SOLID.MODE_EMA.bar).PRICE_TYPICAL. } As you can notice in the above code that we use the function iCCI and iMAOnArray to calculate the Moving average of the CCI indicator.ExtMapBuffer1). SetIndexStyle(0. SetIndexBuffer(1.info/book/print/34 //+------------------------------------------------------------------+ //| iMAOnArray. return(0). The iCCI function simply calculate the CCI of a giving bar and return its value.ExtMapBuffer2). how to get the Moving Average of this buffer? iMAOnArray: With the aid of the iMAOnArray function we can calculate the moving average of the values stored in an array(buffer).14.Mql . Now we have a full of data buffer (ExtMapBuffer1). } int deinit() { return(0).14. We store those values returned by iCCI function in our buffer ExtMapBuffer1. int init() { IndicatorDigits(MarketInfo(Symbol(). if(counted_bars<0) return(-1).metatrader. return(0).0.2). bar++) ExtMapBuffer1[bar] = iCCI(NULL. if(counted_bars>0) counted_bars--. for(bar=0. bar++) ExtMapBuffer2[bar]=iMAOnArray(ExtMapBuffer1.info | //+------------------------------------------------------------------+ #property copyright "Coders Guru" #property link "http://www.metatrader.info" #property #property #property #property indicator_separate_window indicator_buffers 2 indicator_color1 LawnGreen indicator_color2 DarkBlue double ExtMapBuffer1[]. limit=Bars-IndicatorCounted(). int counted_bars=IndicatorCounted().

before continuing with these series of courses. 130 of 258 6/14/2006 5:36 PM . Today we are going to create a simple indictor which will not mean too much for our trade world but it means too much to our MQL4 programming understanding. Parameters: double array []: This is the array of the values you want to calculate the moving average of it. You have to fill this array with double data type items. welcome to your first indicator in MQL4. it means that you want to know the average of the price of the previous 12 hours. If you want to use all the items in the array in your moving average calculation pass 0 in the total parameter. int ma_method: The moving average method you want to use in your calculation. when use the moving average indicator with the daily chart and use 30 as the period of moving average calculation .metatrader.Metatrader Development Course http://www.returns double value.Mql .of the given bar.info/book/print/34 This is the syntax of the iMAOnArray function: double iMAOnArray(double array []. In our example we used the bufferex1 as the array[] parameter passed to iMAOnArray after filling that array with the values of the CCIs of the bars in our chart.int shift) The iMAOnArray . int total: You use the total parameter to indicate the count of items of the data from the array you want to use to calculate the moving average. this is the value of the moving average counted on the array .Your First Indicator (Part1) Welcome to the practical world of MQL4 courses. it means that you want to know the average of the price of the previous 30 days. These are the moving average methods available in MetaTrader Lesson 10 . that’s because we will use them so much in our explanations and studies of the Expert Advisors and Custom Indicators which we will create in this series of lessons. int period: The moving average period of the moving average you want to use. If you are familiar to moving average you can skip this section. I recommend you to read the previous nine lessons very carefully.int total. Don't worry you will understand well when you know the parameters of the iMAOnArray function.int ma_shift.int ma_method. when use the moving average indicator with the hourly chart and use 12 as the period of moving average calculation .int period.as you see in its syntax .

b. Dictionary tab enables you to access the MQL4 help system. Find in files tab. don’t be in a hurry. b. If you want to run MetaEditor you have three choices. you can highlight the keyword you want to know more about it and click F1. I’ve made a shortcut for MetaEditor on my desktop for easily access to the program. Let’s swim! MetaEditor: This is the program which has been shipped with MT4 (MetaTrader 4) enables you to write your programs.exe and click it (I recommend to make a shortcut on you desktop). 131 of 258 6/14/2006 5:36 PM . 3.Mql .metatrader. you will know everything very soon. choose MetaEditor from Tools menu or click its icon on the Standard toolbar (Figure 1). Figure 1 – MetaTrader Standard Toolbar Any method you have chosen leads you to MetaEditor as you can see in figure 2. find MetaTrader 4 group then click MetaEditor. Help tab. 1. Errors tab. you see here the files which contain the keyword you are searching for using the toolbar command “Find in files” or by clicking CTRL +SHIFT+ F hotkeys.Metatrader Development Course http://www. compile your program and More. you see here the errors (if there any) in your code.info/book/print/34 It simply will collect the subtraction of High [] of the price – Low [] of the price. and you will see the help topics in this tab. As you can see in figure 2. then click F4. read MQL4 help.Find the MT4 installation path (usually C:\Program Files\MetaTrader 4). there are three windows in MetaEditor: 12The Editor window which you can write your program in.Run MT4. find the MetaEditor. 2From Start menuà Programs. 3The Navigator window which contains three tabs: a. The Toolbox window which contains three tabs: a. for easy access to the files saved in the MT4 folder. c. Files tab.

First three steps: Now you have run your MetaEditor and navigated around its Menus. 132 of 258 6/14/2006 5:36 PM . Search tab enables you to search the MQL4 dictionary.metatrader. Figure 2 – MetaEditor Windows I recommend you to navigate around the MetaEditor Menus. Toolbar and windows. Note:Custom Indicator is a program which enables you to use the functions of the technical indicators and it cannot automate your deals. and then click next. Now let’s enjoy creating our first custom indicator. Choose Custom Indicator Program option. Step 1: Click File menu à New (you use CTRL+N hotkey or click the New Icon in the Standard toolbar).info/book/print/34 c. To create a custom indicator you have to start with three steps (you will learn later how to skip these boring steps (my personal opinion). You will get a wizard (Figure 3) guiding you to the next step. let’s USE it. Toolbar and windows to be familiar with it.Metatrader Development Course http://www.Mql .

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

Figure 3 - New project wizard

Step 2: When you clicked Next, you will get the second step wizard (Figure 4) which will enable you to edit the properties of your program. In this step you can enter these properties: 1- Name of your program, this is the name which the world will call you program with and it will be saved as the_name_you_have_chosen.mq4 2- Author name, the creator of the program name. 3- Link to your web site. 4- External variables list: I want to pause here to remember you about external variable. External variables are the variables which will be available to the user of you indicator to set from the properties tab of your indicator in MetaTrader. For example: MA_Period in the very popular EMA indicator. And these variables will be declared with the “extern” keyword in your code (Please review Variables lesson). So, this section of the wizard enables you to add these kinds of variables.

In our first indicator example we will not need any external variables just write the values you see in figure 4 and let’s go to step 3 by clicking Next button.

133 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

Figure 4 – Program properties wizard.

Step 3: The third wizard you will get when you clicked Next button is the Drawing properties wizard (Figure 5). Its job is enabling you to set the dawning properties of the lines of your indicator, for example: how many lines, colors and where to draw your indicator (in the main chart or in separate windows). This wizard contains the following options:

1- Indicator in separate window option: by clicking this option, your indicator will be drawn in separate windows and not on the main chart window. If you didn’t check the option, your indicator will be drawn in the main chart window. 2- Minimum option: it will be available (enabled) only if you have checked the Indicator in separate window option, and its job is setting the bottom border for the chart. 3- Maximum option: it will be available (enabled) only if you have checked the Indicator in separate window option, and its job is setting the top border for the chart 4Indexes List: here you add your indicator line and set its default colors.

I want you to wait to the next lesson(s) to know more about these options and don’t be in a hurry. For our first indicator example, choose Indicator in separate window option and click Add button, when you click add button the wizard will add a line to the indexes list like you see in figure 5.

134 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

Figure 5 - Drawing properties wizard.

When you click Finish button the Magic will start. You will see the wizard disappeared and the focus returned to the MetaEditor environment and… guess what?

You have ready to use first indicator draft code.

This is the code you will get:

//+------------------------------------------------------------------+ //| My_First_Indicator.mq4 | //| Codersguru | //| http://www.forex-tsd.com | //+------------------------------------------------------------------+ #property copyright "Codersguru" #property link "http://www.forex-tsd.com" #property indicator_separate_window #property indicator_buffers 1 #property indicator_color1 Red //---- buffers double ExtMapBuffer1[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---- indicators SetIndexStyle(0,DRAW_LINE); SetIndexBuffer(0,ExtMapBuffer1); //---return(0); }

135 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

//+------------------------------------------------------------------+ //| Custor indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---//---return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { int counted_bars=IndicatorCounted(); //---//---return(0); } //+------------------------------------------------------------------+

As you see in the above code, the wizard has written a lot of code for you, now I have to thank the wizard and to thank you too. In the next lesson we will discover every line of code you have seen above and add our code to make our first indicator. To this lesson I hope you be ready! Please don’t forget to download the source code of the first indicator and warm yourself for the next lesson. I welcome very much the questions and the suggestions. See you Coders’ Guru

Lesson 11 - Your First Indicator (Part2)
Welcome to the second part of “Your First Indicator” lesson. In the previous lesson we didn’t write any line of code, that’s because the New Project Wizard wrote all the code for us. Thanks! Today we are going to add few lines to the code the wizard had generated to make our program more useful. Afterwards, we are going to explain the whole of the code line by line. Let’s coding Code we have added: We have added the code which in a bold dark blue to our previous code:

136 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

//+------------------------------------------------------------------+ //| My_First_Indicator.mq4 | //| Codersguru | //| http://www.forex-tsd.com | //+------------------------------------------------------------------+ #property copyright "Codersguru" #property link "http://www.forex-tsd.com" #property indicator_separate_window #property indicator_buffers 1 #property indicator_color1 Red //---- buffers double ExtMapBuffer1[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---- indicators SetIndexStyle(0,DRAW_LINE); SetIndexBuffer(0,ExtMapBuffer1); string short_name = "Your first indicator is running!"; IndicatorShortName(short_name); //---return(1); } //+------------------------------------------------------------------+ //| Custor indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { //----

137 of 258

6/14/2006 5:36 PM

dResult. dLow .check for possible errors if (counted_bars<0) return(-1). Comment("Hi! I'm here on the main chart windows!").Metatrader Development Course http://www. //---. dResult = dHigh . double dHigh .dLow. //---.metatrader. } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { int counted_bars=IndicatorCounted(). int pos=Bars-counted_bars. //---. dLow = Low[pos]. pos--. } //+------------------------------------------------------------------+ How will we work? We will write the line(s) of the code we are going to explain then we will explain them 138 of 258 6/14/2006 5:36 PM .main calculation loop while(pos>=0) { dHigh = High[pos].Mql .last counted bar will be recounted if (counted_bars>0) counted_bars--.info/book/print/34 //---return(0). ExtMapBuffer1[pos]= dResult . } //---return(0).

Metatrader Development Course http://www.forex-tsd. You are commenting your code for a lot of reasons: _ To make it clearer _ To document some parts like the copyright and creation date etc.forex-tsd.mq4 | //| Codersguru | //| http://www.metatrader. _ To tell us how the code you have written is work. #property copyright "Codersguru" #property link "http://www.Mql . _ To make it understandable.com" #property indicator_separate_window #property indicator_buffers 1 #property indicator_color1 Red Property directive: 139 of 258 6/14/2006 5:36 PM . But at the most of the time we will pause to discuss some general topics. author and the link and wrote them as comments at the top of our program. Multi-line comments: The multi-line comment start with “/*” and ends with “*/” and you can comment more than one line. You use Comments to write lines in your code which the compiler will ignore them.info/book/print/34 afterwards.com | //+------------------------------------------------------------------+ Comments: The first five lines of code (which are in gray color) are comments. I want to here your suggestion about this method please! Now let’s crack this code line by line. if there are no topics. In our program the MQL4 wizard gathered from the data we entered the name of the program. //+------------------------------------------------------------------+ //| My_First_Indicator. _… You can write comments in two ways: Single line comments: The Single line comment starts with “//” and ends with the new line. we will explain the line(s) of code directly.

your indicator will be drawn in the main chart window (Figure 1).Metatrader Development Course http://www. their job is setting the properties of your program. indicator_chart_window: When you set this property. or drawing them in separate windows by choosing the indicator_separate_window.info/book/print/34 As you notice all of these lines start with the word (#property). The data type of this property is string. You have to choose one of two options for your Indicators. link: This property setting the web link to your web site which you asked to enter it in step 2 in the Expert Advisor Wizard (review the previous lesson).Mql . indicator_separate_window: When you set this property. That’s because they are kind of the Preprocessors directives called property directives. which means it takes no value. stacksize: It’s an integer value sets the memory size for every thread. The property directives are predefined constants called “Controlling Compilation” built in the MQL4 language. your indicator will be drawn in a separate window (Figure 140 of 258 6/14/2006 5:36 PM . For example: is your Indicator will appear in the main chart window or in a separate window? Who is the writer of the program? Note: The preprocessors lines end with a carriage-return character (new line) not a semi-colon symbol. We will try to discuss here the property directives available in MQL4. You can’t use the both of them at the same time.metatrader. The Preprocessors are the instructions you give to the compiler to carry them out before starting (processing) your code. The data type of this property is void. The data type of this property is string. The data type of this property is integer. same as the link property you asked to enter it in step 2 in the Expert Advisor Wizard. copyright: It’s the name of the author of the program. the default value is 16384. drawing them in the main chart windows by using this property.

In our program we will draw our indicator in a separate window: #property indicator_separate_window Figure 1 indicator_minimum: With the aid of this property we are setting the minimum value of the separate windows scale. which is the top border of the windows. indicator_maximum: With the aid of this property we are setting the maximum value of the separate windows scale. which is the bottom border of the windows.Mql . This value must be greater than the indicator_minimum value. The data type of this property is integer. this value must be greater than the indicator_minimum value and smaller than the indicator_maximum value. Main chart window Separate window indicator_levelN: With the aid of this property we are setting the level of the indicator in the scale we have created with the properties indicator_minimum and indicator_maximum.info/book/print/34 1). 141 of 258 6/14/2006 5:36 PM .metatrader. You can set the scale of the separate indicator window using two properties indicator_minimum for the minimum value and indicator_maximum for the maximum value of the scale. Both of the properties indicator_chart_window and indicator_separate_window are void data type. hence we have a scale ranged from 0 to 100 in our separate window which we are drawing our indicator.Metatrader Development Course http://www. The data type of this property is integer. And you can set the level of your indicators on these scales using the property indicator_levelN where’s the N is the indicator number. For example: #propery indicator_minimum 0 #propery indicator_ maximum 100 Here we have set the bottom border of the window to 0 and the top border to 100 (see indicator_ maximum). which mean they don’t take value and you just write them.

you can set the color of each of them using this property indicator_colorN . 142 of 258 6/14/2006 5:36 PM .info/book/print/34 N is the indicator number which we are setting its level. In our program we used only one buffer. We use Arrays to do this task. #property indicator_color1 Red The data type of this property is color. Arrays are very like the list tables. Arrays: In our life we usually group similar objects into units.metatrader. When we set the number (ranged from 1 up to 8) we are telling MQL4: “Please allocate a memory space for me to draw my indicator line”.Metatrader Development Course http://www. #property indicator_buffers 1 That’s because we will draw only one line.Mql . indicator_buffers: With the aid of this property we are setting the number of memories spaces (Arrays) allocated to draw our line(s). so we can set the indicator_level for each of them using its number). Rows in the Arrays called Indexes. it must range from 1 to 8 (because we are allowed only to use up to 8 indicator buffers in our program. where the N is the line number which defined by indicator_buffers.5 //set the second indicator level The data type of this property is double. in the programming we also need to group together the data items of the same type. indicator_colorN: We can use up to 8 lines in our indicator. In our program the indicator line color will be red. Figure 2 double ExtMapBuffer1[]. The user of your Indicator can change this color from the properties dialog of your Indicator (Figure 2). you group the items in the table and access them the number of the row. For example: #property indicator_minimum 0 #property indicator_minimum 100 #property indicator_level1 10 //set the first indicator level #property indicator_level2 65.

SetIndexBuffer(0. SetIndexStyle(0.24. Here.info/book/print/34 To declare an array you use a code like that: int my_array[50].metatrader. deinit(): This is the last function the program will call before it shutdown.ExtMapBuffer1). Here. like that: My_array[10] = 500.Metatrader Development Course http://www. start(): Here’s the most of the work. 143 of 258 6/14/2006 5:36 PM .Mql . which can hold up to 50 items. You can initialize the array at the same line of the declaration like that: int my_array[5] = {1.15. you can put here any removals you want. You can access each item in the array using the index of the item. Here we have declared and array of double type. you have to put here you initialization values of you variables.66.500}. In MQL4 there are three special functions init(): Every program will run this function before any of the other functions. you have declared an array of integer type. every time a new quotation have received your program will call this function. string short_name = "Your first indicator is running!". We will use array to calculate our values which we will draw them on the chart. you have set the item number 10 in the array to 500. In our program we used this line of code: double ExtMapBuffer1[].DRAW_LINE). int init() { } Special functions: Functions are blocks of code which like a machine takes inputs and returns outputs (Please review lesson 7 – Functions).

int style=EMPTY. color clr=CLR_NONE) This function will set the style of the drawn line. The width parameter is the width of line and ranges from 1 to 5.Metatrader Development Course http://www. The clr parameter is the color of the line. The default value is CLR_NONE which means empty state of colors.Mql . SetIndexStyle: void SetIndexStyle( int index. Or it can be EMPTY (default) which means the width will not change. we will study here the functions used in our program. So. Custom indicator functions: I can’t give you a description for all of the indicators functions in this lesson. int width=EMPTY. The type parameter is the shape type of the line and can be one of the following shape type’s constants: DRAW_LINE (draw a line) DRAW_SECTION (draw section) DRAW_HISTOGRAM (draw histogram) DRAW_ARROW (draw arrow) DRAW_NONE (no draw) The style parameter is the pen style of drawing the line and can be one of the following styles’ constants: STYLE_SOLID (use solid pen) STYLE_DASH (use dash pen) STYLE_DOT (use dot pen) STYLE_DASHDOT (use dash and dot pen) STYLE_DASHDOTDOT (use dash and double dots) Or it can be EMPTY (default) which means it will be no changes in the line style.info/book/print/34 IndicatorShortName(short_name). And it indicte which line we want to set its style. int type. But we will use them all in our next lessons with more details. The index parameter of this function ranges from 1 to 7 (that’s because the array indexing start with 0 and we have limited 8 line). It can be any valid color type variable. 144 of 258 6/14/2006 5:36 PM .metatrader.

string short_name = "Your first indicator is running!". etc.DRAW_LINE).Mql .info/book/print/34 In our line of code: SetIndexStyle(0. int deinit() { //---- 145 of 258 6/14/2006 5:36 PM . And we have left the other parameters to their default values. SetIndexBuffer: bool SetIndexBuffer( int index. And we have only one indicator buffer (#property indicator_buffers 1). IndicatorShortName: void IndicatorShortName( string name) This function will set the text which will be showed on the upper left corner of the chart window (Figure 3) to the text we have inputted. IndicatorShortName(short_name).Metatrader Development Course http://www. The function takes the index of the buffer where’s 0 is the first buffer and 1 is the second. We have set the index to 0 which means we will work with the first (and the only) line. And we have set the shape type of our line to DRAW_LINE because we want to draw a line in the chart. In our program we declared a string variable and assigned the value “You first indicator is running” to it.metatrader. This is the return value of the init() function which terminate the function and pass the program to the execution of the next function start(). So it will be the buffer assigned. Figure 3 return(0). Then it takes the name of the array. In our program the array which will hold our calculated values is ExtMapBuffer1. then we passed it to the IndicatorShortName function. double array[]) This function will set the array which we will assign to it our indicator value to the indicator buffer which will be drawn. It returns true if the function succeeds and false otherwise.

The code we have: //+------------------------------------------------------------------+ //| My_First_EA.0.mq4 | //| Coders Guru | //| http://www. //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ 146 of 258 6/14/2006 5:36 PM .com" //---.0.com | //+------------------------------------------------------------------+ #property copyright "Coders Guru" #property link "http://www.info/book/print/34 //---return(0). extern double TrailingStop=35. See you Coders’ Guru Lesson 16 . Let’s take the final step.forex-tsd. I hope you enjoyed the journey discovering how to write our simple yet important expert advisor.Metatrader Development Course http://www.Mql .1.Your First Expert Advisor (Part 4) we have reached the edge of the moon in our way to the truth. but I’m so happy to reach the last part of explaining or first expert advisor. I hope you enjoyed the lesson and I welcome your questions.input parameters extern double TakeProfit=250.metatrader. I’m not under the impact of alcoholic poisoning (I don’t drink at all). Yes! This is the last part of the expert advisor lesson. extern double Lots=0. } Nothing new to say about deinit() function.forex-tsd. We will continue with remaining of the code in the next lesson.

} int Crossed (double line1 . double line2) { static int last_direction = 0. } else { return (0). if(line1>line2)current_direction = 1.info/book/print/34 int init() { //---//---return(0). static int current_direction = 0. } } 147 of 258 6/14/2006 5:36 PM .metatrader.Metatrader Development Course http://www. return (last_direction). //up if(line1<line2)current_direction = 2. } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---//---return(0).Mql . //down if(current_direction != last_direction) //changed { last_direction = current_direction.

longEma.MODE_EMA. double shortEma.MODE_TRADES)) 148 of 258 6/14/2006 5:36 PM . if(Bars<100) { Print("bars less than 100").Green).longEma). longEma = iMA(NULL.0.0.0). } if(TakeProfit<10) { Print("TakeProfit less than 10"). // check TakeProfit } shortEma = iMA(NULL.0).SELECT_BY_TICKET. total = OrdersTotal().3.PRICE_CLOSE.13.0.Ask.OP_BUY. total. return(0).12345.8. if(ticket>0) { if(OrderSelect(ticket. if(total < 1) { if(isCrossed == 1) { ticket=OrderSend(Symbol(). return(0).MODE_EMA.metatrader. ticket. int isCrossed = Crossed (shortEma.0.Ask+TakeProfit*Point. "My EA".Lots.0.info/book/print/34 //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---int cnt.0.PRICE_CLOSE.Metatrader Development Course http://www.Mql .

} else Print("Error opening SELL order : ".cnt<total.0. } return(0). // close position 149 of 258 6/14/2006 5:36 PM .3.OrderLots(). SELECT_BY_POS. Bid-TakeProfit*Point.GetLastError()).12345. return(0). } else Print("Error opening BUY order : ".OP_SELL.metatrader. if(OrderType()<=OP_SELL && OrderSymbol()==Symbol()) { if(OrderType()==OP_BUY) // long position is opened { // should it be closed? if(isCrossed == 2) { OrderClose(OrderTicket().Metatrader Development Course http://www. if(ticket>0) { if(OrderSelect(ticket.info/book/print/34 Print("BUY order opened : ".Violet).OrderOpenPrice()).Bid.0.SELECT_BY_TICKET.3.OrderOpenPrice()). } for(cnt=0.Mql .GetLastError()). MODE_TRADES). } if(isCrossed == 2) { ticket=OrderSend(Symbol()."My EA".MODE_TRADES)) Print("SELL order opened : ".Lots.Bid.Red).cnt++) { OrderSelect(cnt. return(0).

Green).3. // exit } // check for trailing stop if(TrailingStop>0) { if(Bid-OrderOpenPrice()>Point*TrailingStop) { if(OrderStopLoss()<Bid-Point*TrailingStop) { OrderModify(OrderTicket(). } } } } else // go to short position { // should it be closed? if(isCrossed == 1) { OrderClose(OrderTicket().Violet).BidPoint*TrailingStop. // exit } // check for trailing stop if(TrailingStop>0) { if((OrderOpenPrice()-Ask)>(Point*TrailingStop)) { if((OrderStopLoss()>(Ask+Point*TrailingStop)) || 150 of 258 6/14/2006 5:36 PM .Mql . // close position return(0).metatrader.OrderLots().Metatrader Development Course http://www.OrderTakeProfit(). return(0).info/book/print/34 return(0).0.OrderOpenPrice().Ask.

OrderTakeProfit()..Red). return(0).OrderOpenPrice(). We have used this code: if(total < 1) { if(isCrossed == 1) { . Today we will study Modify-Close Opened Orders routine...Metatrader Development Course http://www. } if(isCrossed == 2) { .Mql . } return(0)... } //+------------------------------------------------------------------+ In the previous lesson.0.metatrader. } } } } } } return(0).Ask+Point*TrailingStop..info/book/print/34 (OrderStopLoss()==0)) { OrderModify(OrderTicket(). 151 of 258 6/14/2006 5:36 PM . } This was the Open New Order routine. we checked the OrdersTotal is less than 1 in order to open a Buy or a Sell orders in the case that there were no already opened orders...

Note: You have to use OrderSelect function before the trading functions which takes no parameters: OrderMagicNumber. if(OrderType()<=OP_SELL && OrderSymbol()==Symbol()) { . 152 of 258 6/14/2006 5:36 PM .. OrderSelect(cnt. OrderPrint.2. OrderCloseTime. OrderCommission.. We used the OrderSelect here before using the OrderType and OrderSymbol functions because if we didn't use OrderSelect.Mql .metatrader. MODE_TRADES).info/book/print/34 for(cnt=0. Every loop cycle we increase the number of cnt by 1 (cnt++).cnt<total.3 etc) which we will use with OrderSelect function to select each order by its position.. OrderStopLoss.So. OrderClosePrice.1. OrderComment. OrderSwap. Our today's mission is studying what's going inside the heart of the above loop. OrderProfit. OrderOpenPrice. Note: The index of the first order is 0 and the index of the second one is 1 index etc. } In the above block of code we used a for loop to go through all the already opened orders. cnt will hold in every cycle the poison of the order (0.. OrderLots. OrderSymbol. OrderTicket and OrderType We used SELECT_BY_POS selecting type which means we want to select the order by its index (position) not by its ticket number. OrderExpiration. the OrderType and OrderSymbol functions will not work. OrderOpenTime..Metatrader Development Course http://www. And we used MODE_TRADES mode which means we will select from the currently trading orders (opened and pending orders) not from the history. We start the loop from the cnt = 0 and the end of the loop is the total number of already orders. OrderTakeProfit. } The OrderSelect function used to select an opened order or a pending order by the ticket number or by index. SELECT_BY_POS.cnt++) { ..

.Violet).Bid. so we check the OrderSymbol of the order with the return value of Symbol function which returns the current chart symbol. the first type is OP_BUY.Metatrader Development Course http://www. OP_BUYSTOP. It's a logical to close this position when the shortEma and longEma crosses each others in reversal direction (downward). If they are equal it means we are working with the currently loaded symbol. So. Let's see what will do in the case of a long position has been opened if(isCrossed == 2) { OrderClose(OrderTicket(). The code above means: Is there a long (Buy) position opened? If yes! Execute this block of code…. if(OrderType()==OP_BUY) // long position is opened { . 153 of 258 6/14/2006 5:36 PM . So. OP_SELLLIMIT or OP_SELLSTOP We checked the type of the order to find is it equal or lesser than OP_SELL.metatrader. // close position return(0). Which means it maybe one of two cases: OP_SELL or OP_BUY (because OP_SELL=1 and OP_BUY = 0).info/book/print/34 The OrderType function returns the type of selected order that will be one of: OP_BUY. OP_SELL.. all the coming code will work only if the OrderType is OP_SELL or OP_BUY and the Symbol = OrderSymbol..Mql .OrderLots().3. OP_BUYLIMIT. // exit } We have opened a Buy order when the shortEma crossed the longEma upward. } We are working only with two types of orders. We want too to work only with the order opened in the chart we loaded our expert advisor on. we checked the isCrossed to find is it = 2 which means the reversal has been occurred and in this case we close the Buy order. We did that because we will not work with pending orders.

metatrader. (Review appendix 2).0. We didn't forget to terminate the start function with return(0) statement.OrderOpenPrice(). // check for trailing stop if(TrailingStop>0) { if(Bid-OrderOpenPrice()>Point*TrailingStop) { if(OrderStopLoss()<Bid-Point*TrailingStop) { OrderModify(OrderTicket(). we used the OrderLots function to get the lots value of the selected order.BidPoint*TrailingStop. } } } Note: We are still inside the block of: if(OrderType()==OP_BUY). The second parameter in the OrderClose is Lots (the number of lots).Green). We’ve got the ticket number of the selected order using the OrderTicket function and passed it as the first parameter for OrderClose function.Metatrader Development Course http://www. We are going to apply our trailing stop technique for the opened Buy position in this block of code. Then we applied our trailing stop technique for the opened Buy orders which is: We modify the stoploos of the order when the subtraction of the current bid price and 154 of 258 6/14/2006 5:36 PM . Firstly. The fifth parameter is the color of the closing arrow and we used Violet color. return(0). OrderClose function closes a specific opened order by its ticket. we have checked the TrailingStop variable the user supplied to check was it a valid value or not (greater than 0). The fourth parameter is the slippage value and we used 3.Mql . The third parameter in OrderClose is the preferred close price and we used the Bid function to get the bid price of the selected order.info/book/print/34 We used the OrderClose function to close the order.OrderTakeProfit().

we are working now a Sell order type..Metatrader Development Course http://www.info/book/print/34 the opened price of order is greater than the TrailingStop and the current stoploss is lesser than the subtraction of the current bid price and the TrailingStop. stoploss: Here's the real work! Because we are in a Buy position we set our new stoploss to the value of the subtraction of the current bid price and the TrailingStop. Note: Stop losses are always set BELOW the current bid price on a buy and ABOVE the current asking price on a sell.Mql . we've got the current profit value of the order with OrderTakeProfit function. So. else // go to short position { . takeprofit: No changes. That's our way trailing the stoploss point every time we make profits.. We used the OrderModify function to make the desired modification. arrow_color: Still Green color. Let's see what are we going to do in the case of a short (Sell) position has been already opened? 155 of 258 6/14/2006 5:36 PM .... These are parameters we used with OrderModify: ticket: We've got the current order ticket with OrderTicket function..metatrader. expiration: We didn't set an expiration date to our order. Finally we terminate the start function. price: We’ve got the open price of the order with OrderOpenPrice function. } Note: else here belongs to the code: if(OrderType()==OP_BUY) // long position is opened { . so we used 0. } We have studied the case of the type of the order is a Buy order.

We used the OrderClose function to close the order. // close position return(0).Ask. Which happens in the case of isCrossed = 1.Metatrader Development Course http://www. // check for trailing stop if(TrailingStop>0) { if((OrderOpenPrice()-Ask)>Point*TrailingStop) { if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0)) { OrderModify(OrderTicket().0. OrderTakeProfit().Red).info/book/print/34 if(isCrossed == 1) { OrderClose(OrderTicket().3. // exit } We’ve opened a Sell order when the shortEma crossed the longEma downward. Then we terminated the start function. we used the same parameters we use in the case of closing a Buy order except the third parameters the preferred close price.Ask+Point*TrailingStop.metatrader.OrderLots(). in this case is the Ask price. It's the time to close this position when the shortEma and longEma crosses each others in reversal direction (upward). 156 of 258 6/14/2006 5:36 PM .OrderOpenPrice().Violet). we’ve checked the TrailingStop variable the user supplied to check was it a valid value or not (greater than 0).Mql . Firstly. } } } We are going to apply our trailing stop technique for the opened Sell position in this block of code. return(0).

Mql . I hope you enjoyed the lesson. Just don’t forget it. We used the OrderModify function to make the desired modification. Coders’ Guru Life cycle of MQL4 program Hi folks. the life cycle of the MQL4 program. What's the different between the life cycle of the expert advisors and script? and a lot of questions about the MQL4 program life cycle. And the fifth parameter which indicates the color of the arrow in this case is Red. what's the phases of the MQL4 program. Today we are going to discuss a flustering issue for the most of new MQL4 comers. there are no conditions to open new positions and there are no needs to close or modify the already opened orders. And used the same parameters we use in the case of modifying already opened Buy order except the third parameter which indicates our stoploss value: We set our new stoploss to the value of the addition of the current ask price and the TrailingStop. What the first block of code is executed first and what the last block of code is executed. Then we terminated the start function using return(0).metatrader.info/book/print/34 Then we applied our trailing stop technique for the opened Sell orders which is: We modify the stoploss of the order when the subtraction of the order's opened price and the current ask price is greater than the TrailingStop and the current stoploss is greater than the addition of the current ask price and the TrailingStop.Metatrader Development Course http://www. Let's know first what happen when the MQL4 starts? When the MQL4 program starts: 157 of 258 6/14/2006 5:36 PM . I welcome very much your questions and suggestions. This line terminates the start function in all other case. return(0).

Each variable you declare using "extern" keyword will appear in the expert advisor input windows with its default value. take profit and stop loss levels).info/book/print/34 The first time you attach the MQL4 to chart the first thing MetaTrader will do is showing the input dialog depending on the type of the program: Expert Advisors: In this case you'll get the expert advisor input window (Figure 1) which enable you to set the parameters of the expert advisor if there was any (i.Mql . Indicators: The same as expert advisors. Each variable you declare using "extern" keyword will appear in the indicator parameters windows with its default value. for example: #property indicator_color1 Silver #property indicator_color2 Red and the preset levels are defined using the preprocessor keywords "#property indicator_levelN".metatrader. the colors of the indicator lines (Figure 3) and the levels of the sub-window chart (Figure 4). "#property indicator_levelwidth" and "#property indicator_levelstyle". the first time you attach an indicator to chart you'll get the parameters window (Figure 2) which enable you to set the parameters of the indicator. "#property indicator_levelcolor".Metatrader Development Course http://www. The colors are defined using the preprocessor keyword "#property indicator_colorN".e. 158 of 258 6/14/2006 5:36 PM .

If you used "#property show_confirm" preprocessor keyword a confirmation message box will appear before the script input window.Mql . they will appear in the script input window (Figure 5) only if you used the preprocessor keyword "#property show_inputs".info/book/print/34 Scripts: If there were any inputs coded in the script using the extern keyword.Metatrader Development Course http://www.metatrader. 159 of 258 6/14/2006 5:36 PM .

When you change the account the expert advisors will be initialized. the initialization code is executed only one time during the life cycle of the program and will not be called again till the end of the program. 3.When you recompile the program in MetaEditor and the program was hosted on one or more charts (except the scripts). Unlike the above case.Metatrader Development Course http://www. This phase executed if one of these triggers occurred: 1.When you change the symbol of the chart and the program was hosted on one or more charts (except the scripts). Every line of code you wrote inside the block of init() function will be executed in this phase.metatrader. The script is executed only once (to the end of its life cycle) then de-initialized so MetaTrader wouldn't host opened scripts. 160 of 258 6/14/2006 5:36 PM .Mql . 4.When you start MetaTrader and there were opened chart(s) that hosts expert advisors or indicators. Let's see what will happen nex? Initialization phase? The next phase in the MQL4 program cycle is the initialization phase.The first time you attach the program to a new chart (After the input window appearance).Figure 6).When you change the period of the chart and the program was hosted on one or more charts (except the scripts). 5. 7. 2.When you change one of the program inputs (hitting F7 hot key to open expert advisor input window and right click the indicator then choose indicator properties from the context menu .info/book/print/34 This is the first step MetaTrader will take in the journey of the MQL4 program life. 6.

6. 3. every time MetaTrader receives new price quotation from the server it calls start() function and execute all the lines of the code in its block.When you change the inputs of the program. De-initialization phase? Every program attached has its end.metatrader.For the indicators the start() function is recalled in the case of changing the chart symbol. you have to close it to enable MetaTrader to execute start() function again. that means the code of start() function is executed line by line and only when MetaTrader find the return keyword it will be ready to call start() function again with the most new quotation. These are the triggers of the deinit() function: 1. Besides the new quotation arrival trigger. 161 of 258 6/14/2006 5:36 PM .For the indicators the start() function is recalled in the case of changing the chart period Note: The start() function will not be run when you open the expert advisor input window.Metatrader Development Course http://www. when the program ends its job the block of deinit() function will be executed. 7. Note: The scripts is an exception because its start() function is executed once you attach it to the chart and immediately after the init() function then the script is detached from the chart.Before the changing of the symbol of the chart that hosts the program.When you close the chart that hosts the program. The execution phase is the longest phase in the program cycle life and in the most of programs the start() function block code is the most important code. 4. 5.When you shut down MetaTader and the program was hosted on one or more charts.When you change the account the expert advisors will be de-initialized. 2. 2.When you recompile the program and the program was hosted on one or more charts.info/book/print/34 Execution phase: After the initialization of the program it will wait for new quotation arrival from the server. the start() function is executed in these cases: 1.Mql . If there were any quotations that arrived while the execution of start() function it would be ignored by the program.Before the changing of the period of the chart that hosts the program. The start() function have to finish its job first before receiving/reacting to new quotations.

int type) Description: The MarketInfo() function is the function you need to retrieve various market data of the given currency. Coders Guru MarketInfo function Hi folks. the Swap value of Buy or Selling the currency and the number of digits the currency uses.Metatrader Development Course http://www. This function can return the following important data: MQL4 programs protection! Hi folks! 162 of 258 6/14/2006 5:36 PM .info/book/print/34 These was the life cycle of the MQL4 program and it's the time to de-initialize the lesson. how to make an expert advisor that can open Buy position of GBPUSD or USDCHF while the expert advisor is hosted on EURUSD chart?" In the previous lesson we studied the Timeseries Access functions that enables us to access the price date of any chart (currency and timeframe) regardless of the chart that hosts the expert advisor. Our magic function today is MarketInfo() function: MarketInfo() function: Syntax: double MarketInfo( string symbol.metatrader. the current Ask price of the currency.Mql . What's the Bid/Ask price we are going to use with OrderSend to open the order? We can't use the function Bid() and Ask() because they are returning the current currency Bid and Ask price. But they are not enough to write our expert advisor. We are going to complete our series of lessons that answer the question: "How to deal with currency pairs which are different than the current chart currency (The chart that hosts the expert advisor)? For example. for example: the current Bid price of the currency. Note: A part of this data are stored in the Predefined Variables but this data is exclusive for the current chart and MarketInfo() function give us more data about the currency. Hope you enjoyed it.

Metatrader Development Course http://www. When the user buy your program you send him the program with a password and he can use the program without the password. Compiling is an operation taken by a special program (called a compiler) to convert the program from text (readable) format to the binary format which the computer can understand (computers think in binary). We compile the mq4 files because the MetaTrader can't load any files except ex4 files. You protect it by write the protection code in the source code of the program then compile it to the ex4 format then distribute it to the user. the program files and the executable files: The program files are normal text files but have one of these extensions: . We are doing this by opening the mq4 files in MetaEditor then pressing F5 hot key. that's why I'm writing this article. This is the general definition of compiling. source code means they could be opened for viewing or editing in MetaEditor. The executable files are binary files (you can't open them for viewing or editing) and has the extension . The source code of MQL4 programs can't be protect because it's in text format and when you distribute it you intend to give the receiver the access to the source code of the program. I think it's not evil to use your programming talent to get some money if you don't want to share (it's a choice anyway). Kinds (ideas) of the protection: We are going to discuss some ideas of MQL4 programs protection. and these are the files that you can load them in MetaTrader and use them. maybe they are not the best but they are the common ideas. Compiling in our case is converting the mq4 files to ex4 for file using MetaEditor program.mgh. Source code verse binary: Just as a review and to emphasis that we are talking about how to protect the . 163 of 258 6/14/2006 5:36 PM . however I've got a lot of requests asking me about MQL4 indicator/experts protection. These files are the result of compiling the .mq4 files using MetaEditor.ex4. we are going to write some code to apply these ideas: Password protection code: This the widely used method to protect softwares in general and can be used to protect MQL4 programs.ex4 files read the next section: There are two kinds of files that you use with MetaTrader.metatrader. The executable version of the program is the only version that you can protect it.info/book/print/34 I'm very fanatic for sharing MQL4 codes/ideas.mq4 and . These files are the source code of the programs wrote in MQL4 programming language. MetaEditor will compile (convert) the file to ex4 format and keeping the mq4 file untouched MetaEditor will place the generated ex4 file at the same path as the mq4 file.Mql . Without protecting your MQL4 code it will be waste of time to try to commercialize your programs.

Metatrader Development Course http://www.type the user account here before compiling int accnt = AccountNumber().info/book/print/34 This is a simple code to apply password protection method: int start() { extern string Please_Enter_Password = "0".06". if (CurTime() >= e_d) { Alert ("The trial version has been expired!"). return (0). } Limited account number protection: In this method of protection you will ask the user to give you his account number and you write the following code to prevent the program to work with another accounts: int start() { int hard_accnt = 11111. //<-.. Use the code below to limit your program for period of time. } // your normal code! return(0). // your code here. //<-. You have to compile the program after adding this piece of code and send it to the user with the password.metatrader. int start() { if (password != "viva metatrader") //change to the password you give the user! { Alert ("Wrong password!").. return(0). Trial period protection: If you want to give the user of the program a try-before-buy program you can limit the usage of your program by limited period of time and after this period the program will not work.. if (accnt != hard_accnt) { 164 of 258 6/14/2006 5:36 PM .. int start() { string expire_date = "2006. } In the code above the password is "viva metatrader" which is hard coded in the MQL4 file.hard coded datetime datetime e_d = StrToTime(expire_date). } // your code here.31.Mql ...

write your own C++ DLL and let the MQL4 program export it. I hope I can to write all purposes MQL4 protection DLL. It's not strong protection because the user can host the program in another instance of MetaTrader that runs in demo mode and trade manually in the real account instance. I'll let you know when I write one. Hope you enjoyed the article! Object functions Hi folks.0) + ") with this program!"). } // your normal code! return(0). return(0). return(0). } Limited account type protection: In this method of protection you will allow the user to use the program in demo mode only and prevent him to use the program in live trading. if (!demo_account) { Alert ("You can not use the program with a real account!"). int start() { bool demo_account = IsDemo().Mql . for instance you can make the DLL communicated to your server (if you have one) enabling the user to download a certificate or even update the MQL4 program.Metatrader Development Course http://www. 165 of 258 6/14/2006 5:36 PM .metatrader.info/book/print/34 Alert ("You can not use this account (" + DoubleToStr(accnt. } // your normal code! return(0). In C++ you can do anything. } DLL protection: This is the method of choice.

arrows and texts) as a visual aid to facilitate the analysis of chart. Then you can modify/delete the created object by selecting the object on the chart and right click it then choose the operation you want from the context menu (Figure 3). it's a hard task to do it manually but in MQL4 it's a very easy task (as you'll see later) 166 of 258 6/14/2006 5:36 PM .Metatrader Development Course http://www.metatrader. For example if you have hundred of objects on the chart and you want to delete them. shapes. you just have to choose the object you want to draw from the Insert menu or from the Line Studies toolbar (Figures 1 and 2).Mql .Line studies toolbar Figure 3 . Drawing objects in MetaTrader manually is an easy task. We are going to study the Object functions which enable us to handle everything you can manually do with the objects and the things you can't do manually.info/book/print/34 You use objects (Line studies. Figure 1 .Insert menu Figure 2 .Objects context menu Today we are going to know how to programicaly work with objects in MQL4.

datetime time1. you use the index of the window with the ObjectCreate function and you have to remember that: 1. double price3=0) Description: The ObjectCreate function creates a new object with the specified name and type.Objects list window Windows: You can draw the object on the chart main window (The main window which show the price date) or on any of the chart sub-windows .To find the index of a specific window by its indicator name use the function WindowFind( string name).To get the number of window use the function WindowsTotal( ). Object name: The name of the object is the name you see in the Objects list window (Figure 4) and this name works as a handle for the object which you can use later to work with this object (For example to delete it or move it) so it must be unique. Figure 4 . 4. 167 of 258 6/14/2006 5:36 PM . datetime time3=0. The function returns true if the object successfully created otherwise it returns false. in the specified window and coordinates.info/book/print/34 Let's see the Object functions: ObjectCreate: Syntax: bool ObjectCreate(string name. int type. double price2=0. 2. To know the exact error use GetLastError() function.metatrader.The index of the chart main window is 0.The chart sub-windows indexes start from 1 up to the number of the windows minus 1. 3.Mql . double price1. int window.Metatrader Development Course http://www. datetime time2=0.

Coordinates Parameters: string name: The string name of the object which you will use it later as a reference of object. you pass to the ObjectCreate function the integer representation of the object or the constant name of this integer.info/book/print/34 5. -.Metatrader Development Course http://www. while the second and third coordinates pairs are optional and you have to use them only with the object which use 2 or 3 coordinates.metatrader. int type: The type of the object you want to draw. The X (vertical) coordinate of the object is the time on the chart and the Y (horizontal) coordinate of the object is the price on the chart (Figure 5). " & / 2 ) 13 & '( ) " ) 0 * '+ . for example the Vertical line object uses only 1 coordinate. this is the table of the object integers representation and their constant names: Constant Value Description ! ! #$ % % 1 $ .The index of the window must be less than the total of windows (retuned by WindowsTotal( ) function). The first coordinate pairs (X and Y) are required parameters even if an object like the OBJ_LABEL will ignore them. Figure 5 .Mql .. * 168 of 258 6/14/2006 5:36 PM . the Trend line object uses 2 coordinates and the Channel object use 3 coordinates. Coordinates: You can use up to 3 coordinates for the object drawing depending on the type of the object.

Mql . 8$ $ 1 <=$ . " & / 2 4 6 9 ? : " " A "" "& 8' 8' 8' 8' 8' ) ) " $ 1( > $ > 0 ' 0 3 " @ & & > 3 " & & 8 1 $ 1 $ % $ % =.info/book/print/34 . You have to note which currency pair you are going to draw on its chart because the prices ranges differs from currency to currency. double price1: The first horizontal coordinate of the object. . It's an optional parameter which you can use it if your object uses 2 coordinates.1. This parameter is required and you can set it to 0 if the object will not use the vertical coordinate. = 1 8 1#1 < $ $ . This parameter is a datetime type (because the vertical coordinate of the chart is the time coordinate). the chart main window has the index 0 and the sub chart starts from 1 to the total of the window . datetime time1: The first vertical coordinate of the object.metatrader. !! %$ %$ %$ 8 8 8 8 1 $ 4 6 . 169 of 258 6/14/2006 5:36 PM . % % % 8' ) 5 " " " 3 7 '* 7 '* 7 '* " " " " 0 ) ) ) 8$ % ! 9 : . > int window: The index of the window you want to draw the object on. datetime time2: The second vertical coordinate of the object. It's an optional parameter which you can use it if your object uses 2 coordinates. double price2: The second horizontal coordinate of the object. This parameter is required and you can set it to 0 if the object will not use the horizontal coordinate. This parameter is a double type (because the horizontal coordinate of the chart is the price coordinate).Metatrader Development Course http://www.

It's an optional parameter which you can use it if your object uses 3 coordinates.info/book/print/34 datetime time3: The third vertical coordinate of the object.20 12:30'.02. Example: // new text object if(!ObjectCreate("text_object". If the object successfully deleted the function will return true.Mql . 170 of 258 6/14/2006 5:36 PM . otherwise it will return false. Use GetLastError() function to get more details about the error. ObjectSet("label_object". return(0).0045)) { Print("error: can't create text_object! code #". OBJ_LABEL. return(0). 0. } // new label object if(!ObjectCreate("label_object". 0. 100).GetLastError()). 200). OBJPROP_XDISTANCE.Metatrader Development Course http://www. 1.metatrader. It's an optional parameter which you can use it if your object uses 3 coordinates. 0)) { Print("error: can't create label_object! code #". ObjectDelete: Syntax: bool ObjectDelete(string name) Description: The ObjectDelete function deletes the object by its name (you have to provide the exact name of the object). D'2004.GetLastError()). OBJPROP_YDISTANCE. } ObjectSet("label_object". OBJ_TEXT. 0. double price3: The third horizontal coordinate of the object. Parameters: string name: The string name of the object you want to delete.

info/book/print/34 Example: ObjectDelete("text_object"). ObjectDescription: Syntax: string ObjectDescription(string name) Description: The ObjectDescription function returns the description of the object (Figure 6).Object description Figure 7 Parameters: string name: 171 of 258 6/14/2006 5:36 PM . For the objects OBJ_TEXT and OBJ_LABEL which has no description the returned value is the text drawn by these objects (Figure 7).Mql .Metatrader Development Course http://www.metatrader. Figure 6.

int index) Description: The ObjectGet function returns the value of the specified object property of the given index.Metatrader Development Course http://www. ObjectGet: Syntax: double ObjectGet(string name. int index: The property index which can be one of these values: 172 of 258 6/14/2006 5:36 PM . Parameters: string name: The string name of the object you want to get one of its proporties. For example to get the first vertical (time) of the object use ObjectGet(object_name.metatrader. Example: if(ObjectFind("line_object2")!=win_idx) return(0).info/book/print/34 The string name of the object you want to get its description. The chart main window is 0 index and the first chart sub-window is 1 then 2 etc.Mql . ObjectFind: Syntax: int ObjectFind(string name) Description: The ObjectFind function searches all the drawn objects for the specified object name and returns the index of the window that host the object if found and returns -1 if the object not found. 0). Parameters: string name: The string name of the object you want to search for. Example: Print(ObjectDescription("Text 44465")).

# . ! ! ! 7 B) '+ 3 = = 1 = .metatrader. $ 1 = 8 = = 1 . 8 $. ! ! '+ >7 03 5 0 5 3 1 > ! 7 B) '+ 2 B) 1 ' '+ 5 * 1 ' ) ) A1 ! . & = = 1 & = 1 = . $ . # !$. " " " " 1 * .info/book/print/34 Constant Value Type Description = = = = = = = = = .1$ = $ % = $ = = ! = 8 = 1 . A! E " & " E ' Example: color oldColor=ObjectGet("hline12". ( . ! ( 5 * '+ & 5 B) B) 8' '+ 5 !7 . 7.* = <! . # ( = = = = = = = = = = = = = = = = = A! = = = = . *' " & / 2 4 6 *' *' ! ! *' ! ! *' ! ! *' 1 * . $ 1 = #! . # . " = = 1 " = . OBJPROP_COLOR). 173 of 258 6/14/2006 5:36 PM . # . # B) = = = = 8 . 5 '+ ' @) * ( ) ) '+ ' ( ( ) 0 '+ '+ 5 ' ( 0 3 1 0 ) ' ) '+ 2 5 * 5 * 5 * 5 * 5 * 5 * 5 * !$.Mql . # . ! B) B) B) B) B) B) B) 3 '+ !7 .C $1? $# =. # . 7. # 5 ) 8' " & > ) &" 5 * 5 * !$. . 7 . # !$.Metatrader Development Course http://www. # !$. # !$. " & / 2 4 *' 9 : ' ' ' *' *' ! *' ! *' ) * ! *' '+ ) ) ' 5 * 5 * ) 5 * 5 * 5 * 5 * 5 * 5 * 5 * ( ' B) 5 * 5 * 5 * D& B) B) 3 3 < # '+ '+ ( ( > B) B) B) 3 5 > B) B) B) B) B) B) 0 ) * ' -' 0 '+ ( '+ ( ' '+ '+ '+ B) . 7 .

The index of Fibonacci object levels start from bottom upward and you can use up to 32 levels.metatrader. int index: The index of the level (line) you want to get its level description. Figure 8 Parameters: string name: The string name of the Fibonacci object you want to get its level description. For example in Figure 8 the description of the second line from bottom (its index is 0) is "23.Metatrader Development Course http://www.Mql . int index) Description: The ObjectGetFiboDescription function returns the description of the given Fibonacci object level. ObjectGetShiftByValue: 174 of 258 6/14/2006 5:36 PM .6". Example: Print(ObjectGetFiboDescription("Fibo 2638". 1)).info/book/print/34 ObjectGetFiboDescription: Syntax: string ObjectGetFiboDescription(string name.

Hope you find the lesson helpful one and hope to see your comments! Coders Guru! 175 of 258 6/14/2006 5:36 PM .metatrader. Figure 9 Parameters: string name: The string name of the object you want to get the bar index for one of its prices (values) double value: The price value of the object. In the next lesson we are going to continue with the remaining Object Function and we are going to make a simple MQL program to apply what we learnt about the objects programming.2156 of the Trendline object is the bar 11. double value) Description: The ObjectGetShiftByValue function returns the index of the bar (shifted from the current . 1.0 upward) for the given price of the given object.Metatrader Development Course http://www. Foe example in figure 9 the bar index for the price 1.2156)).Mql . This price is calculated with the first and second coordinates of the object (using liner equation). Example: Print(ObjectGetShiftByValue("Trendline 5879".info/book/print/34 Syntax: int ObjectGetShiftByValue(string name.

datetime time1: The first vertical coordinate of the object. double price1: The first horizontal coordinate of the object.info/book/print/34 Object Functions . int point: Coordinate index (0.Metatrader Development Course http://www. Parameters: string name: The string name of the object you want to change its coordinate. The function returns true if it successfully had changed the coordinate and false otherwise. Let's see what left of the object functions: ObjectMove: Syntax: bool ObjectMove(string name.metatrader. Any object has up to 3 coordinates and they are indexed 0. This parameter is a double type (because the horizontal coordinate of the chart is the price coordinate). you have to use ObjectMove function 2 or 3 times for every coordinate.Part 2 Hi folks. datetime time1. Example: 176 of 258 6/14/2006 5:36 PM . 1. Today we are going to continue with the remaining of Object Functions and we have a simple MQL program to apply some of what we have learnt about drawing objects programicaly. int point. You specify the coordinate you want to change with its index (point parameter) then set new x and y values for the new coordinate (time1 and time2). Note: You have to note which currency pair you are going to draw on its chart because the prices ranges differs from currency to currency. This parameter is a datetime type (because the vertical coordinate of the chart is the time coordinate). double price1) Description: The ObjectMove function changes the specified coordinate of the object to new x and y coordinate. 1 and 2. Note: If you have a 2 or 3 coordinates object and want to change the 2 or 3 coordinates. 2) you want to change it.Mql .

Note: The index must be equal to 0 or greater. Should I use the Ask or the Bid price? What about the Stop loss is it going below or above the Ask or the Bid price? What about the Take profit? When I open a Sell order using OrderSend function." Could you please answer me only one question: When I open a Buy order using OrderSend function. } OrderSend .02. Should I use the Ask or the Bid price? What about the Stop loss is it going below or above the Ask or the Bid price? What about the Take profit? What about BUYLIMIT.metatrader. 1. string name. Example: int obj_total=ObjectsTotal(). SELLLIMIT and SELLSTOP orders? 177 of 258 6/14/2006 5:36 PM . for(int i=0. ObjectName: Syntax: string ObjectName(int index) Description: The ObjectName function returns the object name for the given index from the object list.i<obj_total. and be less than the total of the objects count returned by ObjectsTotal() function. BUYSTOP.Mql . now I have a brain pain! I just spent the morning scanning thru the MQL4 and MetaTrader help file pages to try and track down if I missed anything.Metatrader Development Course http://www."Object name is " + name).Type of orders! Hi folks. Print(i. "OK.25 12:30'. 1. D'2005.i++) { name=ObjectName(i). Parameters: int index: The index of the object you want to get its name.info/book/print/34 ObjectMove("MyTrend".2345). To check the error use GetLastError() function.

Ask+TakeProfit*Point. OP_SELL Bid Bid+StopLoss Bid-TakeProfit You Sell at the current Bid price of the currency! You set the StopLoss Above (+) the Bid price! You set the TakeProfit Below (-) the Bid price! Example: OrderSend(Symbol().Metatrader Development Course http://www. Bid+StopLoss*Point.0.the level price! Example: OrderSend(Symbol(). 178 of 258 6/14/2006 5:36 PM .slippage.”comment”.0. OP_BUYLIMIT Ask-Level Ask-Level-StopLoss Ask-Level +TakeProfit You Buy at future price level Below the current Ask price of the currency! You set the StopLoss Below (-) the Ask .Ask-Level*Point. ”comment”.0.slippage.Bid-TakeProfit*Point.0.”comment”.Lots.0.info/book/print/34 Is that the only one question? Well here’s the answer! OP_BUY Ask Ask-StopLoss Ask+TakeProfit You Buy at the current Ask price of the currency! You set the StopLoss Below (-) the Ask price! You set the TakeProfit Above (+) the Ask price! Example: OrderSend(Symbol().Green). ( Ask-Level*Point)+TakeProfit*Point.slippage.OP_BUY.Lots.the level price! You set the TakeProfit Above (+) the Ask .Green). (Ask-Level*Point)-StopLoss*Point.metatrader.OP_SELL.Green).OP_BUYLIMIT.Ask.Mql . Ask-StopLoss*Point.Bid.0.Lots.

OP_SELLLIMIT Bid+Level Bid +Level +StopLoss Bid+Level –TakeProfit You Sell at future price level Above the current Bid price of the currency! You set the StopLoss Above (+) the Bid + the level price! You set the TakeProfit Below (-) the Bid + the level price! Example: OrderSend(Symbol().Green). (Bid +Level*Point)-TakeProfit*Point.Green).OP_SELLLIMIT.Green).OP_SELLSTOP.metatrader.0.0.0.0.Mql .Bid-Level*Point.slippage.Bid+Level*Point.”comment”.slippage.info/book/print/34 OP_BUYSTOP Ask+Level Ask+Level -StopLoss Ask+Level +TakeProfit You Buy at future price level Above the current Ask price of the currency! You set the StopLoss Below (-) the Ask + the level price! You set the TakeProfit Above (+) the Ask + the level price! Example: OrderSend(Symbol().Lots.slippage.the level price! Example: OrderSend(Symbol().Lots. 179 of 258 6/14/2006 5:36 PM . (Bid -Level*Point)-TakeProfit*Point.0. (Bid+Level*Point)+StopLoss*Point.Metatrader Development Course http://www.0.”comment”. (Bid-Level*Point)+StopLoss*Point. (Ask+Level*Point)-StopLoss*Point. ( Ask+Level*Point)+TakeProfit*Point.Ask+Level*Point. OP_SELLSTOP Bid-Level Bid -Level +StopLoss Bid-Level-TakeProfit You Sell at future price level Below the current Bid price of the currency! You set the StopLoss Above (+) the Bid + the level price! You set the TakeProfit Below (-) the Bid .”comment”.Lots.OP_BUYSTOP.

Metatrader Development Course http://www. Bid. the Predefined variables. High. They are price related variables that reflect the current price data the chart had got. Digits. the really matter is how to use them! Let's study the Predefined variables set: StringConcatenate: Syntax: double Ask Description: The Ask function return the last known Ask price (the sell price) for the current symbol. So. Bars. is it a variable? Another example will proof for you that they are not variables: If you type and compile this line of code: Bars=1. To be sure it reflects the actual market price you have to use the RefreshRates() function. High. For example Bars collects and returns the number of the bars in chart. Point and Volume are functions Although MetaQuotes called them predefined variables. it doesn't matter what should you call them.Mql . Open. Anyway.unexpected token That’s because they are not variables hence you can’t assign a value to them. Time. Today we are going to talk about a very important topic. Open. Bars. while function means "do something and return some value". These is the list of the predefined variables: Ask. Close. Time.metatrader. Low.info/book/print/34 Predefined variables Hi folks. Note: To get the Ask price for a Parameters: 180 of 258 6/14/2006 5:36 PM . I still considering them functions (I'm going to tell you why later) but I'll use Predefined variables as MetaQuotes has mentioned them. Point and Volume I'm calling them functions because: Ask. Low. Bid. Digits. Variable means "a space in memory and data type you specify". What are the Predefined variables? The Predefined variables are set of the most important variables which MetaTrader set continuously for every loaded chart. Close. You will get this error: 'Bars' .

0. They are the MQL4 functions we need to handle the string variables! Let's give the string data type an overview first! string data type: 181 of 258 6/14/2006 5:36 PM . thess two values are always the same as Open[0](when running tester tool of MetaTrader.Close price How can i get the close.0) it will equal to Close[0]. 0. Low[0] returns the low price of the current bar and Open[0] returns the open price of the current bar) iClose function is very like Close function but it can return the close price for another symbol and timframe. 0) to get close price of current bar. high price of current bar? When I use Close[0]. Many thanks for reading! ---------. demo account) ? The same for low and high prices? Please tell me how can i figure out it. Coders Guru String functions Hi folks. Our set of functions today are the String Functions. low.Metatrader Development Course http://www. right now I'm running MIG Trade Station.info/book/print/34 Example: Questions . iLow and iOpen functions). (The same is true for the iHigh.REPLY ----------------Hi there! Close[0] returns the close price of the current bar (The same is true for the High[0] return the high price of the current bar.metatrader. iClose(Symbol(). If you used it like this: iClose(NULL.Mql .

This array of characters is an array which holds one character after another. Note: (.) means that you can pass to this function any kind of data type and any number of parameters separated by comma.Metatrader Development Course http://www. For example: string str1 = "Hello world!. You can pass to this function any kind of data type except the arrays and any number of parameters separated by comma very like the Print(). The bool. \"Forex-tsd forum\". a NULL character is placed in the next array location.. Now let's study the MQL4 functions concerned about the Strings: StringConcatenate: Syntax: string StringConcatenate( . If you want to pass a double data type to this function the number of digits will be used are 4 digits if you want to change this number you have to use the function DoubleToStr(). string str3 = "1234567890"...Mql . color and datatime passed to function will be printed in their numeric presentation. 182 of 258 6/14/2006 5:36 PM . //Notice the use of (") character. with you coders guru”.".metatrader. starting at index 0. . A NULL character is a special character (represented by the ASCII code 0) used to mark the end of this type of string. Figure 1 – Characters array MQL4 limits the size of the string variable to 255 characters and any character above 255 characters will generate this error: (too long string (255 characters maximum)). After the last character of data. if you want to print them in string format use the string name of the bool or the color value and for the datetime use the function TimeToStr(). ) Description: The StringConcatenate function take the set of parameters passed to it and glue them together and returns them as a string. Alert() and Comment() functions. See figure 1 for a simple representation of the string constant “hello” in the characters array.. It does not matter if there are unused array locations after that.info/book/print/34 The string data type is an array of characters enclosed in double quote ("). string str2 = "Copyright © 2005. We use the keyword string to create a string variable.

Metatrader Development Course http://www. AccountFreeMargin(). The default value is 0 which means to search from the start of the string. if the function find the substring it returns its position. if the function didn't find the substring it returns -1. text=StringConcatenate("Account free margin is ". Example: string text. int start=0) Description: The StringFind function search for substring (part of the given string for example "gur" is substring from the string "codersguru") in a given string. separated by commas.metatrader. Any values. StringFind: Syntax: int StringFind( string text. string matched_text The substring you want to find it in the string. int start=0 The index of the starting position for the search.. the first character in the string has the index 0 then 1 then 2 etc.info/book/print/34 Note: You can use the + operator to add string to another string for example "coders" + "guru" will produce "codersguru". Example: 183 of 258 6/14/2006 5:36 PM . string matched_text.Mql . // slow text="Account free margin is " + AccountFreeMargin() + "Current time is " + TimeToStr(CurTime()) Print(text). TimeToStr(CurTime())). Parameters: This function takes two parameters: string text The string you want to search in it for the substring.. however MetaTrader saying that StringConcatenate() function works faster gluing strings together. Parameters: This function takes any number of parameters: . "Current time is ".

int index=StringFind(text.metatrader.Mql . Example: int char_code=StringGetChar("abcdefgh". 3). don't forget that the string array starts with 0.info/book/print/34 string text="The quick brown dog jumps over the lazy fox". "dog jumps". 0). // char code 'c' is 99 StringLen: Syntax: int StringLen( string text) Description: The StringLen function returns how many character (the length) of the given string. int pos) Description: The StringGetChar function returns the character in a given position from a given string. StringGetChar: Syntax: int StringGetChar( string text. if(index!=16) Print("oops!"). it return it as character code (the ASCII code of the character).Metatrader Development Course http://www. int pos The position of the character you want to get. Parameters: This function takes two parameters: string text The string you want to get the character from. Parameters: 184 of 258 6/14/2006 5:36 PM .

Example: string str="abcdefgh". StringSetChar: Syntax: string StringSetChar( string text. string str1=StringSetChar(str.. // str1 is "abcDefgh" StringSubstr: 185 of 258 6/14/2006 5:36 PM .info/book/print/34 This function takes only one parameter: string text The string you want to get its length. int pos The position of the character you want to change.Mql . Example: string str="some text". int value The new character you want to set it. int pos.Metatrader Development Course http://www.metatrader. Parameters: This function takes three parameters: string text The string you want change a character in it. 3. 'D'). if(StringLen(str)<5) return(0). int value) Description: The StringSetChar function change one character of the given string in a given position to another character and returns the new string.

string substr=StringSubstr(text. Let's give these functions a brief look: 186 of 258 6/14/2006 5:36 PM . int start. how to make an expert advisor that can open Buy position of GBPUSD or USDCHF while the expert advisor is hosted on EURUSD chart?" Good question. int count=EMPTY The count of character you want to extract.Metatrader Development Course http://www. int start Where to start your extracting.Part 1 Hi folks.info/book/print/34 Syntax: string StringSubstr( string text. The default value is EMPTY.Mql . The function returns the extracted string if any or it returns EMPTY string. Huh? To reply these related questions we have to start with studding the Timeseries Access functions. Parameters: This function takes three parameters: string text The string you want to extract from it. Example: string text="The quick brown dog jumps over the lazy fox". // subtracted string is "quick" word Timeseries access functions . The Timeseries Access functions are a set of functions that enables us to access the price date of any chart (currency and timeframe) regardless of the chart that hosts the expert advisor. I've got a lot of messages asking me "How to deal with currency pairs which are different than the current chart currency (The chart that hosts the expert advisor)? For example.metatrader. 5). 4. int count=EMPTY) Description: The StringSubstr function extracts the string from given position to a given count (ex: "codersguru" the position is 3 and the count is 2 then the extracted string is "de").

. In this case and with the all of the Timeseries access functions you have to check the the last was the error # 4066 ERR_HISTORY_WILL_UPDATED (which means the requested data is under updating) to be sure that the price data is up-to-date. Note: If you want to get the number of bars of the current chart (symbol and timeframe) use Bars function. Use 0 if you want to use current timeframe. Note: You can use the integer representation of the timeframe (period in minutes) or you can use the timeframes constants: = = = = = = = = = - ! .30. Parameters: string symbol: The symbol (currency pair) of the chart you want to get its bars number.5. ! .Metatrader Development Course http://www.Mql .metatrader.info/book/print/34 iBars Syntax: int iBars( string symbol. And retry your request for the price data. int timeframe) Description: The iBars function returns the number of Bars of the specified chart. Use NULL if you want to use current symbol. 2 ! . you specify the chart by the symbol name and the timeframe. int timeframe: The timeframe (in integers. @( 3( * 3 3 ! ! ! A ! . Note: If the chart of the symbol and timeframe you are trying to get its price data is not opened.& ! ! / 2 2 & 4 "/ // 9 /&" & 2 2 * * * * 3 * /3 * ! ( A . 187 of 258 6/14/2006 5:36 PM . MetaTrader will try to connect to the server to retrieve the request price data. ex: 1.2 ! .60 etc) of the chart you want to get its bars number.

use exact =false (default) and and the function will return -1 if the open time not found.5. If you want the iBarShift function to return the nearest bar to the given open time set the exact parameter to true.iBars("EUROUSD".60 etc) of the chart you want to get its bars number. Print("shift of bar with open time ".30.metatrader. Use NULL if you want to use current symbol. 188 of 258 6/14/2006 5:36 PM .PERIOD_M1. Use 0 if you want to use current timeframe. Example: datetime some_time=D'2004. And use exact =true and the function will return the nearest bar to the given open time. datetime time.shift). int timeframe. ex: 1. Parameters: string symbol: The symbol (currency pair) of the chart you want to get its bars number. bool exact=false) Description: The iBarShift function takes the open time of the bar for a specified symbol and timeframe and searches for this bar and returns it if found otherwise it returns -1.03. int shift=iBarShift("EUROUSD". int timeframe: The timeframe (in integers.Mql .info/book/print/34 Example: Print("Bar count on the 'EUROUSD' symbol with PERIOD_H1 is".PERIOD_H1))." is ".TimeToStr(some_time).21 12:00'. datetime time: The open time of the bar you want to search for bool exact: The search mode.Metatrader Development Course http://www. iBarShift: Syntax: int iBarShift( string symbol.some_time).

The function returns 0 if the history data not loaded. int shift: The index of the bar you want to get its Close price. int timeframe.60 etc) of the chart you want to get its bars number. Use 0 if you want to use current timeframe.5. int timeframe: The timeframe (in integers.PERIOD_H1. int shift) Description: The iClose function returns the Close price for the given bar (the shift parameter is the bar number) of the given symbol and timeframe. ex: 1. iHigh: Syntax: double iHigh( string symbol.metatrader. Note: It's very important (and always error's source) to know that the current bar is 0 and the previous bar is 1 etc.info/book/print/34 iClose: Syntax: double iClose( string symbol.30.Mql .i)). int shift) 189 of 258 6/14/2006 5:36 PM . Example: Print("Current Close price for USDCHF H1: ". Use NULL if you want to use current symbol. Parameters: string symbol: The symbol (currency pair) of the chart you want to get its bars number.Metatrader Development Course http://www.iClose("USDCHF". Note: If you want to get the Close price (of a bar) of the current chart (symbol and timeframe) use Close[int shift] function. int timeframe.

190 of 258 6/14/2006 5:36 PM .info/book/print/34 Description: The iHigh function returns the High price for the given bar (the shift parameter is the bar number) of the given symbol and timeframe.i)).PERIOD_H1. Parameters: string symbol: The symbol (currency pair) of the chart you want to get its bars number. ex: 1.Metatrader Development Course http://www.30. Use NULL if you want to use current symbol. Use 0 if you want to use current timeframe. Note: If you want to get the Low price (of a bar) of the current chart (symbol and timeframe) use Low[int shift] function.5. Note: If you want to get the High price (of a bar) of the current chart (symbol and timeframe) use High[int shift] function. int timeframe: The timeframe (in integers. Example: Print("Current High price for USDCHF H1: ". The function returns 0 if the history data not loaded. The function returns 0 if the history data not loaded.iHigh("USDCHF". iLow: Syntax: double iLow( string symbol.metatrader. int shift: The index of the bar you want to get its High price.60 etc) of the chart you want to get its bars number. int shift) Description: The iLow function returns the Low price for the given bar (the shift parameter is the bar number) of the given symbol and timeframe. int timeframe.Mql .

PERIOD_H1.30.Metatrader Development Course http://www. The function returns 0 if the history data not loaded. Use 0 if you want to use current timeframe.info/book/print/34 Parameters: string symbol: The symbol (currency pair) of the chart you want to get its bars number.60 etc) of the chart you want to get its bars number. int shift) Description: The iOpen function returns the Open price for the given bar (the shift parameter is the bar number) of the given symbol and timeframe.5.i)). Use NULL if you want to use current symbol. int timeframe: The timeframe (in integers. iOpen: Syntax: double iOpen( string symbol. int shift: The index of the bar you want to get its Low price.60 etc) of the chart you want to get its bars number. Example: Print("Current Low price for USDCHF H1: ". Parameters: string symbol: The symbol (currency pair) of the chart you want to get its bars number. ex: 1. Use NULL if you want to use current symbol. Use 0 if you want to use current timeframe. int timeframe. Note: If you want to get the Open price (of a bar) of the current chart (symbol and timeframe) use Open[int shift] function.Mql .iLow("USDCHF". int shift: 191 of 258 6/14/2006 5:36 PM .30.metatrader.5. int timeframe: The timeframe (in integers. ex: 1.

Parameters: string symbol: The symbol (currency pair) of the chart you want to get its bars number.30.PERIOD_H1. Note: If you want to get the bar Open Time (of a bar) of the current chart (symbol and timeframe) use Time[int shift] function.60 etc) of the chart you want to get its bars number. int timeframe. Use 0 if you want to use current timeframe.metatrader.i)).Mql . int timeframe: The timeframe (in integers. Use NULL if you want to use current symbol. 192 of 258 6/14/2006 5:36 PM . int shift) Description: The iTime function returns the Open Time of the given bar (the shift parameter is the bar number) of the given symbol and timeframe. ex: 1. int shift: The index of the bar you want to get its Open Time. Example: Print("Current Open price for USDCHF H1: ".info/book/print/34 The index of the bar you want to get its Open price. iTime: Syntax: datetime iTime( string symbol.5.iTime("USDCHF".i)).Metatrader Development Course http://www. Example: Print("The Open Time of the current bar for USDCHF H1: ".iOpen("USDCHF".PERIOD_H1.

193 of 258 6/14/2006 5:36 PM .i)). int timeframe: The timeframe (in integers.go trading only for first tiks of new bar if(Volume[0]>1) return. int shift) Description: The iVolume function returns the Tick Volume value of the given bar (the shift parameter is the bar number) of the given symbol and timeframe. etc). Use NULL if you want to use current symbol.30.60 etc) of the chart you want to get its bars number. int shift: The index of the bar you want to get its Tick Volume value. hour.Metatrader Development Course http://www. Example: //---.. Note: If you want to get the Tick Volume value (of a bar) of the current chart (symbol and timeframe) use Volume[int shift] function. Use 0 if you want to use current timeframe. day.info/book/print/34 iVolume: Syntax: double iVolume( string symbol. week. Example: Print("Current Tick Volume for USDCHF H1: ". Parameters: string symbol: The symbol (currency pair) of the chart you want to get its bars number.g.PERIOD_H1.iVolume("USDCHF".metatrader. Note: In MQL if you want to check if the tick is the first tick of the new bar you can check Volume[0] it will be 0 if it's the first tickof the new bar. Note: Volume is simply the number of shares (or contracts) traded during a specified time frame (e. ex: 1. month.5.Mql . int timeframe.

int type: The type of values (Series array) to be calculated.Mql . ex: 1.30. int count=WHOLE_ARRAY. it can be one of these types: Constant Value Description MODE_OPEN 0 Open price. the default value is 0 which means to start from the current bar. MODE_VOLUME 4 Volume.Metatrader Development Course http://www. The default value is WHOLE_ARRAY which means all the bars (values in the series array). 194 of 258 6/14/2006 5:36 PM . int start=0) Description: The Highest function calculate the Highest value of the specified type (Close price.5. Parameters: string symbol: The symbol (currency pair) of the chart you want to get its bars number. int timeframe. int count: How many bars you want to calculate its Highest value. use this parameter with start parameter to determine the range of bars to be calculated. int type. MODE_HIGH 2 High price.metatrader. MODE_TIME 5 Bar Open time. High price etc) for a specified bars of the given symbol and timeframe. Open price. Use NULL if you want to use current symbol.60 etc) of the chart you want to get its bars number. MODE_CLOSE 3 Close price. MODE_LOW 1 Low price. You use the type parameter to determine the type of the values to be calculated and the parameters count and start determine the bars to be calculated. int start: The bar to start the calculation from. int timeframe: The timeframe (in integers.info/book/print/34 Highest: Syntax: int Highest( string symbol. Use 0 if you want to use current timeframe.

int count=WHOLE_ARRAY. ex: 1. 195 of 258 6/14/2006 5:36 PM .metatrader.30. Parameters: string symbol: The symbol (currency pair) of the chart you want to get its bars number. Open price. the default value is 0 which means to start from the current bar.5.4)].Metatrader Development Course http://www.Mql . int type. int timeframe: The timeframe (in integers. // calculating the highest value in the range from 5 element to 25 element // indicator charts symbol and indicator charts time frame val=High[Highest(NULL. int timeframe. use this parameter with start parameter to determine the range of bars to be calculated.0. int count: How many bars you want to calculate its Highest value. You use the type parameter to determine the type of the values to be calculated and the parameters count and start determine the bars to be calculated. The default value is WHOLE_ARRAY which means all the bars (values in the series array).20. int type: The type of values (Series array) to be calculated.MODE_HIGH. Use 0 if you want to use current timeframe. Lowest: Syntax: int Lowest( string symbol.info/book/print/34 Example: double val. High price etc) for a specified bars of the given symbol and timeframe. Use NULL if you want to use current symbol.60 etc) of the chart you want to get its bars number. int start: The bar to start the calculation from. int start=0) Description: The Lowest function calculate the Lowest value of the specified type (Close price.

Metatrader Development Course http://www. int bar=FirstVisibleBar().0.Mql . i<bars_count.info/book/print/34 Example: double val=Low[Lowest(NULL.10. the question is: Is this enough to write our expert advisor that deals with other currency pairs? No! In the coming lesson we are going to know the most important function needed to write this kind of expert advisors. I hope you find it a useful lesson! Windows functions Hi folks.10)]. int bars_count=BarsPerWindow(). These functions are infrequently used (expect WindowsTotal(). the MarketInfo() function..metatrader. i++. Example: // work with visible bars. } 196 of 258 6/14/2006 5:36 PM .bar--) { // . WindowFind() and ScreenShot functions) but as a MQL4 programmer you have to know them.MODE_LOW. Now we have the tools to access the price data of the other charts.. Note: Resizing the chart window or changing the chart period changes this number. These are the Windows functions set: BarsPerWindow: Syntax: int BarsPerWindow( ) Description: The BarsPerWindow function returns the number of bars visible for the user on the chart. for(int i=0. We are going to study today a set of functions that responsible of handling the chart windows. Parameters: The function doesn't take any parameters.

info/book/print/34 caption=FirstVisibleBar() type=int Function returns index of the first visible bar.. } TimeOnDropped: Syntax: 197 of 258 6/14/2006 5:36 PM .metatrader.may be undefined (zero) if(drop_time>0) { ObjectCreate("Dropped price line". Parameters: The function doesn't take any parameters. drop_time). Example: double drop_price=PriceOnDropped(). } PriceOnDropped: Syntax: double PriceOnDropped( ) Description: The PriceOnDropped function returns the price of the currency of the chart from the point you dragged and release the expert advisor or the script at. 0. i++. 0. datetime drop_time=TimeOnDropped(). i<bars_count.Metatrader Development Course http://www. int bars_count=BarsPerWindow(). drop_price). OBJ_VLINE. This function works only with the expert advisors and script and doesn't work with the custom indicators.Mql . //---. ObjectCreate("Dropped time line". OBJ_HLINE. for(int i=0. int bar=FirstVisibleBar(). the PriceOnDropped returns the price at this point.bar--) { // .. When you click the expert advisor or the script in the navigator window and hold the left button mouse then drag it and release the left mouse buttons at any point on the chart. // work with visible bars.

int start_bar=-1. int size_x: The width of the screen shot. The function returns True if it successfully saved the screen shot and false if it failed. 0. 0. It saves the screen shot as GIF file in one of two folder: If you used the function in the live mode it'll save the screen shot in terminal_dir\experts\files and its subdirectories. int chart_mode=-1) Description: The ScreenShot function save a screen shot of the current chart. datetime drop_time=TimeOnDropped(). This function too works only with the expert advisors and script and doesn't work with the custom indicators. 198 of 258 6/14/2006 5:36 PM .Mql . drop_price).may be undefined (zero) if(drop_time>0) { ObjectCreate("Dropped price line". Example: double drop_price=PriceOnDropped(). ObjectCreate("Dropped time line". string filename: The file name that the function will save the screen shot to. If you used the function in the testing mode it'll save the screen shot in terminal_dir\tester\files and its subdirectories.Metatrader Development Course http://www. drop_time).info/book/print/34 datetime TimeOnDropped( ) Description: The TimeOnDropped function returns the time of on the chart where you dragged and release the expert advisor or the script at. int size_y.metatrader. OBJ_HLINE. } ScreenShot: Syntax: bool ScreenShot( string filename. //---. You can combine the file name with a subdirectory to tell the function where to save the file. Parameters: The function doesn't take any parameters. OBJ_VLINE. Parameters: The function takes 6 parameters. int chart_scale=-1. int size_x.

The default vaule is -1 which means the end-of-chart screen shot will be taken. int chart_scale=-1: The scale (Zoom In and Zoom Out) of the chart screen shot that will be taken. It ranges from 0 to 5. else ExtShotsCounter++.gif". Example: int lasterror=0. int start_bar=-1: The index of the first bar you want to include in your screen shot. it can be one of these values: CHART_BAR (0) CHART_CANDLE (1) CHART_LINE (2) The default value is -1 which means the function will use the chart mode.Metatrader Development Course http://www. ExtTradesCounter=TradesTotal().info/book/print/34 int size_y: The height of the screen shot.tester has closed one or more trades if(IsTesting() && ExtTradesCounter<TradesTotal()) { //---.480)) lasterror=GetLastError(). 0 means the first visible bar on the chart.Mql . int chart_mode=-1 The mode of the chart screen shot that will be taken.metatrader. Note: If the indicator search for his name in the init() function using WindowFind() function it always 199 of 258 6/14/2006 5:36 PM .make screenshot for further checking if(!ScreenShot("shots\\tester"+ExtShotsCounter+".640. //---. The default value is -1 which means the function will use the current scale of the chart. } WindowFind: Syntax: int WindowFind(string name) Description: The WindowFind function searches the chart sub windows for the indicator short name passed to it and returns the window index if found and -1 otherwise! Note: The indicators name can be set using the function IndicatorShortName().

Parameters: The function takes only one parameter. Example: int win_idx=WindowFind("MACD(12. Parameters: The function takes two parameters: string symbol: The symbol name you want to search for and return its window index. Example: int win_handle=WindowHandle("EURUSD".H1 detected.info/book/print/34 returns -1. WindowHandle: Syntax: int WindowHandle(string symbol.9)").PERIOD_H1). int timeframe: The timeframe you want to search for and return its window index.Metatrader Development Course http://www. Note: The chart window you are searching must have the symbol name and the timeframe to return the window handle.metatrader. int timeframe) Description: The WindowHandle function searches all the opened chart for the symbol (currency pairs) and timeframe passed to it and returns the window handle of the chart window if found and -1 otherwise. if(win_handle!=0) Print("Window with EURUSD. Rates array will be copied immediately.Mql . WindowIsVisible: 200 of 258 6/14/2006 5:36 PM .26. if the one of the two conditions is found and other not found the return value is -1."). string name: The name of the indicator short name you want to search for and return its window index.

if(maywin>-1 && WindowIsVisible(maywin)==true) Print("window of MyMACD is visible").Mql . return(false). } 201 of 258 6/14/2006 5:36 PM .Metatrader Development Course http://www. else Print("window of MyMACD not found or is not visible"). Example: int maywin=WindowFind("MyMACD"). Example: if(WindowOnDropped()!=0) { Print("Indicator 'MyIndicator' must be applied to main chart window!"). WindowOnDropped: Syntax: int WindowOnDropped() Description: The WindowOnDropped function returns the index of the window you dragged and released the expert advisor. indicator or the script on.info/book/print/34 Syntax: bool WindowIsVisible(int index) Description: The WindowIsVisible function returns true if the chart sub-window index passed to it is visible to the user and false otherwise. Parameters: The function takes only one parameter: int index: The index of the chart sub-window you want to check its visibility.metatrader. Parameters: The function doesn't take any parameters.

Parameters: The function doesn't take any parameters. Parameters: The function doesn't take any parameters.WindowXOnDropped().info/book/print/34 WindowsTotal: Syntax: int WindowsTotal() Description: The WindowsTotal function returns the count of windows (sub-windows and main window) on the chart. WindowsTotal())." y=".WindowYOnDropped()).metatrader. Example: Print("Expert dropped point x=". WindowYOnDropped: Syntax: int WindowYOnDropped() Description: 202 of 258 6/14/2006 5:36 PM . indicator or the script on.Metatrader Development Course http://www. WindowXOnDropped: Syntax: int WindowXOnDropped() Description: The WindowXOnDropped function returns the x-axis coordinate in pixels of the point you dragged and released the expert advisor. Example: Print("Windows count = ".Mql .

the script will be executed only for once.info/book/print/34 The WindowYOnDropped function returns the Y-axis coordinate in pixels of the point you dragged and released the expert advisor. I hope you enjoyed the journey and interested to continue the road with me. Unlike the expert advisors which will be called every time in a new tick arrival. In short the script is an expert advisor which you can run only once.Mql . 203 of 258 6/14/2006 5:36 PM . indicator or the script on. What are we waiting for? Let’s script! What’s a MQL4 script? The scrip is a program you run once to execute an action and it will be removed immediately after the execution. Example: Print("Expert dropped point x=". Lesson 17 . Congratulations! You learnt the basics of MQL4 language then you wrote your first indicator and your first expert advisor. Let's create our first script! Wizards again! With the help of the New Program wizard we will create the backbone of our scrip. It’s useful if you are lazy to set manually your stoploss and takeprofit values from the Modify or Delete Orders window for every order." y=".WindowXOnDropped(). Bring the New Program wizard by choosing New from File menu or by clicking CTRL+N hot keys (Figure 1). so choose Scrip program in the wizard and click next.Metatrader Development Course http://www. We are going to create a script. Parameters: The function doesn't take any parameters. the script has no access to indicator functions.Your First Script It was a long path for you to reach this lesson. And unlike the indicators which have the ability to draw lines on the chart.WindowYOnDropped()). Today we will create our first script which will simply set the stoploss and takeprofit values for all the already opened orders on the chart.metatrader.

Author and Link fields with what you see in the figure 2 (or whatever you want).mq4 | //| Copyright Coders Guru | //| http://www.forex-tsd. we have to add our code to make our script more useful. Now. That’s because it’s rare to find a script needs to execute code in the program initialization and de-initialization because the start() function itself will be executed for once.info/book/print/34 That will bring the second step wizard (Figure 2). Then click finish.com" //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start() { //---//---return(0).metatrader. Fill the Name. But that’s not mean you can’t add init() and deinit() functions in a script. 204 of 258 6/14/2006 5:36 PM . } //+------------------------------------------------------------------+ Note: As you can easily notice from the above code that the wizard hasn’t added the init() and deinit() functions and only added the start() function. this is the code we have got from the wizard.forex-tsd. You can add them if you want.Metatrader Development Course http://www.com | //+------------------------------------------------------------------+ #property copyright "Copyright Coders Guru" #property link "http://www. //+------------------------------------------------------------------+ //| My_First_Script. Figure 1 – New Program wizard Figure 2 – Step 2 By clicking Finish button the wizard will write some code for you and left the places to write your own code.Mql .

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

This is the code we have added to the above wizard’s generated code (our added code marked by the bold font): //+------------------------------------------------------------------+ //| My_First_Script.mq4 | //| Copyright Coders Guru | //| http://www.forex-tsd.com | //+------------------------------------------------------------------+ #property copyright "Copyright Coders Guru" #property link "http://www.forex-tsd.com" #property show_inputs #include <stdlib.mqh> extern double TakeProfit=250; extern double StopLoss=35; //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start() { //---int total,cnt,err; total = OrdersTotal(); for(cnt=0;cnt<total;cnt++) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if(OrderType()==OP_BUY) // long position is opened { OrderModify(OrderTicket(),OrderOpenPrice(), Bid-Point*StopLoss,Bid+Point*TakeProfit,0,Green); err=GetLastError(); Print("error(",err,"): ",ErrorDescription(err)); Sleep(1000);

205 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

} if(OrderType()==OP_SELL) // short position is opened { OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*StopLoss, Ask-Point*TakeProfit,0,Red); err=GetLastError(); Print("error(",err,"): ",ErrorDescription(err)); Sleep(1000); } } //---return(0); } //+------------------------------------------------------------------+ Let’s crack the code line by line as we used to do. //+------------------------------------------------------------------+ //| My_First_Script.mq4 | //| Copyright Coders Guru | //| http://www.forex-tsd.com | //+------------------------------------------------------------------+ #property copyright "Copyright Coders Guru" #property link "http://www.forex-tsd.com" Here the wizard has written the comment block which contains the script name we have been chosen, the copyright and link we have been typed. Then two directive properties have been added according to the date we have entered, these are the copyright and link properties. #property show_inputs We have added the show_inputs directive property to our script. Without this property the script will not accept inputs from the user therefore will not prompt an input window to the user as the one showed in figure 3. In our script the user can set the TakeProfit and StopLoss values from the inputs window

206 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

or he can leave the default values we have set in our code. Note: If you intend to write a script which doesn’t need inputs from the user, it’s preferred to remove show_inputs directive property. Figure 3 – Script Input window #include <stdlib.mqh> Later in our code we are going to use the function ErrorDescription which returns a string description of the passed error number. This function is included in the file “stdlib.mqh”, so we have included this file to our program using the include directive. That means the content of the “stdlib.mqh” is a part of our code now and we can freely use the ErrorDescription function. extern double TakeProfit=250; extern double StopLoss=35; Here we have declared two extern variables which the user can set them from the script inputs window (Figure 2) or he can leave the default values. We will use these variables in our start() function to set the takeprofit and stoploss values of all the already opened order. int start() { //---int total,cnt,err; total = OrdersTotal(); .... } We are inside the start() function which will be called only one time when you attach the script to you chart. We have declared three integer variables using a single line declaration method. Then we assigned the return value of the OrdersTotal function to the total variable. As you remember OrdersTotal function returns the number of opened and pending orders. for(cnt=0;cnt<total;cnt++) {

207 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

.... } Here we enter a for loop starts from 0 and ends to the total of already opened and pending orders. We will use the loop variable cnt with the OrderSelect function to select every opened order by its index. In every cycle of the loop we increase the cnt variable by 1. OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); We have selected the order by its index using the function OrderSelect and the loop variable cnt. We have to use the OrderSelect function before calling OrderType in the coming line. (Please review Appendix 2 – Trading functions). if(OrderType()==OP_BUY) // long position is opened { .... } The OrderType function returns the type of selected order that will be one of: OP_BUY, OP_SELL, OP_BUYLIMIT, OP_BUYSTOP, OP_SELLLIMIT or OP_SELLSTOP. In the above if block we have checked the type of order to find is it a Buy order or not. If it's a Buy order, the code inside the block will be executed. OrderModify(OrderTicket(),OrderOpenPrice(), Bid-Point*StopLoss,Bid+Point*TakeProfit,0,Green); It's a Buy order type, so we want to modify the values of stoploss and takeprofit to the values of StopLoss and TakeProfit variables the user has been set. We use the OrderModify function which modifies the properties of a specific opened order or pending order with the new values you pass to the function. We used these parameters: ticket: We've got the current selected order ticket with OrderTicket function. price: We've got the open price of the current selected order with OrderOpenPrice function. stoploss: Here we have set the stoploss value of the current selected order to the value of the subtraction of the current bid price and the StopLoss value the user has been set.

208 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

takeprofit: Here we have set the takeprofit value of the current selected order to the value of the addition of the current bid price and the TakeProfit value the user has been set. expiration: We haven't set an expiration date to our order, so we used 0. arrow_color: We have set the color of the arrow to Green. err=GetLastError(); Print("error(",err,"): ",ErrorDescription(err)); Sleep(1000); We have assigned the returned value of the GetLastError function to the err variable. The GetLastError returns the number of the last error occurred after an operation (OrderModify in our case). But we want to print not only the error number but the description of the error, so we have used the ErrorDescription function to get the string description of the error number and we have used the print function to output this message to the expert log. Then we have used the Sleep function to give the terminal and our script the time to take their breath for one second (1000 milliseconds). Note: Sleep function suspends the execution of the program for a specified interval, this interval passed to the function in milliseconds. if(OrderType()==OP_SELL) // short position is opened { .... } In the above if block we have checked the type of order to find is it a Sell order or not. If it's a Sell order, the code inside the block will be executed. OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*StopLoss, Ask-Point*TakeProfit,0,Red); It's a Sell order type, so we want to modify the values of stoploss and takeprofit to the values of StopLoss and TakeProfit variables the user has been set. We use the OrderModify function again with these parameters: ticket: We've got the current selected order ticket with OrderTicket function. price: We've got the open price of the current selected order with OrderOpenPrice

209 of 258

6/14/2006 5:36 PM

You have to put all of you scripts in this folder and compile them before using them in the terminal.Metatrader Development Course http://www. Let's compile our script by pressing F5 hot key.Working with templates 210 of 258 6/14/2006 5:36 PM . err=GetLastError(). takeprofit: Here we have set the takeprofit value of the current selected order to the value of the subtraction of the current ask price and the TakeProfit value the user has been set. Print("error(". I hope you enjoyed the lesson and found the first script we have created a useful one. expiration: We haven't set an expiration date to our order."): ". as soon as you compile the script it will appear in the navigator window in the script category (Figure 4) Note: The wizard has created the file "My_First_Script. arrow_color: We have set the color of the arrow to Red. return(0). It's the time to terminate our script by using return function. stoploss: Here we have set the stoploss value of the current selected order to the value of the addition of the current ask price and the StopLoss value the user has been set. The inputs window (Figure 3) will appear and you can set new values for StopLoss and TakeProfit or leave the default values. The same as above explained lines.mq4" and has placed it in the "experts\scripts" folder for us.Mql . or click the left mouse button and a menu as showed in figure 4 will appear then choose Execute On Chart. Sleep(1000).info/book/print/34 function.ErrorDescription(err)). Coders’ Guru Lesson 18 .err. I welcome very much your questions and suggestions. so we used 0. Figure 4 – Execute your script To execute the script simply point it with your mouse and double click it.metatrader.

MetaEditor will read these instructions and use them to generate the appropriated lines of code. Today we will create an indicator based on MACD template shipped with MetaTrader. That’s why MQL4 has the feature of creating templates based programs. Note: The template files are stored in the experts\templates path. Here’s the content of the “MACD. This is a useful thing for MQL4 beginners. experts and scripts and save the time of writing the code from scratch. expert advisor and script in the previous lessons. So. And have the ". <expert> type=INDICATOR_ADVISOR separate_window=1 used_buffers=2 211 of 258 6/14/2006 5:36 PM .mqt" file extension. experts and scripts based on your favorite indicators. Every time we decide to create our program whatever the kind of the program (indicator. By using the templates you can create indicators. Inside look: We are going to give the template file a look before digging into our creation of our first template based indicator. Today we are going to duplicate the MACD indicator and we will not add to it anything that’s because we are not in the indicator creating lesson but we are in the template lessons. but it’s time consuming for advanced programmers.metatrader. let’s template! What are the MQL4 templates? The MQL4 templates are text files contain instructions (commands) for MetaEditor to generate a new program based on these instructions.Mql .info/book/print/34 We have created our first indicator.mqt” template which we will use it today creating our template based indicator: Note: We have indented some of content and colored them to make it clearer but you can give the original file an inside look. We use the templates to duplicate the frequently used codes and save our coding time. expert or script) we have to write it from scratch.Metatrader Development Course http://www.

indicator buffers double ExtSilverBuffer[].info/book/print/34 <param> type=int name=FastEMA value=12 </param> <param> type=int name=SlowEMA value=26 </param> <param> type=int name=SignalSMA value=9 </param> <ind> color=Silver type=DRAW_HISTOGRAM </ind> <ind> color=Red </ind> </expert> #header# #property copyright "#copyright#" #property link "#link#" #indicator_properties# #extern_variables# #mapping_buffers# //---.metatrader.Mql .Metatrader Development Course http://www. 212 of 258 6/14/2006 5:36 PM .

213 of 258 6/14/2006 5:36 PM .check for possible errors if(counted_bars<0) return(-1). //---. //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { #buffers_used#.name for DataWindow and indicator subwindow label IndicatorShortName("MACD("+FastEMA+". //---.Mql .SignalSMA)."+SlowEMA+". int counted_bars=IndicatorCounted().indicator buffers mapping SetIndexBuffer(0.last counted bar will be recounted if(counted_bars>0) counted_bars--. ExtSilverBuffer).initialization done return(0).Metatrader Development Course http://www."+SignalSMA+")"). //---.info/book/print/34 double ExtRedBuffer[]. //---.metatrader. ExtRedBuffer). IndicatorDigits(5). //---. } //+------------------------------------------------------------------+ //| Moving Averages Convergence/Divergence | //+------------------------------------------------------------------+ int start() { int limit. //---.drawing settings #indicators_init# //---SetIndexDrawBegin(1. SetIndexBuffer(1.

Metatrader Development Course http://www.Bars. //---.MODE_SMA.SignalSMA. For example <expert> is the start tag and </expert> is the closing tag.i) .done return(0).Mql . i<limit. There is a start tag and a closing tag. For example: type=int name=FastEMA value=12 There are three tags in MQL4 template: expert tag: This is main tag and the other two tags are belonging to it.MODE_EMA.info/book/print/34 limit=Bars-counted_bars. } //+------------------------------------------------------------------+ If you give the above code a look you can notice that the most of the code is a normal MQL4 code with two new kinds of different code. i<limit. //---.i). these are the template commands: MQL4 template tags: The template file starts with tags very like the Html and XML tags.0.metatrader. the number of buffer 214 of 258 6/14/2006 5:36 PM .PRICE_CLOSE.MODE_EMA. these are the template tags.signal line counted in the 2-nd buffer for(i=0.0. i++) ExtSilverBuffer[i]=iMA(NULL.SlowEMA.FastEMA. And the second kind of code (Ex: #header# and #link#) looks like the MQL4 directives.macd counted in the 1-st buffer for(int i=0. i++) ExtRedBuffer[i]=iMAOnArray(ExtSilverBuffer.i)iMA(NULL. The closing tag uses a slash after the opening bracket.0. The first kind of code (Ex: <expert> and <param>) looks like the HTML tags. //---.0. the indicator chart window.0. The text between the brackets is called an element. In this tag we write the type of program.PRICE_CLOSE.

These are the elements used in the expert tag: type: The type of program. ind_minimum: The fixed bottom border of indicator window. separate_window: The chart window type. These are the template commands: #header#: This line will be replaced with the program header block (comments with file name. the bottom border for the chart and the top border for the chart of the indicator. INDICATOR_ADVISOR. name: The variable name. And these lines of code will be replaced with the corresponded lines with code in the generation process. arrow: The character for displaying the DRAW_ARROW indicator. DRAW_SECTION. These are the elements used in the ind tag: type: The indicator drawing shape style.Metatrader Development Course http://www. value: The default value of the variable. 215 of 258 6/14/2006 5:36 PM . These are the elements used in the param tag: type: The data type of the variable. color: The indicator color.metatrader. Possible values are EXPERT_ADVISOR.Mql . DRAW_HISTOGRAM. param tag: We use this tag to create external variables. ind tag: We use this tag to set the parameters of every indicator (drawing line) we use in our program. used_buffers: The number of used buffers. ind_maximum: The fixed top border of indicator window. Note: MetaEditor reads these lines and replace them in the place they found and generate the MQ4 file. Possible values are DRAW_LINE. author name and the company name). MQL4 template commands: They are lines of code starts and ends with # symbol. DRAW_ARROW. For every variable we use a param tag. SCRIPT_ADVISOR.info/book/print/34 used. "Wingdings" font is used for displaying the characters.

Now. That will bring the New Program wizard (Figure 1). #extern_variables#: This line will be replaced with external variables used in your program with their types and default values. Creating our MACD template based indicator. Figure 2 – Second step wizard Hitting Next button will bring the third step wizard (figure 3) which contains the indicator parameters. ready to run: //+------------------------------------------------------------------+ 216 of 258 6/14/2006 5:36 PM . Code ready to compile. Now click the finish button and you will see the magic of the templates. #buffers_used#: This line will be replaced with the number of buffer used if any.info/book/print/34 #copyright#: This line will be replaced with your company name. This time we will choose “Create from template” option and from the drop list we will choose “Indicator – MACD”. #indicator_properties#: This line will be replaced with the properties of the indicator.Mql . let’s create our template based indicator by hitting our File menu and choose New or clicking CTRL+N. Figure 3 – Third step wizard What have we got? The wizards have generated a new indicator for us based on MACD template. As you guessed MetaEditor has red our template file and generated the values of the indicator properties. #indicators_init#: This line will be replaced with the initialization of the indicators (using the function SetIndexStyle). Figure 1 – New program wizard Then we will hit Next button which brings the second step wizard (Figure 2). MetaEditor has filled the fields with Author name and the Link (reading them from the windows registry) and left the Name field blank which we typed in it "MACD_From_Template" In the Parameters list the MetaEditor has red our template file and filled the list with the external variables and its default values. #link#: This line will be replaced with your website link.metatrader.Metatrader Development Course http://www.

com" #property indicator_separate_window #property indicator_buffers 2 #property indicator_color1 Silver #property indicator_color2 Red //---.forex-tsd.drawing settings SetIndexStyle(0. 217 of 258 6/14/2006 5:36 PM .input parameters extern int FastEMA=12.buffers //---.DRAW_LINE).DRAW_HISTOGRAM).indicator buffers double ExtSilverBuffer[]. //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---. //---SetIndexDrawBegin(1.forex-tsd. //---. double ExtRedBuffer[]. IndicatorDigits(5). SetIndexStyle(1.SignalSMA). //---.com | //+------------------------------------------------------------------+ #property copyright "Copyright Coders Guru" #property link "http://www.Metatrader Development Course http://www. ExtSilverBuffer).Mql .metatrader.mq4 | //| Copyright Coders Guru | //| http://www. extern int SlowEMA=26.info/book/print/34 //| MACD_From_Template.indicator buffers mapping SetIndexBuffer(0. extern int SignalSMA=9.

PRICE_CLOSE.MODE_EMA.metatrader. //---.done return(0).i)iMA(NULL.SlowEMA.0.last counted bar will be recounted if(counted_bars>0) counted_bars--."+SlowEMA+". } //+------------------------------------------------------------------+ Compile the code and enjoy your new MACD indicator.Mql .macd counted in the 1-st buffer for(int i=0.Bars.FastEMA.signal line counted in the 2-nd buffer for(i=0. i++) ExtRedBuffer[i]=iMAOnArray(ExtSilverBuffer. 218 of 258 6/14/2006 5:36 PM .MODE_SMA. //---.MODE_EMA.name for DataWindow and indicator subwindow label IndicatorShortName("MACD("+FastEMA+".i). //---.i) .initialization done return(0).PRICE_CLOSE. i++) ExtSilverBuffer[i]=iMA(NULL. limit=Bars-counted_bars. i<limit.0. i<limit.Metatrader Development Course http://www. //---. //---. ExtRedBuffer).SignalSMA. } //+------------------------------------------------------------------+ //| Moving Averages Convergence/Divergence | //+------------------------------------------------------------------+ int start() { int limit. int counted_bars=IndicatorCounted().info/book/print/34 SetIndexBuffer(1."+SignalSMA+")"). //---.0. //---.0.0.check for possible errors if(counted_bars<0) return(-1).

metatrader.Bar chart dawning How the bars indexed in MQL4? MQL4 indexes the bars from 0 (for the current bar) then 1. 2. I’m going to describe everything about Bars in this appendix. So.BARS MQL4 COURSE By Coders’ guru (Appendix 1) Bars ---------------------------I have got a lot of questions about the mystery of the bars count. And the index of the previous bar (of the current bar) is 1. Coders’ Guru Appendix 1 .info/book/print/34 I welcome very much your questions and suggestions. (Figure 1) Figure 1 . 219 of 258 6/14/2006 5:36 PM . if you want to work with the current bar you use the index 0. 3 etc to the count of the bars. low. For example: The 30 minutes timeframe will draw a bar every 30 minutes. open and close prices to draw the bar start and end boundaries. MetaTrader (and other platforms) uses the values of to high.Metatrader Development Course http://www. And the index 100 is the bar 100 in the history (100 bars ago).Mql . What’s a BAR? The bar is the dawning unit on the chart which you can specify by choosing the period of the timeframe.

Note that.info/book/print/34 And the index of last bar is the count of all bars on chart. you use this line: iBars(NULL. PERIOD_H1)).metatrader. int iBars( string symbol.Mql . Note: If you used it like this: iBars(NULL. int timeframe) This function returns the number of bars on the specified currency pairs symbol and timeframe. It returns the same number as Bars function. Assume you are working on 30M timeframe and you want to get the count of Bars on 1H time frame. That’s because the last bar not counted yet (Figure 2). At the first run of your indicator this count will be zero. Afterwards. that’s because your indicator didn’t count any bars yet. which returns the number of bars have been counted by your indicator. But it’s useful to know if you have counted the bar before or it’s the first time you count it.Metatrader Development Course http://www.0)). That’s because. it will equal to the count of Bars – 1. changing the timeframe will change this count. you know now how to get the number of bars. MQL4 BARS count functions: In MQL4 there is a variety of functions working with the count of bars: int Bars This function returns the number of the bars of the current chart. In this case you use the function IndicatorCounted(). if you have counted it before you don’t want to count it again and want to work only with the new bars. 220 of 258 6/14/2006 5:36 PM . You use this number in your calculation and line dawning. int IndicatorCounted() When you are writing your indicator.

//+------------------------------------------------------------------+ //| Bars.mq4 | //| Codersguru | //| http://www. } //+------------------------------------------------------------------+ //| Custor indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- 221 of 258 6/14/2006 5:36 PM .com" #property indicator_chart_window //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---.Metatrader Development Course http://www.forex-tsd.com | //+------------------------------------------------------------------+ #property copyright "Codersguru" #property link "http://www.indicators //---return(1).metatrader.Mql .info/book/print/34 Figure 2 – Program output Let’s write a small program to show you what’s going on.forex-tsd.

} //+------------------------------------------------------------------+ Note: This program produces the image you have seen in figure 2 I hope the Bars count is clear now.Metatrader Development Course http://www. //Open price of the first bar Alert( "Last Bar Open = " . //Open price of the last bar (current bar) //---return(0). IndicatorCounted()).Trading Functions MQL4 COURSE By Coders’ guru 222 of 258 6/14/2006 5:36 PM . iBars(NULL. //The count of bars have been counted Alert( "Bars = " ._ See you Coders’ Guru Appendix 2 . Open[Bars-1]).metatrader.Mql . } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { //---Alert( "counted_bars = " .info/book/print/34 //---return(0). Open[0]). Bars).0)). //The count of the bars on the chart Alert( "iBars = " . I welcome very much the questions and the suggestions. //the same as Bars function Alert( "First Bar Open = " .

metatrader. double volume. int magic=0. Note: GetLastError function returns a predefined number of the last error occurred after an operation (for example when you call GetLastError after OrderSend operation you will get the error number occurred while executing OrderSend). Parameters: This function takes 11 parameters: string symbol: The symbol name of the currency pair you trading (Ex: EURUSD and USDJPY). int cmd.Metatrader Development Course http://www. Note: Use Symbol() function to get currently used symbol and OrderSymbol function to get the symbol of current selected order. double price. Use GetLastError function to get more details about the error.Mql . It returns the ticket number of the order if succeeded and -1 in failure. color arrow_color=CLR_NONE) Description: The OrderSend function used to open a sell/buy order or to set a pending order. Calling GetLastError will reset the last error number to 0. I decided to write this appendix before writing the third part of “Your First Expert Advisor” lesson because you have to know these important functions before cracking the remaining of the code. string comment=NULL. it can be one of these values: 223 of 258 6/14/2006 5:36 PM .info/book/print/34 (Appendix 2) Trading Functions -------------------In this appendix you will find the description of the 25 MQL4 trading functions. double takeprofit. Note: The ticket number is a unique number returned by OrderSend function which you can use later as a reference of the opened or pending order (for example you can use the ticket number with OrderClose function to close that specific order). You can find a full list of MQL4 errors numbers in stderror. datetime expiration=0. OrderSend: Syntax: int OrderSend( string symbol. int slippage.mqh file. double stoploss. And you can get the error description for a specific error number by using ErrorDescription function which defined at stdlib. int cmd: An integer number indicates the type of the operation you want to take.mqh file.

int slippage: The slippage value you assign to the order. For example the orders you have opened by your expert advisor and the orders have opened manually by the user. Sell stop pending position.Mql .…) .3. Note: Magic number is a number you assign to your order(s) as a reference enables you to distinguish between the different orders. double takeprofit: The price you want to close the order at in the case of making profit.com).0. For example: OrderSend(Symbol(). double stoploss: The price you want to close the order at in the case of losing. int magic: The magic number you assign to the order.0. Note: You can use the integer representation of the value or the constant name.3. double price: The price you want to open the order at.Lots. The default value is NULL which means there's no comment assigned to the order. Sell limit pending position. Buy stop pending position.Lots.metatrader.0. Selling position. double volume: The number of lots you want to trade.OP_BUY.OP_BUY. Or like this: OrderSend(Symbol(). Use the functions Bid and Ask to get the current bid or ask price.OP_BUY.Metatrader Development Course http://www. But it's recommended to use the constant name to make your code clearer.Green).Ask."My order comment". For example we can write OrderSend function with or without comment parameter like this: OrderSend(Symbol().Ask-25*Point.Ask. Note: Default value of a parameter means you can leave (don’t write) it out. 224 of 258 6/14/2006 5:36 PM .Ask-25*Point. string comment: The comment string you want to assign to your order (Figure 1).12345.12345.Ask+25*Point. Buy limit pending position. slippage is usually attributed to a change in the spread. (Investopedia.…) is equal to OrderSend(Symbol().info/book/print/34 Constant OP_BUY OP_SELL OP_BUYLIMIT OP_SELLLIMIT OP_BUYSTOP OP_SELLSTOP Value 0 1 2 3 4 5 Description Buying position. Note: slippage is the difference between estimated transaction costs and the amount actually paid.Green).Ask+25*Point. and MQL4 will use a predefined value for this parameter.

14.0.GetLastError()). return(0). if(ticket<0) { Print("OrderSend failed with error #"."My order #2".16384.Ask+25*Point. The default time is 0 which means there's no exportation. color arrow_color: The color of opening arrow (Figure 2). Note: The time here is the server time not your local time.PRICE_CLOSE.info/book/print/34 Figure 1 .1.0. Figure 2 – Arrows color Example: int ticket. to get the current server time use CurTime function and to get the local time use LocalTime function.3.Green).OP_BUY.metatrader. the default value is CLR_NONE which means there's no arrow will be drawn on the chart.Comment datetime expiration: The time you want your pending order to expire at. if(iRSI(NULL.0)<25) { ticket=OrderSend(Symbol().Ask.Mql . 225 of 258 6/14/2006 5:36 PM .Ask-25*Point.Metatrader Development Course http://www.

but in some case the Array has more than one dimension (In MQL4 the maximum dimension is four dimensions). you group the items in the table and access them by number of the row. it called 1 indexed arrays. Creating an Array: The arrays must to be declared (like the variables) before using it in the code. What are the Arrays? In our life we usually group similar objects into units.Mql . Arrays are very like the list tables. MQL4 is not exception. Today we are going to reveal the mystery behind the Array in general and in MQL4 in particular. The subject of Arrays in any programming language is a big mystery to any new comer. Note: In some of programming language the Arrays index starts from 1.Metatrader Development Course http://www. Declaring an array means creating it by giving it a name (identifier). So the index of the first item in an array is 0 and the index of the second item is 1 and the index of the third item is 2 etc. but in MQL4 and the most of programming languages the Arrays index start from 0 (0 indexed Arrays). The rows in the Arrays start from 0 not from 1 like anything else.metatrader. where the first column is the first dimension of the Array and the second column is the second dimension of the Array etc. Figure 1 – one dimension array of 10 integers Array dimensions: In the most of cases the Array has one dimension like the description above. Multi-dimensional arrays are very like multi-column tables.info/book/print/34 } } Arrays Hi folks. In MQL4 we are creating the Arrays like this: 226 of 258 6/14/2006 5:36 PM . We use Arrays to do this task. but rows in the Arrays called Indexes. in the programming we also need to group together the data items of the same type. type and size.

The number of elements has to be equal to the array size. The code above will produce will fill the array with the elements you see in figure 2. Alert ("myarray[2] " +myarray[2]). Look at this code which initializes one. In the code above we declared one-dimensional array. 227 of 258 6/14/2006 5:36 PM .16.info/book/print/34 int myarray[50]. We have now a one-dimensional array of 50 integers double myarray[5][40].9. Alert ("myarray[1] " +myarray[1]).Mql .16. [] telling the compiler that we are declaring an array not an integer variable. myarray is the name of the array (identifier). Alert ("myarray[0] " + myarray[0]).dimensional array of 6 integers: int myarray [6] = {1.4.25}. The list of array element have to be enclosed between curly braces {} then be assigned to the array. Alert ("myarray[5] " +myarray[5]).25. For example the following code will fill the last element of the array with zero because the size of array is 6 elements and we provided it 5 elements: int myarray [6] = {1. And if you provided number greater than the array size.36}. If you provided number of elements lesser than the array size the last elements of arrays will be filled with zeros.4. //5 elements only for 6 size array. int keyword indicates that the array is an array of integers.9. 50 is the size of the array. Alert ("myarray[4] " +myarray[4]). Alert ("myarray[3] " +myarray[3]). Initializing the Array: Initializing an array (or a variable) means setting its value at the same declaration line.metatrader.Metatrader Development Course http://www. MQL4 will ignore these elements and set the array to the first elements. The line above is the way to declare two-dimensional of seven arrays each of them consisting of 40 doubles.

Metatrader Development Course http://www.25.assigned elements greater than array size.4. 228 of 258 6/14/2006 5:36 PM . The code above will produce will fill the array with the elements you see in figure 3. Alert ("myarray[4] " +myarray[4]).Mql . Alert ("myarray[2] " +myarray[2]). Alert ("myarray[1] " +myarray[1]). Alert ("myarray[3] " +myarray[3]).metatrader.16. Alert ("myarray[5] " +myarray[5]). Figure 3 .info/book/print/34 Figure 2 .9. You can do that in two ways. //7 elements for 6 size array. the first way we have explained above is initializing the array with the elements in the declaration line. Assigning elements to an Array: You’ve created an array and want to fill it with elements. Alert ("myarray[0] " + myarray[0]).36.assigned elements lesser than array size int myarray [6] = {1.55}.

Alert ("myarray[3] " + myarray[3]).info/book/print/34 If you didn’t initialize the array yet. The assigned to array must be the same size of the assigned from one. myarray[3] = 16. myarray[4] = 25. myarray[2] = 9.4.25. mycopyarray[1] = mysourcearray [1]. Alert ("mycopyarray[3] " + mycopyarray[3]). myarray[1] = 4. Alert ("mycopyarray[4] " + mycopyarray[4]). In this method you assign element by element using the index of the element. 2.Assigning the elements of the array using the element index. mycopyarray[4] = mysourcearray [4]. Alert ("mycopyarray[5] " + mycopyarray[5]). Alert ("myarray[0] " + myarray[0]). Then we set each element with a line of code. You can assign the elements of the array in two ways: 1.16. Alert ("mycopyarray[0] " + mycopyarray[0]).Metatrader Development Course http://www. Alert ("myarray[4] " + myarray[4]). Look at this code: int myarray [6] . In the code above we declared an array without initializing it. mycopyarray[0] = mysourcearray [0]. But the ArrayCopy is not the scope of our today article and we will discuss the MQL4 Arrays Function in another article.Mql . myarray[0] = 1. Alert ("myarray[2] " + myarray[2]). int mycopyarray[6] . mycopyarray[3] = mysourcearray [3].Assigning the element of one filled array to an empty array: In this method you have already filled array and you assign it to another array. don’t worry.9. mycopyarray[5] = mysourcearray [5].metatrader. Alert ("myarray[5] " + myarray[5]). Alert ("mycopyarray[1] " + mycopyarray[1]). The first element is 0 index and the second is 1 index etc. Alert ("mycopyarray[2] " + mycopyarray[2]). mycopyarray[2] = mysourcearray [2]. Alert ("myarray[1] " + myarray[1]). myarray[5] = 36.36}. Look at this code: int mysourcearray [6] = {1. 229 of 258 6/14/2006 5:36 PM . Note: You can use MQL4 ArrayCopy function which copies one array to another one.

info/book/print/34 Accessing the elements of the Array: When you create an array and fill it with the elements.accessing the elements or the array You can type code like this to access the third array element: int third_element. Alert ("The second element at myarray is: " + myarray[1]). Alert ("The fourth element at myarray is: " + myarray[3]). Figure 4 .9. The first element in the array has the index 0 and the second has the index 1 etc. Look at this code: int myarray [6] = {1.Metatrader Development Course http://www. (Figure 4).16. //9 Hope that the Arrays is understandable subject now. Alert ("The fifth element at myarray is: " + myarray[4]). The last element in this array is myarray[5]. Alert ("The sixth element at myarray is: " + myarray[5]).36 }.25. third_element = myarray[2]. Coders Guru MQL4 Array Functions 230 of 258 6/14/2006 5:36 PM . Alert ("The third element at myarray is: " + myarray[2]). you can access the elements of the array by the index number of each element. In the above code myarray[0] is the first element in the array and myarray[1] is the second element etc. And see you in other article.Mql . Alert ("The first element at myarray is: " + myarray[0]).4. Alert(third_element).metatrader.

By default. Today will talk about this set of build-in MQL4 functions one by one. // All the Time[] timeseries are sorted in descendant mode ArrayCopySeries(daytimes.Metatrader Development Course http://www. Example: datetime daytimes[]. int start=0. We have talked about the Arrays in a previous article and we covered all the aspects of the Arrays in general and in MQL4 in particular. ArrayBsearch: Syntax: int ArrayBsearch( double array[]. int direction=MODE_ASCEND) Description: The ArrayBsearch function searches an array for the occurrence of a value.MODE_TIME. if(Time[shift]>=daytimes[0]) dayshift=0. 231 of 258 6/14/2006 5:36 PM .WHOLE_ARRAY. double value The value you are searching for in the array. Parameters: double array[] The numeric array you want to search it.PERIOD_D1). By default the function searches the whole of the array (WHOLE_ARRAY or 0).info/book/print/34 Hi folks.dayshift. the search starts on the first element (0). int shift=10.0.Mql . The function returns the index of the first occurrence of the value if the value is found in the array and returns the nearest one if the value is not found. Note: You have to sort the numeric arrays using ArraySort() function before performing binary search. But MQL4 concerned more about the arrays and for that it built a set of functions handling the arrays. else { dayshift=ArrayBsearch(daytimes.Time[shift]. int count=WHOLE_ARRAY.MODE_DESCEND). It can be one of the following values: MODE_ASCEND: forward direction searching.metatrader. int count The count of elements in the array you want to search them. double value. MODE_DESCEND: backward direction searching.Symbol(). int direction The searching direction. int start The index you want to start from your searching. The function searches only the first dimension of the array and cannot be used with the arrays of strings or serial numbers.

Bars-9. int start_source The starting index for the source array. string symbol=NULL. The function returns the number of the elements has been copied.0. Example double array1[][6].metatrader. int count=WHOLE_ARRAY) Description: The ArrayCopy function copies an array to another array. color[]. object source[] The source array . int count The count of elements that should be copied. double array2[10][6]. int start_dest=0. 232 of 258 6/14/2006 5:36 PM . int timeframe=0) Description: The ArrayCopyRates function copies the rate from the chart RateInfo array to a two-dimensional array where the second dimension has these elements. int[].info/book/print/34 if(Period()<PERIOD_D1) dayshift++. start index is 0. Parameters: object& dest[] The destination array . By default. // fill array with some data ArrayCopyRates(array1). TimeToStr(daytimes[dayshift])). object source[].dayshift. datetime[]. The source and destination arrays must be of the same type. start index is 0. By default.Metatrader Development Course http://www. } Print(TimeToStr(Time[shift]).the array you want to copy to." corresponds to ". // now array2 has first 10 bars in the history ArrayCopyRates: Syntax: int ArrayCopyRates( double& dest_array[].Mql . int start_source=0. By default." day bar opened at". int start_dest The starting index for the destination array.10). array1. and bool[] can be copied as arrays with same type.the array you want to copy from. ArrayCopy(array2. all the elements of the source array (WHOLE_ARRAY). but arrays with type double[]. ArrayCopy: Syntax: int ArrayCopy( object& dest[].

PERIOD_M30 30 30 minutes. Default (NULL) means the current currency used in the chart. It can be any of the following values: Constant Value Description PERIOD_M1 1 1 minute. PERIOD_H4 233 of 258 6/14/2006 5:36 PM . Parameters: double& dest_array[] The array you want to copy the chart rate info to.Metatrader Development Course http://www.info/book/print/34 0 – time. 3 – high. int timeframe The chart periodicity you want to use. PERIOD_H1 60 1 hour. 1 – open. string symbol The symbol name of the currency pair you want to get the rate info. Note: The numbers in front of the above rate are the index in the array. PERIOD_M15 15 15 minutes. 2 – low. 4 – close. PERIOD_M5 5 5 minutes.volume. 5 .metatrader.Mql .

info/book/print/34 240 4 hour. Parameters: double& array[] The array you want to copy to. 0 (zero) 0 The current Time frame used on the chart. int timeframe=0) Description: The ArrayCopyRates function copies a series array to another array. PERIOD_W1 10080 Weekly. string symbol=NULL. The function returns the number of the elements has been copied. ArrayCopySeries: Syntax: int ArrayCopySeries( double& array[]. PERIOD_D1 1440 Daily. Example: double array1[][6]. PERIOD_H1). array1[0][1]).Mql ."Open"."EURUSD". ArrayCopyRates(array1. PERIOD_MN1 43200 Monthly. Print("Current bar ". Use 0 if you want the current timeframe of the chart.metatrader. It can be any of following values: Constant Value 234 of 258 6/14/2006 5:36 PM . int series_index The type of the series array you want to copy. int series_index.Metatrader Development Course http://www.TimeToStr(array1[0][0]).

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

Description MODE_OPEN 0 Open price. MODE_LOW 1 Low price. MODE_HIGH 2 High price. MODE_CLOSE 3 Close price. MODE_VOLUME 4 Volume, used in Lowest() and Highest() functions. MODE_TIME 5 Bar open time, used in ArrayCopySeries() function. Note: If the series_index is MODE_TIME, the first distension array must be a datetime array. string symbol The symbol name of the currency pair you want to get the rate info. Default (NULL) means the current currency used in the chart. int timeframe The chart periodicity you want to use. Use 0 if you want the current timeframe of the chart. Example: datetime daytimes[]; int shift=10,dayshift; // All the Time[] timeseries are sorted in descendant mode ArrayCopySeries(daytimes,MODE_TIME,Symbol(),PERIOD_D1); if(Time[shift]>=daytimes[0]) dayshift=0; else { dayshift=ArrayBsearch(daytimes,Time[shift],WHOLE_ARRAY,0,MODE_DESCEND); if(Period()<PERIOD_D1) dayshift++; } Print(TimeToStr(Time[shift])," corresponds to ",dayshift," day bar opened at ",
235 of 258 6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

TimeToStr(daytimes[dayshift])); ArrayDimension: Syntax: int ArrayDimension( int array[]) Description: The ArrayDimension function returns the dimensions count of the given array. Parameters: int array[] The array you want to retrieve its dimensions count. Example: int num_array[10][5]; int dim_size; dim_size=ArrayDimension(num_array); // dim_size is 2 ArrayGetAsSeries: Syntax: bool ArrayGetAsSeries( object array[]) Description: The ArrayGetAsSeries function checks the elements of given array and retruns true if the array is a series array (array elements indexed from last to first) and false otherwise. Parameters: int array[] The array you want to check its elements. Example: if(ArrayGetAsSeries(array1)==true) Print("array1 is indexed as a series array"); else Print("array1 is indexed normally (from left to right)"); ArrayInitialize: Syntax: int ArrayInitialize( double& array[], double value) Description: The ArrayInitialize function sets all the elements of the given numeric array to the same value. The function returns the count of the elements in the created array. Parameters:

236 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

double& array[] The numeric array you want to initialize. double value The value you want to set all the elements of the array to. Example: //---- setting all elements of array to 2.1 double myarray[10]; ArrayInitialize(myarray,2.1);

ArrayIsSeries: Syntax: bool ArrayIsSeries( object array[]) Description: The ArrayIsSeries function checks the given array if it’s a series array (time, open, close, high, low, or volume) or not. The function returns true if the array is a series array and false otherwise. Parameters: object array[] The array you want to check. Example: if(ArrayIsSeries(array1)==false) ArrayInitialize(array1,0); else { Print("Series array cannot be initialized!"); return(-1); } ArrayMaximum: Syntax: int ArrayMaximum( double array[], int count=WHOLE_ARRAY, int start=0) Description: The ArrayMaximum function searches the elements of the given array for the maximum value. The function returns the index of the maximum value Parameters: double array[] The array you want to search. int count

237 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

The count of elements in the array you want to search them. By default the function searches the whole of the array (WHOLE_ARRAY or 0). int start The index you want to start from your searching. By default, the search starts on the first element (0). Example: double num_array[15]={4,1,6,3,9,4,1,6,3,9,4,1,6,3,9}; int maxValueIdx=ArrayMaximum(num_array); Print("Max value = ", num_array[maxValueIdx]); ArrayMinimum: Syntax: int ArrayMinimum ( double array[], int count=WHOLE_ARRAY, int start=0) Description: The ArrayMinimum function searches the elements of the given array for the minimum value. The function returns the index of the minimum value Parameters: double array[] The array you want to search. int count The count of elements in the array you want to search them. By default the function searches the whole of the array (WHOLE_ARRAY or 0). int start The index you want to start from your searching. By default, the search starts on the first element (0). Example: double num_array[15]={4,1,6,3,9,4,1,6,3,9,4,1,6,3,9}; int maxValueIdx=ArrayMaximum(num_array); Print("Max value = ", num_array[maxValueIdx]); ArrayRange: Syntax: int ArrayRange( object array[], int range_index) Description: The ArrayRange function returns the count of the elements of the given dimension of the given array. Note: Because the arrays in MQL4 are zero-based array, the size of the array is the largest index + 1. Parameters: object array[] The array you want to check.

238 of 258

6/14/2006 5:36 PM

Mql - Metatrader Development Course

http://www.metatrader.info/book/print/34

int range_index The dimension you want to check. Example: int dim_size; double num_array[10,10,10]; dim_size=ArrayRange(num_array, 1); ArrayResize: Syntax: int ArrayResize( object& array[], int new_size) Description: The ArrayResize function sets a new size for the first dimension of the given array. The function returns the count of the elements of the resized array if it successfully resized the array and 0 otherwise. Parameters: Object& array[] The array you want to resize. int new_size The new size. Example: double array1[][4]; int element_count=ArrayResize(array, 20); // element count is 80 elements ArraySetAsSeries: Syntax: bool ArraySetAsSeries( double& array[], bool set) Description: The ArraySetAsSeries function reverses the index order of the given array to a series array. The function returns true in success and false otherwise. Parameters: double & array[] The array you want to reverse its elements. bool set The series flag to set (true) or drop (false). Example: double macd_buffer[300]; double signal_buffer[300];

239 of 258

6/14/2006 5:36 PM

limit.Mql . int start The index you want to start from your sorting from. int count The count of elements in the array you want to sort them. ArraySize: Syntax: int ArraySize( object array[]) Description: The ArraySize function returns the size of the given array. Example: int count=ArraySize(array1). i++) macd_buffer[i]=iMA(NULL. i<limit. By default the sort starts from the first element (0). i++) { // do some calculations. i<count.MODE_SMA. Parameters: object array[] The array (any type) you want to get its size. i<limit.0.Metatrader Development Course http://www.0.metatrader. int sort_dir The sorting direction.i)-iMA(NULL. for(int i=0.i). ArraySetAsSeries(macd_buffer. 240 of 258 6/14/2006 5:36 PM . } ArraySort: Syntax: int ArraySort( double& array[]. int start=0.26. It can be one of the following values: MODE_ASCEND: sort ascending.PRICE_C for(i=0.PRICE_CLOSE. for(i=0. int sort_dir=MODE_ASCEND) Description: The ArraySort function sorts the first dimension of the given numeric array.MODE_EMA.0. By default the function sorts the whole of the array (WHOLE_ARRAY or 0).0.MODE_EMA.true). Parameters: double& array[] The numeric array you want to sort. int count=WHOLE_ARRAY.12.9. i++) signal_buffer[i]=iMAOnArray(macd_buffer. Note: Series arrays can't be sorted by this function.0.info/book/print/34 int i.limit=ArraySize(macd_buffer).

// now array is sorted 1. 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 ma_method. // now array contains values 4. // now array is sorted 9.6. iCustom. Example: double num_array[5]={4. int shift) The above code calculates the moving average indicator and returns its value. double iATR( string symbol.metatrader.3.1. int shift) What's iCustom anyway? iCustom is a MQL4 function enables you to use external indicators in your expert advisor or custom 241 of 258 6/14/2006 5:36 PM .. string name.9 ArraySort(num_array.6. 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.Mql .9 ArraySort(num_array). int ma_shift. int applied_price.1.Metatrader Development Course http://www. .info/book/print/34 MODE_DESCEND: sort descending. 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. int period.3.9}.4. There are two kinds of indicators you can use in your code (Expert advisors. int shift) The above code calculates the average true range indicator and returns its value.3. int period.3. int timeframe. .1 I hope you enjoyed the article! Coders Guru iCustom function mystery Hi folks.. int timeframe.6.6. int mode.4.MODE_DESCEND).

exe4 format).mq4 | //| Codersguru | //| http://www. //---.//+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---.info/book/print/34 indicator code without re-writing the code from scratch.metatrader. Your indicator draws only one line on the chart.metatrader. 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 (.DRAW_LINE).metatrader.buffers double ExtMapBuffer1[]. This line is the EMA of the period the user enters (external variable). } //+------------------------------------------------------------------+ //| Custor indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---//---return(0). if (counted_bars<0) return(-1). //---. 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. } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { int counted_bars=IndicatorCounted(). //---return(0).last counted bar will be recounted 242 of 258 6/14/2006 5:36 PM .info" #property indicator_chart_window #property indicator_buffers 1 #property indicator_color1 Red //---. SetIndexBuffer(0. and you are not interested in duplicating the indicator code in your expert advisor.Metatrader Development Course http://www.indicators SetIndexStyle(0.inputs extern int UsePeriod = 13.ExtMapBuffer1).Mql .info | //+------------------------------------------------------------------+ #property copyright "Codersguru" #property link "http://www. The code of you custom indicator will be something like that: //+------------------------------------------------------------------+ //| Demo_Indicator.

Demo_Indicator Just keep in your mind that. } //---return(0). pos--.UsePeriod. } //+------------------------------------------------------------------+ You've compiled the code above and loaded the indicator in MetaTrader terminal and have got this result (Figure 1).And draws only one line.Mql . Figure 1 . //---. 2.0.MODE_EMA. Let's assume that you want to use two of your Demo_Indicator. Your code of the expert advisor will be something like that: //+------------------------------------------------------------------+ //| Demo_EA. The first one uses 13 UsePeriod as a parameter and the second one uses 20 UsePeriod as parameter.Your indicator uses only one external variable. ExtMapBuffer1 Now you want to write your expert advisor which uses the indicator above.main calculation loop while(pos>=0) { ExtMapBuffer1[pos]= iMA(NULL. 1. int pos=Bars-counted_bars. At the crossing of the two indicators you will take a trade action (sell or buy).pos).metatrader. UsePeriod.mq4 | //| Codersguru | 243 of 258 6/14/2006 5:36 PM .PRICE_CLOSE.info/book/print/34 if (counted_bars>0) counted_bars--.Metatrader Development Course http://www.0.

0. shortEma = iCustom(NULL. return (last_direction). static int current_direction = 0. } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---//---return(0).metatrader. 244 of 258 6/14/2006 5:36 PM .info" //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---//---return(0).info/book/print/34 //| http://www. double line2) { static int last_direction = 0."Demo_Indicator". double shortEma.0). if(line1>line2)current_direction = 1.info | //+------------------------------------------------------------------+ #property copyright "Codersguru" #property link "http://www. } } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---int total. } int Crossed (double line1 .metatrader.0.13.Metatrader Development Course http://www. //up if(line1<line2)current_direction = 2. longEma. } else { return (0).Mql .metatrader. //down if(current_direction != last_direction) //changed { last_direction = current_direction.

. Figure 2 . return(0). int mode. if(total < 1) { if(isCrossed == 1) { Alert("Take an action"). return(0). let’s give iCustom an inside look. } if(isCrossed == 2) { Alert("Take an action").20.info/book/print/34 longEma = iCustom(NULL. int shift) iCustom function takes these parameters: string symbol: 245 of 258 6/14/2006 5:36 PM . iCustom syntax: double iCustom( string symbol.0).Metatrader Development Course http://www. total = OrdersTotal(). The lines: Print("shortEma = " + shortEma + " : longEma = " + longEma).0.longEma). int isCrossed = 0. } return(0). } return(0). isCrossed = Crossed (shortEma. string name.metatrader.Demo_EA We have used the iCustom function in the above code to get the calculated value of our indicator."Demo_Indicator".. Printed in the journal as you see in figure 2.Mql . int timeframe.. And Alert("Take an action"). Print("shortEma = " + shortEma + " : longEma = " + longEma). } //+------------------------------------------------------------------+ 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).0. .

Use NULL for the current symbol. PERIOD_M5 5 5 minutes. PERIOD_M30 30 30 minutes. PERIOD_W1 246 of 258 6/14/2006 5:36 PM . PERIOD_H1 60 1 hour.Mql . PERIOD_M15 15 15 minutes. int timeframe: The chart periodicity you want to use.info/book/print/34 The symbol name of the currency pair you trading (Ex: EURUSD and USDJPY). PERIOD_H4 240 4 hour.Metatrader Development Course http://www. ote: Use Symbol() function to get currently used symbol and OrderSymbol function to get the symbol of current selected order. It can be any of the following values: Constant Value Description PERIOD_M1 1 1 minute.metatrader. PERIOD_D1 1440 Daily.

0.0). The indicator must be placed in the indicators folder and be compiled (you are loading the ex4 not the mql4 file. In our Demo Indicator we have only one line (buffer) ExtMapBuffer1. int shift: The number of the shifts (backwards) from the current bar you want to calculate. iCustom function returns double data type. If you use 0 for the shift value it means you want to work with the current bar without shifting.0.metatrader.Metatrader Development Course http://www.usually used 0.Mql . 247 of 258 6/14/2006 5:36 PM .13.NULL for current symbol. How did we use the iCustom function in our code? double shortEma. It returns the calculation value of the passed parameters for the loaded indicator. longEma = iCustom(NULL. parmeter 2 : time frame . Then we called iCustom in the second line with these parameters: parmeter 1 :the symbol . so you have to compile the indicator before loading it). string name: The exact name of the indicator you want to use. parmeter 5 : the line number (range from 0 to 7) .info/book/print/34 10080 Weekly."Demo_Indicator". parmeter 3 : indicator name . the index of this line is 0 (because it’s the first line and the only one too)."Demo_Indicator". The index of these lines starts at 0 and up to 7. …: The parameters set for the indicator you are calling. In our Demo Indicator we have only one parameter (External variable) UsePeriod – an integer type. int mode: The index of the line you want to get its value. shortEma = iCustom(NULL. 0 (zero) 0 The current Time frame used on the chart. PERIOD_MN1 43200 Monthly.0.here it's " Demo_Indicator". In the first line we have declared two double variable (shortEma and longEma) which hold the returning value of iCustom.0 for current time frame.0). longEma.0. parmeter 4 : this is a setting for Demo_Indicator .UsePeriod = 13. We set its value here to 13 in the first iCustom call and to 20 in the second call. You know that any indicator can use up to 8 lines (buffers). (…) means it the parameter can be any type and it can supply any count of parameters.20.

info/book/print/34 parmeter 6 : the working bar .metatrader. parmeter 4 : this is a setting for Demo_Indicator . parmeter 6 : the working bar . Let’s take an example: double //type of sausage -return value type my_func(double a .0 for the current bar. we can use it very like if we have the indicator in our program. you put the parameters of the function. Today we are going to talk about a very important development issue. External functions Hi folks. There’s only one difference between the functions and the sausage machine that some of functions will return nothing (nothing in MQL4 called void). double b . The meat and the spices are the function parameters and the sausage is the function output (return value).usually used 0. //sausage outputs .UsePeriod = 20. double c) //function name and parameters list (meat & spices) { return (a*b+c).Metatrader Development Course http://www.0 for the current bar. In our example the function body will produce the operation (a*b+c). The external functions in MQL4. you input the meat and spices in the machine from one side and it outputs the sausage. if you don’t know what are the functions (or you forgot) I’ll repeat some my speech about the functions I told you in my MQL4 Functions lesson.Mql .returned value } As you see above the function starts with the type of the returned value "double" followed by the function name which followed by parentheses. parmeter 5 : the line number (range from 0 to 7) . Inside the parentheses you put the meat and the spices. What are the MQL4 functions anyway? The function is very like the sausage machine. And in the third line we used iCustom again to get the second indicator value. sorry. parmeter 3 : indicator name . The machine itself is the function body.0 for current time frame. You call the above function like this: 248 of 258 6/14/2006 5:36 PM . Then the function body starts and ends with braces. We all know the normal functions in MQL4. double b and double c. Now we have the value of the indicator for the current bar. I hope it's clearer now and you can iCustom function without problems.NULL for current symbol. The return keyword is responsible about returning the final result. These are the parameters we used: parmeter 1 :the symbol .here it's " Demo_Indicator". parmeter 2 : time frame . Here we have put three parameters double a.

As you see in the above line of code.9). 2 . They are very like the normal programs like the Microsoft Word or FireFox browser but they mostly have no user interface and the other important difference that they can loaded from more than one application. The creating of this type of program is the subject of another article. For example you can use the windows winsock DLL to send and receive data through the internet. When MQL4 see the function name.info/book/print/34 double result = my_func(1. you first declared a double variable to hold the returning value of our function.info | //+------------------------------------------------------------------+ #property copyright "Copyright Coders Guru" #property link "http://www.zip (309 B) //+------------------------------------------------------------------+ //| mylib. You can use these function by importing them from the external files to your code. Using DLLs from MQL4 give the language a very strong advantage and enables it to make a lot of things another applications can do. Those external files can be one of two kinds of files: 1. We will know everything about using the functions reside at these types of MQL4 programs in this article. The options are very wide and even dangerous. Using external functions from a library file: I’ve create a library file in the purpose of this article (The steps creating of this file is out or article’s scope). We will know everything about using the functions reside at windows DLLs in this article. This was a summery explaining of the MQL4 function. Then you assigned to that variable the function calling.Mql .info" #property library //+------------------------------------------------------------------+ //| My functions | 249 of 258 6/14/2006 5:36 PM .Metatrader Development Course http://www. Download the file if you want and save it the libraries path then compile it: icon mylib.metatrader.metatrader. The file must be located at the MetaTrader 4\experts\libraries path and must be compiled (.MQL4 executable files (ex4): You can use the functions reside at an already compiled MQL4 program called library programs. What about the external functions in MQL4? External functions: External functions are functions reside at external files not the source file you are writing right now. You called the function by writing the function name then passed to it between the brackets the proper parameters (three double values in our case).metatrader. it will take the provided parameters and goes to the function body to execute the code inside that body and return with the value and place it at the same point of the function calling.5 . The creating of these DLLs is out scope of our MQL4 development field. 5. They are mostly contains shared function which can be used with all the windows application.mq4 | //| Copyright Coders Guru | //| http://www. 2.ex4) before importing the functions you want from them.Windows Dlls: DLLs (Dynamic Link Libraries) are programs written in an advanced programming language (like Visual basic or C++) for Microsoft Windows operating system.

#import //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start() { //---int result = MyExtFunction(10. int MyExtFunction(int value.info | //+------------------------------------------------------------------+ #property copyright "Copyright Coders Guru" #property link "http://www. Download this file if you want and place it in the scripts folder then compile it: icon Exteranl functions 1. #import 250 of 258 6/14/2006 5:36 PM .Metatrader Development Course http://www.zip (406 B) //+------------------------------------------------------------------+ //| Exteranl functions 1 .Importing the external function from the library.metatrader.int value2). The declaration line must ends with semi-colon. Importing the external function: To be able to use the external function from your code you have to import it to your code. we use the #import keyword followed by the library name. the line doesn't end with semi-colon. 2.ex4" This is the first import line. } //+------------------------------------------------------------------+ In the code above to use an external function resides in a MQL4 library file we have taken two steps: 1. in this case you write every function in a separate line. The MyExtFunction function takes two integers parameters and returns the value of those two numbers addition.info/book/print/34 //+------------------------------------------------------------------+ int MyExtFunction(int value. You can import as many function as you want.int value2) { return(value+value2).int value2). //---return(0).ex4" int MyExtFunction(int value.metatrader. Let’s create a simple program which imports and uses the external function MyExtFunction.metatrader.20). } //+------------------------------------------------------------------+ In the above code we have created a normal function MyExtFunction which we will import it from another MQL4 program and use it. Without this declaration your program will not know anything about the external function. Then in the second line you declare the function very like the normal functions by writing the type of returned value followed by the function name then the parameters of the function and their types.info" #import "mylib.mq4 | //| Copyright Coders Guru | //| http://www.Using (calling) the function like any MQL4 function.Mql . Alert ( result). Importing the function takes three lines of code as you see above: #import "mylib.

The Alert function will pop up the result variable like figure 1.metatrader.string lpText.zip (439 B) //+------------------------------------------------------------------+ //| Exteranl functions 2.ex4" double MyExtFunction2(double value3).metatrader.dll" int MessageBoxA(int hWnd.Mql ."Helo world!". } //+------------------------------------------------------------------+ 251 of 258 6/14/2006 5:36 PM . for example: #import "mylib. //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start() { //---int result = MessageBoxA(NULL.mq4 | //| Copyright Coders Guru | //| http://www. #import "mylib2. Using external functions from a DLL file: Importing an external function from a DLL file is the same as importing them from a library file.info" #import "user32.info | //+------------------------------------------------------------------+ #property copyright "Copyright Coders Guru" #property link "http://www. in the case of importing an external function from a DLL you have not to write the #import line.int value2). Let's take an example: Download the file if you want and save it the scripts path then compile it: icon Exteranl functions 2.metatrader. The only difference is the close import line.ex4" int MyExtFunction(int value."MQL4 Messagebox". but in this case without an external file. #import Calling the external function: If you have written right import block lines like the above description.string lpCaption. Note: You use only one #import line to end all the opened import lines. In our program we called the MyExtFunction like this: int result = MyExtFunction(10. you can call the external function very like calling any normal function in MQL4 program.int uType). //---return(0).info/book/print/34 To tell the compiler of MQL4 that you have finished your importing you have to write another line contains the #import keyword.0). We passed the numbers 10 and 20 to the function and assigned the returned value to the integer variable result.Metatrader Development Course http://www.20). Alert ( result).

they are not two separated worlds but they are two faces of the same coin. and called it in the code very like any normal function. because the syntax of MQL2 is based on EasyLanguage while the syntax of MQL4 is very like the C syntax (Besides the new added features to the MQL4 language). We will take somewhat a practical approach studding the difference between the two languages. We can’t set a series of lessons to study MQL2 like which we assigned to MQL4 but you will know a lot of MQL2 principals while you are skimming these conversion articles.Mql .dll the very important windows DLL. That’s because the both of the two languages talking about the same thing. In these series of articles I’ll try to remove the stumbling blocks from the road of the programmers who want to convert MQL2 programs to MQL4 and vice versa.Message box MQL2 to MQL4 conversion and vice versa! Hi folks. although it’s hard to convert between the two languages but it’s not an impossible task. A lot of people find that the MQL2 and the MQL4 are different worlds.info/book/print/34 As you can notice in the program above the import lines are the same as the using external function from a library except the closing #import line. about creating a program for MetaTrader.Metatrader Development Course http://www. The MessageBoxA function will pop up a message box like the one in figure 2. that’s by studding a real example of a program wrote in the both language and observing the conversion operation has been occurred.metatrader. In the above code we used a function of user32. Let’s converting! Our example program: 252 of 258 6/14/2006 5:36 PM . But I think that. Figure 2 . so.

5.Metatrader Development Course http://www.Place the “3D Oscilator. 3. Figure 1 .zip (974 B) Download the MQL4 source code: icon 3D Oscilator_MQL4.Double click it to open it in MetaEditor. To compile the MQL4 version: 1.Mql . but you will get a Properties window like this: 253 of 258 6/14/2006 5:36 PM .When you get the Properties window (Figure 1) click OK. Download the MQL2 source code: icon 3D Oscilator_MQL2.ex4).net/downloads/). (If you don't have MT3 yet.Open MetaTrader and from the Navigator window navigate to the Custom Indicators section and double click the 3D Oscilator. you can compile the 3D Oscilator and load it in the Terminals. 2. Loading the 3D Oscilator(s) in the MT4 and MT3 terminals: If you are a lucky person like me and have the both of MT4 and MT3 installed in your machine.metaquotes.zip (1009 B) Note: The 3D Oscilator has been created in MQL2 by Luis Damiani and converted to MQL4 by Ricardo. 4.Properties window in MetaTrader 4 To compile the MQL2 version: The same steps as MQL4.info/book/print/34 We are going to work in these articles with an indicator called “3D Oscilator”.mq4” file in the Indicators path.metatrader. you can download it from the MetaQuotes download section: http://www.Press F5 to compile the program (produced file extension is . Ramdass.

Metatrader Development Course http://www.metatrader.info/book/print/34 Figure 2 .Properties window in MetaTrader 3 Figures 3 and 4 shows how the indicator looks like in the both platforms: Figure 3 .How the indicator appears MetaTrader 4 254 of 258 6/14/2006 5:36 PM .Mql .

info/book/print/34 Figure 4 . Third etc). Separate Window: Plot the indicator in the main chart window (No) or in a separate window.How the indicator appears MetaTrader 3 Cracking the MQL2 program: We are going to crack the MQL2 program section by section and line by line to convert it to the MQL4 program. it maybe: Line. First Color: The color of the first line (Second. Minimum Chart Limits: If the indicator is shown in a separate window this command sets the minimum value drawn on the chart. Histogram or Symbol (Second. First Draw Type: The type of the drawing line. Maximum Chart Limits: the maximum value drawn on the chart.Mql . Author: The author name of the program. Use Second Data: Yes means that the indicator calculation results in 2 charts. and not the only one.Metatrader Development Course http://www. the author name. Third etc). the indicator line properties and symbols etc. /*[[ Name := 3D Oscilator Author := Luis Damiani Separate Window := Yes First Color := lime First Draw Type := Line First Symbol := 217 Use Second Data :=yes Second Color := RoyalBlue Second Draw Type := Line Second Symbol := 218 ]]*/ The section above is the description section where you put the name of the program. 255 of 258 6/14/2006 5:36 PM . Third etc). In this section you can find the following commands: Name: The name of the program. window type of the indicator. First Symbol: The symbol number from Wingdings table of the drawing line (Second. The section when converted to MQL4 it will be dispersed in the program and not in a gathered section like MQL2.metatrader.

So we have to set 2 buffers: #property indicator_buffers 2 And to set the color of the first line we used this line of code: #property indicator_color1 Yellow First Draw Type := Line To set the drawing type of the line in MQL4 you use SetIndexStyle() function and you have to use it inside the Init() function.info/book/print/34 Let's see how we converted these lines to MQL4: Name := 3D Oscilator The Name of the program usually wrote in the comment section in MQL4 along with the Author name and the website Link. In our program we will use two lines and will not use any buffers for calculation. where the N is is the number of the line.mq4 | //| | //| | //+------------------------------------------------------------------+ Author := Luis Damiani The Author name wrote in the comment section and in the copyright property directive: #property copyright "Author . //+------------------------------------------------------------------+ //| 3D Oscilator. In our program we used code like this: 256 of 258 6/14/2006 5:36 PM .metatrader.Metatrader Development Course http://www. for example: #property indicator_color1 //First line color #property indicator_color2 //Second line color #property indicator_color8 //Eighth line color In MQL4 we have to add extra line before the indicator_color property. this is the indicator_buffers property which sets the number of the buffers used in the program.Mql . Ramdass . the buffers used for the calculations of the indicators and for drawing lines.Ricardo.Conversion only" Separate Window := Yes The equivalent line in MQL4 is the indicator_separate_window property: property indicator_separate_window First Color := lime The color of the line in MQL4 set by the indicator_colorN property.

every time a new quotation have received your program will call this function. . The clr parameter is the color of the line. color clr=CLR_NONE) This function will set the style of the drawn line. } SetIndexStyle: void SetIndexStyle( int index. The width parameter is the width of line and ranges from 1 to 5. you have to put here you initialization values of you variables. 257 of 258 6/14/2006 5:36 PM . int style=EMPTY.In MQL4 there are three special functions which you can't name your functions the same names and have special jobs in MQL4 init(): Every program will run this function before any of the other functions. The default value is CLR_NONE which means empty state of colors. deinit() and start(): Functions are blocks of code which like a machine takes inputs and returns outputs. deinit(): This is the last function the program will call before it shutdown. int width=EMPTY. start(): Here’s the most of the work. MQL4 Special functions init()... you can put here any removals you want. And it indicates which line we want to set its style.. It can be any valid color type variable..info/book/print/34 int init() { .metatrader.. int type.Metatrader Development Course http://www..Mql . The type parameter is the shape type of the line and can be one of the following shape type’s constants: DRAW_LINE (draw a line) DRAW_SECTION (draw section) DRAW_HISTOGRAM (draw histogram) DRAW_ARROW (draw arrow DRAW_NONE (no draw) The style parameter is the pen style of drawing the line and can be one of the following styles’ constants: STYLE_SOLID (use solid pen) STYLE_DASH (use dash pen) STYLE_DOT (use dot pen) STYLE_DASHDOT (use dash and dot pen) STYLE_DASHDOTDOT (use dash and double dots) Or it can be EMPTY (default) which means it will be no changes in the line style. The index parameter of this function ranges from 1 to 7 (that’s because the array indexing start with 0 and we have limited 8 lines).DRAW_LINE). Or it can be EMPTY (default) which means the width will not change. SetIndexStyle(0.

Mql .metatrader.info/book/print/34 Alerts 258 of 258 6/14/2006 5:36 PM .Metatrader Development Course http://www.

Sign up to vote on this title
UsefulNot useful