QF Trading Workshop
Current location: Home > Workshops > QF Trading Workshop

Workshop #4 Program Trading using MQL4

Posted:2021-03-26 11:53:28 Click:1490

Workshop 4 - MQL Programing

1. Introduction

In Lab 7, we learnt the programming basics of MQL4 and how to build and compile simple MT4 EA programs.

As mentioned, the main purpose of MQL programming is to build and implement real-time trading strategy and automatic trading systems.

In this Lab, we learnt how to build a real-time trading system with the trading strategy and technical analytical technique we have learnt in the lectures.

2. Trading Strategy

Throughout the years, traders all over the years study various kind of trading techniques and strategies, we have summarized SEVEN major trading techniques / strategies.

They are:

1. Trend Trading Strategy

2. Breakout Trading Strategy

3. Reversal Trading Strategy

4. Channel Trading Strategy

5. Averaging Trading Strategy

6. Stop-loss Trading Strategy

7. Hedge Trading Strategy

As mentioned in the lecture, these strategies can be combined together and used one single or multiple financial products. In particular, Stop-Loss / Hedge-Trading Strategy are important risk control strategies that should be adopted in every trading session.

3. Technical Analytical Techniques

In Lab 7, we have learnt the basics MQL programming. One of the most important functions of MQL is the build-in Technical Indicator/Oscillator function library so that they can be easily adopted and used for the development of TA-based trading strategies for real-time automatic trading.

In fact, MQL library has totally 39 build-in TA indicators/oscillators which include ALL commonly used TA tools including:-

- Moving Averages (MA)


- Stochastics


- Bollinger Bands (BB)

In this Lab, we will use RSI indicator as an example to demonstrate how to use MQL TA indicator to build a real-time TA-based trading system.

4. Lab4_2_RSI_30 RSI-based EA Automatic Trading System

4.1 Introduction

As mentioned in the lecture of Technical Analysis using Technical Indicators and Osicllators, RSI indicator provides us a effective way for the judgment of Over-Buy & Over-Sell of financial product.
In general, RSI > 70 (Over-Buy) with a good chance of price reversal, while RSI < 30 (Over-Sell) with a high chance of price rebound.
The following Lab7_2_RSI_30 studies how to use MQL to write a automatic trading program with the application of R7_1SI 30 Buying Strategy.

As a realistic automatic trading program, we have certain additional criteria:

- The EA program is generic to be used for any financial products.

- The program will be started automatically every morning at 0700 localtime.

- After 0700, the program will check whether the hourly RSI has dropped to 30 level, trigger the buy order automatically if there is NO outstanding order.

- The automatic program will “sleep” after 2100, to avoid chaotic fluctuation during the US trading time.

4.2 Program Initialization

For program declaration:

- Define the total transaction volume TPLot = 1.0.

- Define the current and previous time hour as cHH & pHH.

- Define current price as cPrice.

- Define current H1 as CRSI.

- Set the Stop-loss and Target-profit as 150 & 300 pts.

- Define the status and RSI_Pass signals as bBUY_STOP, bBUY_PASS1.

- Set the RSI 30 Level as nBUY_PASS1

// Global variables

extern double  TPLot=1.0;                // Transaction Volume 1 Lot

extern int     cHH=0;                    // Current HOUR
extern int     pHH=0;                    // Previous HOUR
extern double  cPRICE=0;                 // Current Price
extern string  sPRICE="";                // Current Price string
extern double  cRSI=0;                   // Current M30_RSI value
extern int     sl=150;                   // Stop Loss 150
extern int     tp=300;                   // Target Price 300
extern string  TPSymbol="";              // Product Symbol
extern int     TPMagic=88888;            // Product Magic No

extern bool    bBUY_STOP=false;          // SIGNAL : STOP PLACING ORDER
extern bool    bBUY_PASS1=false;         // SIGNAL : BUY_PASS1
extern double  nBUY_PASS1=30.0;          // BUY_PASS1 RSI LEVEL
extern string  sBUY_SIGNAL="NOSIG";      // SIGNAL VALUE


In real-world practise, we commonly used "signalling" technique to indicate/set the current status  of EVERY TA indicator and oscillator used in the system instead of taken trading right away when certain criteria is matched.

The main reasons are:

1) The trading strategy might be changed/evolved to become more complex, using "signalling" method can effectively separate the current status of the TA indicator with the  action(s) being taken for program development and maintenance.

2) In case of complex trading strategy which might involve the monitoring of multiple TA indicators/oscillators,  "Signalling Technique" provides an easy way for system development and real-time testing and monitoring.

4.3 Program Initialization

For program initialization, we need to reset all the Time related variables and RSI BUY related signals.

Like this:

int init()
pHH                 = 0;
cHH                 = 0;
bBUY_STOP           = false;
bBUY_PASS1          = false;
cPRICE              = 0;
TPSymbol            = Symbol();

Note: Remember to implement the deinit() module as well.

4.4 Core Program - The start() Module

4.4.1 First. Get the current Time Hour

// Get Current Time Hour
cHH         = TimeHour(TimeLocal());

4.4.2 Every morning at 0700, reset the status:


// Refresh the Status Every Morning
if ((pHH==6) && (cHH==7))
bBUY_STOP         = false;
bBUY_PASS1        = false;
sBUY_SIGNAL       = "NOSIG";

Note: We Document that section as "BUY Order Section" as you will later write the "SELL Order Section". It  is good practice to do so for the clarity of the program.

4.4.3 Get the current Ask price for BUY (not Bid,  remember why?)

// Get Current Price Quote
cPRICE = Ask;
sPRICE = DoubleToString(cPRICE,5);

4.4.4 Get the current H1 RSI by using iRSI() function

// Get current RSI value

4.4.5 Check for existing Buying order by calling nActiveBUYOrder() function

// Don't trigger if there is outstanding order
if (nActiveBUYOrder()>=1)
bBUY_STOP         = true;
sBUY_SIGNAL       = "ASTOP";

Note: In real world application, such status checking is VERY IMPORTANT as we (or our clients) will start this application 24x7 and more importantly will use in multiple products. By doing so, we can limit the number of "Active order" being triggered at the same time (day). Of course, one can set it to other value such as >= 3 (orders).

4.4.6 The nActiveBUYOrder() function

int nActiveBUYOrder()
int a=0;
for(int i1=0;i1 {

4.4.7 Check whether reach the “sleeping” time

// Stop the process after H21
if (TimeHour(TimeLocal())>=21)
bBUY_STOP         = true;
sBUY_SIGNAL       = "NSTOP";

4.4.8 Check whether hit the RSI 30 Level, signal the PASS1 when hit:

if (!bBUY_STOP && !bBUY_PASS1 && (cRSI {
bBUY_PASS1        = true;
sBUY_SIGNAL       = "PASS1";

4.4.9 Place BUY order when PASSS_1 Signal is ON

if (!bBUY_STOP && bBUY_PASS1)
sBUY_SIGNAL       = "ORDER";
bBUY_STOP         = true;

4.4.10 BUYOrder function

int BUYORDER(double Lots,double sloss,double tprice,string comment,int magic2)
int nticket=0;

nticket=OrderSend(TPSymbol ,OP_BUY,Lots,Ask,0,Bid-sloss*Point,Ask+tprice*Point,comment,magic2,0,Red);

4.4.11 Here is the OrderSend() function structure

4.4.12 Lastly: Print the current status and wait for 15 seconds and loop again

Print(TPSymbol," : PRICE=",sPRICE," RSI=",cRSI," ",TPSymbol," : BUY=",sBUY_SIGNAL);

// Update pDAY=cDAY
pHH = cHH;

// Sleep for 15 secs

4.4.13 Put them ALL together into Lab7_2_RSI_30.mq4 and Compile it

If everything okay, it should be like this:

5. Lab4_3_RSI_30B_70S

Using the same skill set, write the second-part of the RSI 30/70 EA program by integrating the RSI 70 Selling Strategy.

Name it as Lab7_3_RSI_30B_70S.mq4.


1. To maintain a good EA programming practice, separate the RSI BUY and SELL sections clearly in terms of program declaration, core program coding and program subroutines.

2. Implement the SELLORDER() and nActiveSELLOrder() subroutines.

6. Variations of RSI_30/70 Signalling Strategy

Some Technical Analysts and experienced traders believe that it is much better to implement the RSI 30/70 Buying/Selling strategy NOT when RSI hit the RSI 30/70 thresholds, but rather when it returns/rebounded back to these two RSI thresholds.

In order to do so we have to:

1) To create 2 more thresholds, that is a over-sell threshold <30 (RSI_Base, say 25) and over-buy threshold >70 (RSI_Top, say 75) in which the RSI have to reach not only the RSI 30/70 levels, but also these threshold and returns/rebounds back to RSI 30/70 to trigger the Buying/Selling signal.

2) To create 4 more signals, 2 for RSI-BUY and 2 for RSI-SELL. That is, in case of RSI-30 case, we need THREE signals, one for first enter RSI 30, one for hitting RSI_Base and one for rebound back to RSI 30. Same for RSI-70 case.

By using "RSI Signalling" technique mentioned in the previous Lab example, it can be easily implemented.

Write this RSI variation EA program and named as Lab7_4_RSI_30_25_30B_70_75_70S and try to implement it in your MT4 demo account.

Compare the performance of these TWO trading problem for a week to see which one is better.

7. Integration with other TA Tools

As mentioned in the lecture, RSI indicator is commonly used together with other TA indicator such as MA, Stochastics, MACD and Bollinger Bands to give us more reliable trading signals.

So implement these integrated multiple TA-based trading programs:-

7.1 MA with RSI (e.g. MA(5), MA(14) with RSI(14))

7.2 MACD with RSI (e.g. MACD(12,26,9) with RSI(14))

7.3 Stochastic with RSI (e.g. Stochastic(5,3,3) with RSI(14))

7.4 MACD + Stochastic + RSI (Actually this combination is commonly used in the industry and many TA and trader believe it gives a more reliable trading signals).

Note: Try to implement these EAs and compare their performance for at least 10-trading days. (Of course using your demo account for experimental purposes.)