Sie sind auf Seite 1von 12

MQL4 Programming

I have been writing MQL4 code since 2005 and wrote some tutorials back then. I have
decided to update these tutorials and create more advanced chapters in the coming
months. I hope you like what you see and that this will help you bring your MQL
programming skills to a new level
Patrick Nouvion
Mistigri LLC Founder

MQL4 Programming
o Basic Intro to programming
Creating the algorythm
o Coding a basic EA for MT4
EA - Step 1 - Global Variables
EA - Step 2 - User Inputs
EA - Step 3 - Init & deinit functions
EA - Step 4 - Start function - Basic Layout
o Coding a DLL for MT4
Writing a basic MT4 dll
MT4 DLL Common Errors
ShellExecute - Run program
MT4 DLL Time Limit
MT4 DLL Web Connect

Basic Intro to programming


If you are familiar with basic programming concepts already you may skip this chapter...
This is not intended to be a full fledged introduction to programming, but we will cover a
lot useful information that you will need for the more MT4 specific pages. Please make
sure you spend more time trying to understand and follow the logic than try to get the
right answer.
The truth is, in programming, there is not just one right solution. Everyone has their own
style and approach to solve logic problems and that is fine, keep your own style just make
sure you understand what you are typing vs copying some code you do not understand.
Maybe the most important thing to learn is that a program only does what it is told to do!
If you did not think out your program properly you will end up with a lot bugs.

There are many different programming languages ( C, Visual Basic, Pascal, Delphi etc
) and their goal has always been to facilitate the communication between us and the
computer. Unless you want to write binary, assembly language programs ... Which
would not be practical ( nor easy for that matter ), you have to use a compromise between
English and Computer Speak.
For now our programming language will be what people call pseudo code, which means
that we will write our programs in plain English. The reason is because more often than
not people will focus on the syntax and specific commands of a given programming
language without learning the logic and programming concepts they need. Think of it as a
kid who knows 3*2=6 but does not understand why ... He will get good grades until the
problem he faces was not in his text book.

Creating the algorythm


Just like trading, before you can start anything you first need to come up with a plan.
What is this program going to do?
Let me say that the more time you spend defining your program and its requirements the
less time you will spend debugging and rewriting code ...
An algorythm is a specific, finite set of instructions used to solve a problem or perform a
function. A good example is a cooking recipe; let me point out that you can find many
examples on the back of products you purchase everyday. Take a bottle of shampoo, read
the back and you will see something like:

Shake well
Shampoo
Rinse thoroughly

It's pretty much what you need to do before you start writing your program. List out all
the steps it will need to perform. Your algorithm has to be very detailed and it needs to be
finite. Try to think about all potential issues, "the devil is in the details".
Let's make a very simplistic algorithm for a trading system.

Check Condition
If BUY Then place BUY order
If SELL Then place SELL order
If BUY_EXIT Then close BUY order
If SELL_EXIT Then close SELL order

That's definitely not enough ( far from it ), what about checking that there is actually a
trade before closing it, ...

I will try to create a more detailed algorithm for this page, it won't be perfect but
hopefully a good starting point for many.

Coding a basic EA for MT4


In this chapter we will go through the creation of a basic EA, I will try to go through
every step in details.
To get started open the MetaEditor then click on file, new, select expert advisor, click on
next. Enter a name for the EA, the author information and a link then simply click on
finish.
You should end up with something like this:
//+------------------------------------------------------------------+
//|
MSFX - Expert Template.mq4 |
//|
Copyright 2009, MistigriFX |
//|
http://www.mistigrifx.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2009, MistigriFX"
#property link
"http://www.mistigrifx.com"
//+------------------------------------------------------------------+
//| expert initialization function
|
//+------------------------------------------------------------------+
int init(){ return(0); }
//+------------------------------------------------------------------+
//| expert deinitialization function
|
//+------------------------------------------------------------------+
int deinit() { return(0); }
//+------------------------------------------------------------------+
//| expert start function
|
//+------------------------------------------------------------------+
int start() { return(0); }
//+------------------------------------------------------------------+

As you can see there are 3 main functions, init() which is only ran once ( when you apply,
switch TimeFrame/chart, compile or change settings on the EA ).
The start function which is ran with every tick that comes through the platform and the
deinit function which is only ran once when you remove the EA or change the chart
( symbol or TimeFrame ).
I usually create 6 sections ... as follow :
//+------------------------------------------------------------------+
//|
MSFX - Expert Template.mq4 |
//|
Copyright 2009, MistigriFX |
//|
http://www.mistigrifx.com |

//+------------------------------------------------------------------+
#property copyright "Copyright 2009, MistigriFX"
#property link
"http://www.mistigrifx.com"
//+------------------------------------------------------------------+
//| Global Variables / Includes
|
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Expert User Inputs
|
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Expert initialization function
|
//+------------------------------------------------------------------+
int init(){ return(0); }
//+------------------------------------------------------------------+
//| Expert deinitialization function
|
//+------------------------------------------------------------------+
int deinit() { return(0); }
//+------------------------------------------------------------------+
//| Expert start function
|
//+------------------------------------------------------------------+
int start() { return(0); }
//+------------------------------------------------------------------+
//| Expert Custom Functions
|
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+

EA - Step 1 - Global Variables


We will certainly come back to this section later on but I usually declare a few variables
as global so that I can set them ONCE at init() time and that's it.
I understand that I'm not saving that much speed but later this makes it easier to update
the entire EA without changing too much code.
So what do I need as global variables, for a basic EA, I usually have the following :
//+------------------------------------------------------------------+
//| Global Variables / Includes
|
//+------------------------------------------------------------------+
datetime
CurrTime = 0;
datetime
PrevTime = 0;
string
Sym = "";
int TimeFrame = 0;
int
Shift = 1;

int
double

SymDigits = 5;
SymPoints = 0.0001;

Now to show an example of how this can help later on. By default I would leave the time
frame input to 0 which in MT4 would default to the chart time frame / periodicity.
However if later on I wanted to lock the EA to simply use a 5 minute time frame I would
simply have to update my global variable TimeFrame to 5 and I would be done.
Also instead of calling the MT4 function Period() with every tick, I would only use my
TimeFrame variable.
Another example would be the shift input, let's say I first program my EA to work on
completed bars only but later wanted to switch it to real time, by simply updating the
shift variable to 0 I would update the whole EA easily.
Etc ...

EA - Step 2 - User Inputs


For a simple EA we usually need the following:
//+------------------------------------------------------------------+
//| Expert User Inputs
|
//+------------------------------------------------------------------+
extern double
Lots = 0.01;
extern
int MagicNumber = 1235;
extern
int ProfitTarget = 100;
extern
int
StopLoss = 100;
extern
int
BreakEven =
10;
extern
int
Trailing =
20;
extern
int
Slippage =
3;

We need the Lots size, the MagicNumber to keep track of the EA's orders, then the usual
trading inputs.
notice that to define an input you simply need to use the keyword "extern" in front of
your variable.

EA - Step 3 - Init & deinit functions


In the init section I set my global variables once and also adjust the Digits and Points
variables to work on 5 digits brokers.
//+------------------------------------------------------------------+
//| expert initialization function
|
//+------------------------------------------------------------------+

int init()
{
Sym = Symbol();
TimeFrame = Period();
SymPoints = MarketInfo( Sym, MODE_POINT );
SymDigits = MarketInfo( Sym, MODE_DIGITS );
//--if( SymPoints == 0.001
) { SymPoints = 0.01;
SymDigits =
3; }
else if( SymPoints == 0.00001 ) { SymPoints = 0.0001; SymDigits =
5; }
//---return(0);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function
|
//+------------------------------------------------------------------+
int deinit() { return(0); }

Since this is a very basic EA the deinit function will not be modified. Though you would
usually use the deinit section to clean up objects or comments you have created as well as
update global variables you have set on the MT4 platform.

EA - Step 4 - Start function - Basic Layout


Assuming we follow a basic trading system algorithm we would first check to see if we
have any trades. So I need to create a function that will count the currently opened trades.
While it does not exist ... yet ... I will start writing the code as if it did, same with other
functions that I may need. Later on we'll create the functions.
//+------------------------------------------------------------------+
int start()
{
//---- Do we have Trades? If Yes run money management functions
if( CountAll( Sym, MagicNumber) > 0)
{
Trail( Trailing );
}
//---- Complete Bar?
CurrTime = iTime(Sym, TimeFrame, Shift );
if( CurrTime != PrevTime )
{
//---- Update Vars
PrevTime = CurrTime;
//---- Need to chek for a new Signal?
if( CountAll( Sym, MagicNumber) == 0)
{
//---- Indicator 1 Values
double Indicator1CurrentValue = 0.0;

double
//---double
double

Indicator1PreviousValue = 0.0;
Indicator 2 Values
Indicator2CurrentValue = 0.0;
Indicator2PreviousValue = 0.0;

//---- Moving Average Cross System


if( Indicator1CurrentValue > Indicator2CurrentValue &&
Indicator1PreviousValue <= Indicator2PreviousValue ) { EnterLong(); }
else if( Indicator1CurrentValue < Indicator2CurrentValue &&
Indicator1PreviousValue >= Indicator2PreviousValue ) { EnterShrt(); }
}
//---}
//---return(0);
}

That pretty much covers the logic for a simple MA Crossover system.
Now we need to create the functions we need as well as define the indicators we want to
use.
Here is a list of the functions to be created:
CountAll - Count all open trades
Trail - Trailing Stop function
EnterLong - Place Long Order Function
EnterShrt - Place Short Order Function

Coding a DLL for MT4


MQL is by itself a very powerful programming interface, especially compared to the
many other trading software out there who have limited programing capabilities ( though
the trend is changing ). Yet MetaTrader still offers us the ability to program our own dlls.
Now, I may be wrong but until someone corrects me here are a few things to know about
writing DLL's for MT4.
1) You have to write the DLL using C++/Delphi, NOT VB, NOT C#...
2) You MUST have a def file, in visual studio it needs to be created manually, if using
dev-c++ it will be generated for. I would say 70% of the problems one has with dll's in
MetaTrader is error 127. This error means that you either do not have a def file or that the
def file is not set properly.

Writing a basic MT4 dll

Let's get started with writing a dll for MT4, I'm using VS 2008 but you can use a free
software such as dev-c++, note that for dev-c++ the def file is created for you but you
need to watch out for name-mangling.
if using dev-c++ add the following around your code:
#ifdef __cplusplus
extern "C" {
#endif
Your code goes here ...
#ifdef __cplusplus
}
#endif
Well I could wrote some long boring chapters or you could just watch the video to the
right
This should get you started and I have provided a sample VS2008 project as well as a
sample dev-c++ project to help you get started.

MT4 DLL Common Errors


The most common error codes when dealing with a MT4 DLL are 126 and 127. Here is
what they mean and how to troubleshoot the issue:
Error 126:
Usually this means that your DLL file was not found in the libraries folder.
If the DLL works on your PC but not on another system then it means that you did not
link the MFC library as static. To fix the issue go to your project properties and under:
Configuration Properties | General | Use of MFC
Make sure that you have Use MFC in a Static Library selected.
Then rebuild your dll...
Error 127:
By far the most common error, it is due to the def file. You either do not have a def file, it
is not linked properly or the function names in your def file are wrong.
Well checking whether you have a def file or not should be easy, check your project
folder and make sure it is there. Then open it and make sure the function name match the
ones in your MT4 code.

If you get mangled function names such as:


EXPORTS
_Z11GetSMAArrayP8RateInfoiiPd@16 @ 1
_Z12GetHighValueP8RateInfoii = _Z12GetHighValueP8RateInfoii@12 @ 2
_Z12GetHighValueP8RateInfoii@12 @ 3
_Z13GetCloseValueP8RateInfoii = _Z13GetCloseValueP8RateInfoii@12 @ 4
_Z13GetCloseValueP8RateInfoii@12 @ 5
_Z11GetSMAArrayP8RateInfoiiPd = _Z11GetSMAArrayP8RateInfoiiPd@16 @
6

Make sure to use the following code:


#ifdef __cplusplus
extern "C" {
#endif
Your code goes here ...
#ifdef __cplusplus
}
#endif

Download the Dev-c++ project from "Writing a basic MT4 Dll" for more info.
Once the above steps have been checked, if you still get error 127, make sure your def
file is linked properly.
In visual studio 2008 ( Including Express Version ), go to project, properties, then expand
the "linker" group, select "Input" and change the "Module definition File" to be whatever
you named your def file. Make sure it has the path and full name of the file - such as
.\MyDef.def
In Dev-c++, the def file is created and linked automatically... Unless you manually
created it, in which case go to Project Options, Linker parameters and add: --def
yourfile.def

ShellExecute - Run program


For many of my Experts, Indicators and scripts I want/need to open file or execute a
program. It could be a webpage, a report I just created or even an application that I wrote
in C# ...
One easy way would be to add the following code to the top of your MT4 code:
//+------------------------------------------------------------------+
//|
MSFX - Trades Analyzer.mq4 |
//|
Copyright 2006-2009, Mistigri LLC |
//|
http://www.mistigrifx.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2006-2009, Mistigri LLC"
#property link
"http://www.mistigrifx.com"

#import "shell32.dll"
int ShellExecuteA(int hWnd,int Verb,string File,int Parameter,int
Path,int ShowCommand);
#import
#define IDYES
6
#define IDNO
7
#define MB_OK
0x00000000
#define MB_YESNO
0x00000004
#define MB_ICONQUESTION
0x00000020
#define SW_SHOWNORMAL 1
//+------------------------------------------------------------------+

then inside the MT4 code open the file with the following:
//---- OUTPUT REPORT FILE - START
int Prompt = MessageBox( "Report was created. Would you like to open
it?", "MSFX - Trades Analyzer", MB_YESNO|MB_ICONQUESTION );
if( Prompt == IDYES )
{
string PAT = TerminalPath();
string URL = StringConcatenate( PAT,"/experts/files/MSFX-Trades
Analyzer Report.html");
ShellExecuteA( 0,"open",URL,NULL,NULL,SW_SHOWNORMAL);
}

The above code works most of the time, but seems to crash more often than not. So I
created my own dll to do the exact same thing... Just seems to be more stable that way.
Setup your DLL as per the previous chapters and create a function with the following
code. By the way I know the function is called OpenBrowser but it really is just
ShellExec, you can rename the function to anything you want.
MT4_EXPFUNC void __stdcall OpenBrowser( char * URL )
{
CString strURL( URL );
//CString strURL = _T("http://www.mistigrifx.com");
//MessageBox( NULL, strURL, L"MistigriFX DLL", 0 );
ShellExecute( NULL, _T("open"), strURL, NULL, NULL, SW_SHOWNORMAL);
}

MT4 DLL Time Limit


Every once in a while I have to put a time limitation on a MT4 DLL, so far I have used
the following code:
// You need to have #include <windows.h> at the top of your code
MT4_EXPFUNC double __stdcall Sample( int Whatever )
{
//---- Let's get the system's time

SYSTEMTIME st;
GetSystemTime(&st);
int
Year = static_cast<int>(st.wYear) *10000;
int
Month = static_cast<int>(st.wMonth)*100;
int
Day = static_cast<int>(st.wDay);
int SystemDate = Year+Month+Day;
//---- Is trial expired?
if( SystemDate >= 20080501 && SystemDate < 20080601 )
{
//---- Your code here ...
}
else
{
return(0);
}
}

MT4 DLL Web Connect


Here is basic way to connect to a website using an MFC dll that will work with MT4.
//---- You need to add these includes at the top of your code
//---- #include <wininet.h>
//---- #include <atlstr.h>
MT4_EXPFUNC int __stdcall Sample( int Whatever )
{
//---- Declare Return Value
CHAR buffer[2048] ;
CString m_strContents;
DWORD dwRead;
/* Connect to the internet */
HINTERNET hiNet = InternetOpen(
L"InetURL/1.0",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
0
);
/* if connection fails throw error */
if( !hiNet ) { return( -1010 ); }
/* Connect to a site */
HINTERNET hConnection = InternetConnect(
hiNet,
L"www.yoursite.com",
INTERNET_DEFAULT_HTTP_PORT,
NULL,
NULL,
INTERNET_SERVICE_HTTP,
0,
0

);
/* if connetion to site failed */
if( !hConnection )
{
InternetCloseHandle(hiNet);
return( -1020 );
} // COULD NOT CONNECT TO WEBSITE
/* Get Data */
HINTERNET hData = HttpOpenRequest( hConnection, L"GET",
L"/yourpage.php", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0 );
if ( !hData )
{
InternetCloseHandle(hConnection);
InternetCloseHandle(hiNet);
return( -1030 );
// PAGE NOT
FOUND
}
HttpSendRequest( hData, NULL, 0, NULL, 0);
bool Done = false;
while( !Done )
{
InternetReadFile( hData, buffer, 255, &dwRead );
if ( dwRead == 0 ) { Done = true; }
buffer[dwRead] = 0;
m_strContents += buffer;
}
//---- Here you can output m_strContents
MessageBox( 0, m_strContents, L"WebPage OutPut", 0 );

InternetCloseHandle(hConnection);
InternetCloseHandle(hiNet);
InternetCloseHandle(hData);

Attached is a Sample VS2008 project.

Das könnte Ihnen auch gefallen