Intx13's MQL4 Beginner Tutorial

[B]intx13’s MQL4 Beginner Tutorial[/B]
[I]Latest installment: 1[/I]

This thread will contain the installments of my tutorial on writing expert advisors in MQL4, the programming environment included in MetaTrader 4. This tutorial is aimed at people who are comfortable with forex, have some experience with technical analysis, but have little or no programming experience. Hopefully it will be useful for people that want to write their own expert advisor but don’t know where or how to start.

I’d love feedback - questions, comments, whatever - as I go along, but please don’t post them here. Start a new topic if you have a question or comment; please don’t put them in the middle of this thread or it will be tough to find each installment.

The installments will be written as I have the time (i.e. don’t hold your breath!). The tentative breakdown is as follows:

[B]1. Introduction to MQL4[/B]
[I]Topics:[/I]
[ul]
[li]Capabilities and limitations
[/li][li]The strategy tester
[/li][li]The programming environment
[/li][/ul]
[I]Code:[/I]
[ul]
[li]hello.mq4
[/li][/ul]

[B]2. Basic Concepts[/B]
[I]Topics:[/I]
[ul]
[li]Functions
[/li][li]Variables and variable types
[/li][li]If/else statements
[/li][li]The “Print” function
[/li][/ul]
[I]Code:[/I]
[ul]
[li]basics.mq4
[/li][/ul]

[B]3. Our First Real Expert Advisor[/B]
[I]Topics:[/I]
[ul]
[li]Constructing and sending orders
[/li][li]Implementing a simple strategy
[/li][/ul]
[I]Code:[/I]
[ul]
[li]ea_2run.mq4
[/li][/ul]

[B]4. Our Second Real Expert Advisor[/B]
[I]Topics:[/I]
[ul]
[li]Loops
[/li][li]Working with arrays
[/li][li]Closing orders manually
[/li][/ul]
[I]Code:[/I]
[ul]
[li]ea_nrun.mq4
[/li][/ul]

[B]5. Analyzing EA Performance[/B]
[I]Topics:[/I]
[ul]
[li]Open and close positions
[/li][li]Win/loss percentages
[/li][li]Using the performance graph
[/li][li]Training and overtraining
[/li][/ul]
[I]Code:[/I]
[ul]
[li]None
[/li][/ul]

[B]6. Our Third Real Expert Advisor[/B]
[I]Topics:[/I]
[ul]
[li]Indicators
[/li][li]Configurable expert advisors
[/li][/ul]
[I]Code:[/I]
[ul]
[li]ea_breakout.mq4
[/li][/ul]

[B]7. Codifying Your Strategy[/B]
[I]Topics:[/I]
[ul]
[li]Human trading and expert advisors
[/li][li]Converting strategy to code
[/li][/ul]
[I]Code:[/I]
[ul]
[li]None
[/li][/ul]

Interested in seeing some other stuff? Let me know! (But not in this thread, please!)

[U][B]Introduction to MQL4: Part 1[/B][/U]

[I]MQL4[/I] (MetaQuotes Language 4) is the programming language/environment used in MetaTrader 4. It is a very powerful, yet fairly simple, environment in which you can write scripts, custom indicators, or expert advisors. We will focus on expert advisors, but much of the same material applies to custom indicators as well. In fact, all of the custom indicators available in MetaTrader are themselves written in MQL.

If you have no programming experience, writing software to implement your chosen strategy may seem like a daunting task. Luckily, MQL4 is easy to learn and most straightforward strategies can be implemented in an afternoon. Of course if you’ve never written a program in your life, you’ll need to learn a bit before you’re ready to write the money-maker that will let you retire at 40! And that’s what this tutorial is all about (the learning, not the retiring).

[B]Capabilities and Limitations[/B]

MQL4 is very powerful. In essence it can do anything that you can, sitting in front of MetaTrader, plus a lot more. One way to think about it is that MetaTrader is this big complex machine that can do many things, and that there are two ways to interface with this machine. There is the graphical user interface (GUI), which lets a human click buttons and type in numbers to analyze the market and place orders, and there is MQL4, which lets a computer program do the same thing.

In MQL4 you can use indicators, analyze the history of the market, open and close positions based on your analysis, and do many complex tasks at once.

There aren’t really any true limitations (a limitation being something that a human can do that MQL4 cannot). The only limitation that one might think of is that the expert advisor is not human (duh!). Your EA is going to make cold, logical decisions and follow them blindly. A human following a strategy can still make high level judgements like “the market looks unstable, I’ll not trade for a bit, even though my strategy says I should buy right now”. An EA will simply buy (unless you have programmed it to analyze the market stability, of course).

[B]The strategy tester[/B]

In “real life”, the idea is to load up your trustworthy expert advisor, attach it to your favorite market, and hey presto! you’re rich. We will not be discussing real-time trading (even on demo accounts) in this tutorial, because it takes forever to see if your system is really working. Instead we will test all of our designs on the [I]strategy tester (back-tester)[/I]. Until you’re comfortable writing MQL programs there’s no real reason to be running EAs on a live account anyway.

The back-tester is a component in MetaTrader 4 that allows you to specify a fake initial deposit size, pick a market and timeframe, and execute an expert advisor against the historical data of that market very quickly, to see how your design would have performed. This lets us examine the long term behavior of an EA without having to wait a long time. So long as the market behaves similarly in the future as it did in the near past (which is a good assumption for the lengths of time used in the back-tester) then we’re in business.

Let’s open the strategy tester.
[ul]
[li]Start MetaTrader 4.
[/li][li]Click “Strategy Tester” under the “View” menu.
[/li][li]The following window should appear at the bottom of the screen.
[/li][/ul]

Let’s test out a built-in expert advisor just to hang of things.
[ul]
[li]Select “MACD Sample” from the “Expert Advisor” menu.
[/li][li]Select your favorite market from the “Symbol” menu.
[/li][li]Select “Every tick” from the “Model” menu.
[/li][li]Select “H1” from the “Period” menu.
[/li][li]Click “Start”
[/li][li]Wait until it completes (may take a while!).
[/li][li]Click “Graph” at the bottom of the strategy tester window.
[/li][/ul]

The expert advisor in progress:

The performance graph after it finishes:

Back-testing an EA is important because we don’t want to get hung up on short-term profits or losses. By testing our code over long periods of time we can analyze its performance in the “big picture”.

[U][B]Introduction to MQL4: Part 2[/B][/U]

[B]The programming environment[/B]

MetaTrader 4 comes with an easy-to-use [I]IDE[/I] (integrated development environment) for writing MQL4 programs. Expert advisors are stored in the “experts” folder of your MetaTrader 4 folder.

Download the file “hello.txt” that is attached to this tutorial and save it to the experts folder of your MetaTrader 4 folder. When you save it, you must save it as “hello.mq4” (this is because BabyPips does not currently allow uploading expert advisors). You can find your MetaTrader 4 folder in the “Program Files” on your system hard drive (Usually “C:\Program Files”).

For example, I am using the version of MetaTrader 4 distributed by Interbank FX, so I would save the file to the “C:\Program Files\Interbank FX Trader 4\experts” folder. There will be some other folders and files in that folder already.

Now we’re going to start up the MQL4 IDE and open up the file we just downloaded.
[ul]
[li]In MetaTrader, click “MetaQuotes Language Editor” under the “Tools” menu.
[/li][/ul]

Now let’s open up the file we just downloaded.
[ul]
[li]Click “Open…” under the “File” menu.
[/li][li]Select “hello” and click “Open”.
[/li][/ul]

The file is now open in the main screen.

It is traditional that the first program you execute when learning a new programming language is a “Hello, world!” program (a program that does nothing but print out “Hello, world!”). We don’t want to break with tradition, so that is what we’ll do :slight_smile:

This program is complete and bug-free. All we need to do is compile it and run it. Compiling converts the program from a text-file that we can read and edit (hello.mq4) to an executable file that MetaTrader 4 can actually use (hello.ex4).
[ul]
[li]Click “Compile”.
[/li][/ul]

The “Errors” window should say “0 error(s), 0 warning(s)”.

Ok, now we want to run the program. Go back to MetaTrader 4 (or press F4 to switch between the IDE and MetaTrader) and make sure that the strategy tester is still open at the bottom of the screen.
[ul]
[li]Select “hello” from the “Expert Advisor” menu.
[/li][li]The rest of the settings don’t matter for this program, since it doesn’t do anything.
[/li][li]Click “Start”.
[/li][li]Wait until it finishes.
[/li][li]Click “Journal” at the bottom of the strategy tester screen.
[/li][/ul]

Among other messages (don’t worry about what they say), you should see the output of the “hello” program. Tada! Your first MQL4 program works like a charm :slight_smile:

That’s all we’re going to cover in this installment - just getting our feet wet. Play around with “hello.mq4” if you like; you can always download it again if you mess it up. Every time you change it you must recompile it (just like we did before) before you run it again! Try moving the Print message to the other parts of the file and see what happens when you compile and run it. Check out the “Results” and “Report” window; run the “MACD Sample” EA again and see what goes in those windows.

Next time we’re going to write an actually useful program, and we’ll talk about what the various parts of the program do and how to write them.

Realy interesting topic please go on :slight_smile:

Don’t worry, more updates coming, once real life settles down a bit… :slight_smile:

i,m really in need of an EA programmer and i need INTX13 to help me please. i’m a newbie and lost so muh money approximately $700.i need help please.its a simple EA

sent you a p.m.

Hi intx13,

Thanks for the valuable info. Been trying to learn for a long time, but find it too difficult to learn. Looking forward to your lessons. :slight_smile:

Hi intx13,

Do you know how to create an alert (sound, visual or both) that pop out once the MACD crossess?

Thanks in advance

great idea for this thread! am subscribed and will be following. I have programming experience but learning a new language’s syntax has always been a learning curve. Look forward to learning more from your posts!

Considering INTX13 posted this several months back, I wouldn’t expect him to reply.

Here is one way of doing it that will give you both a sound and visual alarm. Change the 12 and 26 to the FAST and SLOW EMA you want your MACD to be set to.

if (iMACD(NULL,0,12,26,0,PRICE_CLOSE,MODE_MAIN,0) == 0)
{
Alert("MACD Crossing Zero on “, Symbol(),” at “, Close[0],” - ", TimeToStr(CurTime(),TIME_SECONDS));
}

You can copy and past this into your own Indicator or Expert Advisor using the MetaEditor wizard built into Metatrader. Once in there, use the Navigator to search out functions like iMACD and Alert and they will show you the parameters and you can learn how to set them. The above code compiles with no errors and will work on the pair you put it on (Null) and the timeframe you put it on as the second field in the iMACD function is set to 0.

Thanks Rubberband.
Didn’t notice the thread date

//±-----------------------------------------------------------------+
//| jpin.mq4 |
//| Copyright © 2009, MetaQuotes Software Corp. |
//| MetaTrader 4, MetaTrader 5, TeamWox / MetaQuotes Software Corp. |
//±-----------------------------------------------------------------+
#property copyright “Copyright © 2009, MetaQuotes Software Corp.”
#property link “http://www.metaquotes.net

double CandleHigh, CandleLow,x, y, px, py;

//±-----------------------------------------------------------------+
//| expert initialization function |
//±-----------------------------------------------------------------+
int init()
{
//----

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

//----
return(0);
}
//±-----------------------------------------------------------------+
//| expert start function |
//±-----------------------------------------------------------------+
int start()
{
pin_bar();
Print (iHigh(Symbol(),PERIOD_M15,1));

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

//custom function
int pin_bar()
{
//return 0 if not a pin; return 1 if a pin point up; return 2 if pin point down
//this is almost pin - ie no confirmation by next candle breaks h or l
//to calculate - open of bar1 and close of bar1 must be within high and low of bar2

     CandleHigh           = High [ iHighest ( Symbol(), PERIOD_H1, MODE_HIGH, 2, 1 ) ];
     CandleLow            = Low  [ iLowest  ( Symbol(), PERIOD_H1, MODE_LOW,  2, 1 ) ];
     x = iHigh(Symbol(), PERIOD_M15, 2);
     y = iLow(Symbol(), PERIOD_M15, 2);
     
     px = PRICE_OPEN;
     py = PRICE_CLOSE;
     
     Print ("Price Open ",PRICE_OPEN);
     Print ("Price Close ",PRICE_CLOSE);
     return(0);
  }

I;m just going to try to identify a pinbar on the 15 minute timeframe for the G/U pair.
This is just my first step to a) see if my ea works and b) see what a couple of the actions are.
As you can see in the attached file this code produces a repeating pattern of showing the previous candles high value and price open of 0 and price close of 1 - -I really don’t know what they mean - and so will probably not exist in my next batch of coding.

NOTE - Commented out a bunch of code and it produces exact same results
just printing some stuff basically.

//±-----------------------------------------------------------------+
//| jpin.mq4 |
//| Copyright © 2009, MetaQuotes Software Corp. |
//| MetaTrader 4, MetaTrader 5, TeamWox / MetaQuotes Software Corp. |
//±-----------------------------------------------------------------+
#property copyright “Copyright © 2009, MetaQuotes Software Corp.”
#property link “http://www.metaquotes.net

double CandleHigh, CandleLow,x, y, px, py;

//±-----------------------------------------------------------------+
//| expert initialization function |
//±-----------------------------------------------------------------+
int init()
{
//----

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

//----
return(0);
}
//±-----------------------------------------------------------------+
//| expert start function |
//±-----------------------------------------------------------------+
int start()
{
pin_bar();
Print (iHigh(Symbol(),PERIOD_M15,1));

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

//custom function
int pin_bar()
{
//return 0 if not a pin; return 1 if a pin point up; return 2 if pin point down
//this is almost pin - ie no confirmation by next candle breaks h or l
//to calculate - open of bar1 and close of bar1 must be within high and low of bar2

     //CandleHigh           = High [ iHighest ( Symbol(), PERIOD_H1, MODE_HIGH, 2, 1 ) ];
    // CandleLow            = Low  [ iLowest  ( Symbol(), PERIOD_H1, MODE_LOW,  2, 1 ) ];
    // x = iHigh(Symbol(), PERIOD_M15, 2);
    // y = iLow(Symbol(), PERIOD_M15, 2);
     
   //  px = PRICE_OPEN;
   //  py = PRICE_CLOSE;
     
     Print ("Price Open ",PRICE_OPEN);
     Print ("Price Close ",PRICE_CLOSE);
     return(0);
  }

Trying to get closer to defining a pin bar - still just printing stuff - but my comparisons from what the ea shows and what the platform is - is right on :slight_smile:

//±-----------------------------------------------------------------+
//| jpin.mq4 |
//| Copyright © 2009, MetaQuotes Software Corp. |
//| MetaTrader 4, MetaTrader 5, TeamWox / MetaQuotes Software Corp. |
//±-----------------------------------------------------------------+
#property copyright “Copyright © 2009, MetaQuotes Software Corp.”
#property link “http://www.metaquotes.net

double b1h,b1l,b1o,b1c,b2h,b2l; //b1h = bar 1 high; b1o = bar 1 open

//±-----------------------------------------------------------------+
//| expert initialization function |
//±-----------------------------------------------------------------+
int init()
{
//----

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

//----
return(0);
}
//±-----------------------------------------------------------------+
//| expert start function |
//±-----------------------------------------------------------------+
int start()
{
pin_bar();
Print (iHigh(Symbol(),PERIOD_M15,1));

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

//custom function
int pin_bar()
{
//return 0 if not a pin; return 1 if a pin point up; return 2 if pin point down
//this is almost pin - ie no confirmation by next candle breaks h or l
//to calculate - open of bar1 and close of bar1 must be within high and low of bar2

    double pb1l,pb1h,pb1o,pb1c,pb2h,pb2l; //not entirely sure if need the globals defined above in here
                                          //so i redefined with a p in front for in function pin_bar
                                          
    pb1l = iLow(Symbol(),PERIOD_M15,1);  //would be pinbar low price on 15 minute candle
    pb1h = iHigh(Symbol(),PERIOD_M15,1); // same . . . .. . high . .  .. . .  .   . .  .
    pb1o = iOpen(Symbol(),PERIOD_M15,1); // same open price of would be pin
    pb1c = iClose(Symbol(),PERIOD_M15,1);//      close price of would be pin
    pb2h = iHigh(Symbol(),PERIOD_M15,2); // high of bar before pin
    pb2l = iLow(Symbol(),PERIOD_M15,2); // low of bar before pin
    
    
     Print ("Price Open ",pb1o);
     Print ("Price Close ",pb1c);
     Print ("Pin High ",pb1h);
     Print ("EyeHigh ",pb2h);
     Print ("EyeLow ",pb2l);
     return(0);
  }

a little further along - meeting the first criteria of a pinbar - where the open and close of the would be pin must be within the high and low of the previous candle - attachment shows the little printing -

//±-----------------------------------------------------------------+
//| jpin.mq4 |
//| Copyright © 2009, MetaQuotes Software Corp. |
//| MetaTrader 4, MetaTrader 5, TeamWox / MetaQuotes Software Corp. |
//±-----------------------------------------------------------------+
#property copyright “Copyright © 2009, MetaQuotes Software Corp.”
#property link “http://www.metaquotes.net

double b1h,b1l,b1o,b1c,b2h,b2l; //b1h = bar 1 high; b1o = bar 1 open

//±-----------------------------------------------------------------+
//| expert initialization function |
//±-----------------------------------------------------------------+
int init()
{
//----

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

//----
return(0);
}
//±-----------------------------------------------------------------+
//| expert start function |
//±-----------------------------------------------------------------+
int start()
{
pin_bar();
Print (iHigh(Symbol(),PERIOD_M15,1));

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

//custom function
int pin_bar()
{
//return 0 if not a pin; return 1 if a pin point up; return 2 if pin point down
//this is almost pin - ie no confirmation by next candle breaks h or l
//to calculate - open of bar1 and close of bar1 must be within high and low of bar2

    double pb1l,pb1h,pb1o,pb1c,pb2h,pb2l; //not entirely sure if need the globals defined above in here
                                          //so i redefined with a p in front for in function pin_bar
                                          
    pb1l = iLow(Symbol(),PERIOD_M15,1);  //would be pinbar low price on 15 minute candle
    pb1h = iHigh(Symbol(),PERIOD_M15,1); // same . . . .. . high . .  .. . .  .   . .  .
    pb1o = iOpen(Symbol(),PERIOD_M15,1); // same open price of would be pin
    pb1c = iClose(Symbol(),PERIOD_M15,1);//      close price of would be pin
    pb2h = iHigh(Symbol(),PERIOD_M15,2); // high of bar before pin
    pb2l = iLow(Symbol(),PERIOD_M15,2); // low of bar before pin
    
    if (pb1o < pb2h && pb1o > pb2l && pb1c > pb2l && pb1c < pb2h)
     {
        Print ("The pin passes first step - where the open and close of potential pin is within . . ");
       
     }
    
     Print ("Price Open ",pb1o);
     Print ("Price Close ",pb1c);
     Print ("Pin High ",pb1h);
     Print ("EyeHigh ",pb2h);
     Print ("EyeLow ",pb2l);
     
     
     
     //ok so stuff prints as expected - now what are you going to do with it?
     return(0);
  }

More code - and waiting for somekind of pin to form, but not seeing it yet.

//±-----------------------------------------------------------------+
//| jpin.mq4 |
//| Copyright © 2009, MetaQuotes Software Corp. |
//| MetaTrader 4, MetaTrader 5, TeamWox / MetaQuotes Software Corp. |
//±-----------------------------------------------------------------+
#property copyright “Copyright © 2009, MetaQuotes Software Corp.”
#property link “http://www.metaquotes.net

double b1h,b1l,b1o,b1c,b2h,b2l; //b1h = bar 1 high; b1o = bar 1 open

//±-----------------------------------------------------------------+
//| expert initialization function |
//±-----------------------------------------------------------------+
int init()
{
//----

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

//----
return(0);
}
//±-----------------------------------------------------------------+
//| expert start function |
//±-----------------------------------------------------------------+
int start()
{
pin_bar();

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

//custom function
int pin_bar()
{
//return 0 if not a pin; return 1 if a pin point up; return 2 if pin point down
//this is almost pin - ie no confirmation by next candle breaks h or l
//to calculate - open of bar1 and close of bar1 must be within high and low of bar2

    double pb1l,pb1h,pb1o,pb1c,pb2h,pb2l; //not entirely sure if need the globals defined above in here
                                          //so i redefined with a p in front for in function pin_bar
    double ptotal,bar1total;
                                          
    pb1l = iLow(Symbol(),PERIOD_M15,1);  //would be pinbar low price on 15 minute candle
    pb1h = iHigh(Symbol(),PERIOD_M15,1); // same . . . .. . high . .  .. . .  .   . .  .
    pb1o = iOpen(Symbol(),PERIOD_M15,1); // same open price of would be pin
    pb1c = iClose(Symbol(),PERIOD_M15,1);//      close price of would be pin
    pb2h = iHigh(Symbol(),PERIOD_M15,2); // high of bar before pin
    pb2l = iLow(Symbol(),PERIOD_M15,2); // low of bar before pin
    ptotal = pb1h - pb1l;
    bar1total = pb2h - pb2l;
    
    if (pb1o < pb2h && pb1o > pb2l && pb1c > pb2l && pb1c < pb2h)
     {
        Print ("The pin passes first step - where the open and close of potential pin is within . . ");
       //to take next step , I need to know if I am looking for nose up or down to determine where to use
       //calculations - I think this could be done much easier but I am not seeing it yet.
       if (pb1h > pb2h)  //have to look for nose up in this case
        { Print("inside pin Higher high. . ."); //remove this when done
          if (pb1l > pb2l)  //now have HH and HL of pin so nose up and not IB
           { Print("..now inside  pin has higher low . .");
              // here i want to know that the potential pin is a bit bigger than previous
              // in the future - i want to average this out over several bars.
              if (ptotal > bar1total+(.5*bar1total))
                 { Print (" . . now inside pin is 1.5 times as many pips as previous");
                   // here i want the potential pin to start above 50% of eye
                   if (pb1l > (.5*bar1total+pb2l))
                    {
                       Print ("holy crap batman - a pin formed and looks nice too");
                    }
                     
                 }
                 return (0);
           }
        return (0);  //if only pb1h is > pb2h and lows arenot in line- need return 0 no pin 
        }
     return (0); //could not find pin  
     }
     else
        Print("not even close");
     return(0);
  }

Thks Intx13! Helped a lot!

Alright kiddies, this may be biting off more than I can chew, but I’m looking to set up an EA. The basic outline of the EA is this:

Buy currency pair when signal EMA(10) crosses OVER EMA(25)
Sell currency pair when signal EMA(10) crosses BELOW EMA(25)

If anyone has any ideas as to which direction I should be taking on this, and how to layout the code, it would be friggin sweet.

Buy currency pair when signal EMA(10) crosses OVER EMA(25)
Sell currency pair when signal EMA(10) crosses BELOW EMA(25)

Now I’m no expert at mql4 so I don’t know the syntax. Here’s some psuedo code that might help you get started. There are plenty of good tutorials out there that can give you the syntax and teach you how to programm the trade operations. I am currently learning too. Hope this helps. I’m sure there are things I missed so if anyone can correct this I’d be grateful for it too.


if(EMA(10) > EMA(25) & last tick EMA(25) > EMA(10)){
     if(active sell trade){
             Work out what you want to do with your short trade.
             What are your exit criteria?
             Make new long trade.
     else if(active long trade){
             Do nothing.
     else{
             Make trade.
     }
else if(EMA(10) < EMA(25) & last tick EMA(25) < EMA(10)){
Invert what I did above.
}