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?
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.
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.

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
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.
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”.
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:
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 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 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.
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.
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 (\).
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 |
x + y / 100x + (y / 100) //unambiguous, recommended
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<= 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
= 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
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?
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 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:
| 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?).
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.
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.
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”.
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:
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:
| 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.
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.
What are the Preprocessors mean?
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; |
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 |
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.
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).
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
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 |
//+------------------------------------------------------------------+
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);
}
//+------------------------------------------------------------------+
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--;
_
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));_
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.
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
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
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
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:
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
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()
{
//----
//----
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 |
//+------------------------------------------------------------------+
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);
}
}
//+------------------------------------------------------------------+
//| 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))
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
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)) ||
(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:
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).