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

Andrey Kornishkin | 1 September, 2010

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:

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:

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.