Download MetaTrader 5

How to Quickly Create an Expert Advisor for Automated Trading Championship 2010

1 September 2010, 13:21
Andrew Kornishkin
3
5 357

Introduction

In order to develop an expert to participate in Automated Trading Championship 2010, let's use a template of ready expert advisor from The Prototype of Trade Robot article. Even novice MQL5 programmer will be capable of this task, because for your strategies the  basic classes, functions, templates are already developed. It's enough to write a minimal amount of code to implement your trading idea.  

What we will need to prepare:
  • Selection of strategy
  • Writing an Expert Advisor
  • Testing
  • Optimization in Strategy Tester
  • Optimization of the strategy
  • Testing on different intervals

1. Selection of Strategy

It is believed that trading with trend is more profitable than trading in a range, and the bounce from the intraday levels occurs more frequently than the breakdown of channel borders.

Based on these assumptions, we will open position towards the current trend on the bounce from the channel boundaries (Envelopes). We'll close position on a signal to close position or when the Stop Loss or Take Profit levels will be reached.

  As the trend signal we'll use MACD growth or dwindling on the daily chart, and we will trade on the bounce from the channel boundaries on the hour timeframe.  

Figure 1. MACD Indicator on EURUSD Daily Chart

Figure 1. MACD Indicator on EURUSD Daily Chart

If MACD indicator grows on two bars in succession - this is the Buy signal. If it dwindles on two bars in succession - this is the Sell signal.

Figure 2. Price Bounce from the Envelopes Boundaries

Figure 2. Price Bounce from the Envelopes Boundaries


2. Writing an Expert Advisor 

2.1. Included Modules

The expert will use the ExpertAdvisor class from the ExpertAdvisor.mqh module.

#include <ExpertAdvisor.mqh>

2.2. Input Variables

input int    SL        =  50; // Stop Loss distance
input int    TP        = 100; // Take Profit distance
input int    TS        =  50; // Trailing Stop distance
input int    FastEMA   =  15; // Fast EMA
input int    SlowEMA   =  26; // Slow EMA
input int    MACD_SMA  =   1; // MACD signal line
input int    EnvelPer  =  20; // Envelopes period
input double EnvelDev  = 0.4; // Envelopes deviation
input double Risk      = 0.1; // Risk

2.3. Create a Class Inherited From CExpertAdvisor

class CMyEA : public CExpertAdvisor
  {
protected:
   double            m_risk;          // size of risk
   int               m_sl;            // Stop Loss
   int               m_tp;            // Take Profit
   int               m_ts;            // Trailing Stop
   int               m_pFastEMA;      // Fast EMA
   int               m_pSlowEMA;      // Slow EMA
   int               m_pMACD_SMA;     // MACD signal line
   int               m_EnvelPer;      // Envelopes period
   double            m_EnvelDev;      // Envelopes deviation
   int               m_hmacd;         // MACD indicator handle
   int               m_henvel;        // Envelopes indicator handle
public:
   void              CMyEA();
   void             ~CMyEA();
   virtual bool      Init(string smb,ENUM_TIMEFRAMES tf); // initialization
   virtual bool      Main();                              // main function
   virtual void      OpenPosition(long dir);              // open position on signal
   virtual void      ClosePosition(long dir);             // close position on signal
   virtual long      CheckSignal(bool bEntry);            // check signal
  };
//------------------------------------------------------------------
2.4. Delete Indicators
//------------------------------------------------------------------    
void CMyEA::~CMyEA()
  {
   IndicatorRelease(m_hmacd);  // delete MACD indicator
   IndicatorRelease(m_henvel); // delete Envelopes indicator
  }
//------------------------------------------------------------------    
2.5. Initialize Variables
//------------------------------------------------------------------    Init
bool CMyEA::Init(string smb,ENUM_TIMEFRAMES tf)
  {
   if(!CExpertAdvisor::Init(0,smb,tf)) return(false);    // initialize parent class
   // copy parameters
    m_risk=Risk; 
   m_tp=TP; 
   m_sl=SL; 
   m_ts=TS;
   m_pFastEMA=FastEMA; 
   m_pSlowEMA=SlowEMA; 
   m_pMACD_SMA=MACD_SMA;
   m_EnvelPer = EnvelPer;
   m_EnvelDev = EnvelDev;
   m_hmacd=iMACD(m_smb,PERIOD_D1,m_pFastEMA,m_pSlowEMA,m_pMACD_SMA,PRICE_CLOSE);      // create MACD indicator
   m_henvel=iEnvelopes(m_smb,PERIOD_H1,m_EnvelPer,0,MODE_SMA,PRICE_CLOSE,m_EnvelDev); // create Envelopes indicator
   if(m_hmacd==INVALID_HANDLE ||m_henvel==INVALID_HANDLE ) return(false);             // if there is an error, then exit
   m_bInit=true; 
   return(true);                                                                      // trade allowed
  } 

2.6. Trade Function

//------------------------------------------------------------------    CheckSignal
long CMyEA::CheckSignal(bool bEntry)
  {
   double macd[4],   // Array of MACD indicator values
         env1[3],    // Array of Envelopes' upper border values
         env2[3];    // Array of Bollinger Bands' lower border values
   MqlRates rt[3];   // Array of price values of last 3 bars
   
   if(CopyRates(m_smb,m_tf,0,3,rt)!=3) // Copy price values of last 3 bars to array
     {
       Print("CopyRates ",m_smb," history is not loaded"); 
        return(WRONG_VALUE);
     }
   // Copy indicator values to array
   if(CopyBuffer(m_hmacd,0,0,4,macd)<4 || CopyBuffer(m_henvel,0,0,2,env1)<2 ||CopyBuffer(m_henvel,1,0,2,env2)<2)
     { 
        Print("CopyBuffer - no data"); 
       return(WRONG_VALUE);
     }
   // Buy if MACD is growing and if there is a bounce from the Evelopes' lower border
   if(rt[1].open<env2[1] && rt[1].close>env2[1] && macd[1]<macd[2] &&  macd[2]<macd[3])
      return(bEntry ? ORDER_TYPE_BUY:ORDER_TYPE_SELL); // condition for buy
   // Sell if MACD is dwindling and if there is a bounce from the Evelopes' upper border
   if(rt[1].open>env1[1] && rt[2].close<env1[1]&& macd[1]>macd[2] &&  macd[2]>macd[3])
      return(bEntry ? ORDER_TYPE_SELL:ORDER_TYPE_BUY); // condition for sell

   return(WRONG_VALUE); // if there is no signal
  }

CMyEA ea; // class instance

And so, after writing the code, send the resulting expert to Strategy Tester.


3. Testing 

In Strategy Tester for the "Last year" period on EURUSD we get the following chart:

Figure 3. Results of Testing the Trading System with Initial Parameters

Figure 3. Results of Testing the Trading System with Initial Parameters

The results are not impressive, so let's start to optimize the Stop Loss and Take Profit levels.


4. Optimization in Strategy Tester

We will optimize the Stop Loss and Take Profit parameters at the interval 10-500 with step 50.

Best results: Stop Loss = 160, Take Profit = 310. After Stop Loss and Take Profit optimization we received 67% of profitable trades against the previous 36% and net profit of $1522.97. Thus, by simple manipulations, we've upgraded our system to break-even and even got some profit.

Figure 4. Results of Testing the Trading System with Optimized Stop Loss and Take Profit

Figure 4. Results of Testing the Trading System with Optimized Stop Loss and Take Profit

Next let's optimize the Envelopes period and deviation.

Envelopes period will change from 10 to 40 with step 4, and deviation - from 0.1 to 1 with step 0.1.

The best optimization results are: Envelopes period = 22, Envelopes deviation = 0.3. Even now we've got $14418.92 net profit and 79% of profitable trades.

Figure 5. Results of Testing the Trading System with Optimized Envelopes Period and Deviation

Figure 5. Results of Testing the Trading System with Optimized Envelopes Period and Deviation

If we increase the risk to 0.8, we'll get $77330.95 net profit.

Figure 6. The Results of Testing the Trading System with Optimized Risk

Figure 6. The Results of Testing the Trading System with Optimized Risk

 

5. Optimization of the Strategy

Optimization of the strategy may consist of the following steps:

  • Change trend indicator
  • Select another envelope
  • Select another timeframe
  • Change trade conditions

5.1. Change Trend Indicator

As we can see from the Several Ways of Finding a Trend in MQL5 article, the best trend indicators are moving average and a "fan" of moving averages.

Let's replace the MACD indicator with simple moving average. The expert's code can be found in the attached Macena.mq5 file.

5.2. Select Another Envelope

Besides the Envelopes you can also select another envelope at our disposal. For example, Price Channel, Bollinger Bands or an envelope based on moving averages.

An example of expert, that uses MA and Bollinger Bands, can be found in the attached Maboll.mq5 file.

5.3. Select Another Timeframe

Let's change the timeframe to bigger or lesser. As a bigger timeframe - take H4, as the lesser - M15, and then test and optimize your system.

To do this, replace only one line in the code:

m_henvel=iEnvelopes(m_smb,PERIOD_H1,m_EnvelPer,0,MODE_SMA,PRICE_CLOSE,m_EnvelDev);  // create Envelopes indicator

In the case of H4 timeframe:

m_henvel=iEnvelopes(m_smb,PERIOD_H4,m_EnvelPer,0,MODE_SMA,PRICE_CLOSE,m_EnvelDev);  // create Envelopes indicator 

For the M15 timeframe: 

m_henvel=iEnvelopes(m_smb,PERIOD_M15,m_EnvelPer,0,MODE_SMA,PRICE_CLOSE,m_EnvelDev);  // create Envelopes indicator

5.4. Change Trade Conditions

As an experiment, also let's change trade conditions.  

  1. Make the system able to reverse. We will buy on the bounce from the Envelope's lower boundary, and sell on the bounce from the Envelopes upper boundary.
  2. Check the system without following the day trend. This is done simply by inserting the following code into trade block:
    //------------------------------------------------------------------ CheckSignal
    long CMyEA::CheckSignal(bool bEntry)
      {
       double env1[3],   // Array of Envelopes' upper border values
             env2[3];    // Array of Bollinger Bands' lower border values
       MqlRates rt[3];   // Array of price values of last 3 bars
    
       if(CopyRates(m_smb,m_tf,0,3,rt)!=3) // Copy price values of last 3 bars to array
         {
          Print("CopyRates ",m_smb," history is not loaded");
          return(WRONG_VALUE);
         }
    // Copy indicator values to array
       if(CopyBuffer(m_henvel,0,0,2,env1)<2 || CopyBuffer(m_henvel,1,0,2,env2)<2)
         {
          Print("CopyBuffer - no data");
          return(WRONG_VALUE);
         }
    // Buy if there is a bounce from the Evelopes' lower border
       if(rt[1].open<env2[1] && rt[1].close>env2[1])
          return(bEntry ? ORDER_TYPE_BUY:ORDER_TYPE_SELL); // condition for buy
    // Sell if there is a bounce from the Evelopes' upper border
       if(rt[1].open>env1[1] && rt[2].close<env1[1])
          return(bEntry ? ORDER_TYPE_SELL:ORDER_TYPE_BUY); // condition for sell
    
       return(WRONG_VALUE); // if there is no signal
      }
    
    CMyEA ea; // class instance
    //------------------------------------------------------------------    OnInit
    

     3. We will close short position when the price did not go far down, but turned and went up.

     4. We will close long position when the price did not go far up, but turned and went down.

You can invent many other ways to optimize a trading strategy, some of them are described in corresponding literature.

Further researches are up to you.


6. Testing on Different Intervals

Test our Expert Advisor on equal intervals of time with a shift of 1 month. Let's take the "Last year" as a testing period. Period of time - 3 months.

Testing interval
Profit, USD
Profitable trades
 1.01.2010 - 30.03.2010
7239.50 76.92%
 1.02.2010 - 30.04.2010 -6577.50 0%
 1.03.2010 - 30.05.2010 -8378.50 50%
 1.04.2010 - 30.06.2010 -6608.00 0%
 1.05.2010 - 30.07.2010  41599.50 80%
  1.06.2010 - 30.08.2010  69835.50  85%
Summary: It's not desirable to use Expert Advisor with such an aggressive money management. Reduce the risk.


Conclusion

Brief conclusion: on the basis on this template you can quite quickly implement your trading idea with minimum of time and effort.

Optimization of system parameters and trade criteria is also makes no problems.

To create a more stable working trading system, it is desirable to optimize all parameters over longer time intervals.

List of used sources:
  1. 20 Trade Signals in MQL5 article.
  2. The Prototype of Trade Robot article.
  3. Several Ways of Detecting a Trend in MQL5 article.
  4. Expert Advisors Based on Popular Trading Systems and Alchemy of Trading Robot Optimization article.
  5. Limitations and Verifications in Expert Advisors article.
  6. Writing an Expert Advisor Using the MQL5 Object-Oriented Programming Approach article.
  7. Functions for Money Management in an Expert Advisor article.   

Translated from Russian by MetaQuotes Software Corp.
Original article: https://www.mql5.com/ru/articles/148

Attached files |
mabol.mq5 (6.65 KB)
macena.mq5 (6.94 KB)
maena.mq5 (6.58 KB)
Last comments | Go to discussion (3)
okwh
okwh | 8 Sep 2010 at 10:24

Please give some sample code for folloe thr rules of Championship 2010.

It is not easy to code since using position, order, and deal to manage order in mql5, and some functions like ordertotal() not always work right.

for example, iinsdie Ontrade() function,   ordertotal()  always return  0 at test mode.

koko
koko | 23 Sep 2010 at 23:06

Where all the files go? I put them in" C:\Program Files\MetaTrader 5\MQL5\Experts " and try to compile them and compiler shows a bunch of errors...?!?

Although I've managed to write few indicators in MQL5 I dont like the way MQL is going... too complicated.

I'm on Win7 x64. I cant believe I  cant use already written code...!!!  

Rashid Umarov
Rashid Umarov | 24 Sep 2010 at 03:00
Read client terminal help (F1)



Step on New Rails: Custom Indicators in MQL5 Step on New Rails: Custom Indicators in MQL5

I will not list all of the new possibilities and features of the new terminal and language. They are numerous, and some novelties are worth the discussion in a separate article. Also there is no code here, written with object-oriented programming, it is a too serous topic to be simply mentioned in a context as additional advantages for developers. In this article we will consider the indicators, their structure, drawing, types and their programming details, as compared to MQL4. I hope that this article will be useful both for beginners and experienced developers, maybe some of them will find something new.

Here Comes the New MetaTrader 5 and MQL5 Here Comes the New MetaTrader 5 and MQL5

This is just a brief review of MetaTrader 5. I can't describe all the system's new features for such a short time period - the testing started on 2009.09.09. This is a symbolical date, and I am sure it will be a lucky number. A few days have passed since I got the beta version of the MetaTrader 5 terminal and MQL5. I haven't managed to try all its features, but I am already impressed.

False trigger protection for Trading Robot False trigger protection for Trading Robot

Profitability of trading systems is defined not only by logic and precision of analyzing the financial instrument dynamics, but also by the quality of the performance algorithm of this logic. False trigger is typical for low quality performance of the main logic of a trading robot. Ways of solving the specified problem are considered in this article.

Using text files for storing input parameters of Expert Advisors, indicators and scripts Using text files for storing input parameters of Expert Advisors, indicators and scripts

The article describes the application of text files for storing dynamic objects, arrays and other variables used as properties of Expert Advisors, indicators and scripts. The files serve as a convenient addition to the functionality of standard tools offered by MQL languages.