Cómo crear rápidamente un Expert Advisor para el Campeonato de Trading Automatizado 2010

Andrey Kornishkin | 11 marzo, 2014

Introducción

Con el fin de desarrollar un Expert Advisor para participar en el Automated Trading Championship 2010 (Campeonato de Trading Automatizado 2010), vamos a utilizar una plantilla de Expert Advisor lista a partir del artículo El prototipo del Robot de trading. Incluso los programadores principiantes en MQL5 serán capaces de realizar esta tarea, puesto que las clases básicas, funciones y plantillas ya están listas para sus estrategias. Es suficiente para escribir la cantidad mínimo del código para implementar su idea de trading.  

Lo que tenemos que preparar:

1. Elección de la estrategia

Se cree que el trading con la tendencia es más rentable que el trading en un rango, y que el salto a partir de los niveles intradía ocurre con más frecuencia que la ruptura de los bordes del canal.

Basándonos en estos supuestos, vamos a abrir una posición en la dirección de la tendencia actual sobre los saltos entre los límites del canal (Envolventes). Cerraremos la posición al recibir una señal de cierre de posición o cuando se alcanza el nivel Stop Loss o Take Profit.

  Cómo señal de tendencia vamos a utilizar el crecimiento o la disminución de MACD en el gráfico diario, y operaremos sobre los saltos entre los límites del canal con períodos de tiempo por horas.  

Figura 1. El indicador MACD sobre el gráfico EURUSD diario

Figura 1. El indicador MACD sobre el gráfico EURUSD diario

Si el indicador MACD crece en dos barras sucesivas -es una señal de Compra. Si decrece en dos barras sucesivas -es una señal de Venta.

Figura 2. Salto de precios de los límites de las envolventes

Figura 2. Salto de precios de los límites de las envolventes


2. Escritura de un Expert Advisor 

2.1. Módulos incluidos

El Expert Advisor va a utilizar la clase ExpertAdvisor del módulo ExpertAdvisor.mqh.

#include <ExpertAdvisor.mqh>

2.2. Variables de entrada

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. Crear una clase heredada de 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. Eliminar indicadores
//------------------------------------------------------------------    
void CMyEA::~CMyEA()
  {
   IndicatorRelease(m_hmacd);  // delete MACD indicator
   IndicatorRelease(m_henvel); // delete Envelopes indicator
  }
//------------------------------------------------------------------    
2.5. Inicializar 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. Función de trading

//------------------------------------------------------------------    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

Y por lo tanto, después de escribir el código, envía el resultado del Expert Advisor al Probador de Estrategias.


3. Pruebas 

En el Probador de estrategias obtenemos el siguiente gráfico para el intervalo del "Último año" con EURUSD:

Figura 3. Resultados de la prueba del sistema de trading con los parámetros iniciales

Figura 3. Resultados de la prueba del sistema de trading con los parámetros iniciales

Los resultados no son muy alentadores, así que vamos a empezar a optimizar el Stop Loss y el Take Profit.


4. Optimización en el Probador de Estrategias

Vamos a optimizar los parámetros del Stop Loss y Take Profit en el intervalo 10-500 con pasos de 50.

Mejores resultados: Stop Loss = 160, Take Profit = 310. Después de la optimización de Stop Loss y Take Profit hemos conseguido el 67% de operaciones rentables frente al anterior 36% y un beneficio neto de 1522,97 $. De este modo, con unos procedimientos sencillos, hemos mejorado nuestro sistema para el punto de equilibrio e incluso conseguir alguna ganancia.

Figura 4. Resultados de la prueba del sistema de trading con Stop Loss y Take Profit optimizados

Figura 4. Resultados de la prueba del sistema de trading con Stop Loss y Take Profit optimizados

A continuación, vamos a optimizar el período y la desviación de las envolventes.

El intervalo de las envolventes varía de 10 a 40 con un paso de 40 y la desviación de 0.1 a 1 con un paso de 0.1.

Los mejores resultados de la optimización son: Período de las envolventes = 22, Desviación de las envolventes = 0.3. Incluso ahora, tenemos 14418.19 $ de beneficio neto y el 79% de operaciones rentables.

Figura 5. Resultados de la prueba del sistema de trading con optimización del período y la desviación de las envolventes

Figura 5. Resultados de la prueba del sistema de trading con optimización del período y la desviación de las envolventes

Si aumentamos el riesgo a 0.8 obtendremos 77330.95 $ de beneficio neto.

Figura 6. Resultados de la prueba del sistema de trading con optimización del riesgo.

Figura 6. Resultados de la prueba del sistema de trading con optimización del riesgo.

 

5. Optimización de la estrategia

La optimización de la estrategia puede consistir en los siguientes pasos:

5.1. Cambio del indicador de tendencia

Como podemos observar del artículo Distintas maneras de averiguar la tendencia en MQL5, los mejores indicadores de tendencia son el promedio móvil y el "abanico" (fan) de los promedios móviles.

Vamos a sustituir el indicador MACD por un promedio móvil sencillo. Se puede encontrar el código del Expert Advisor en el archivo adjunto Macena.mq5.

5.2. Seleccionar otra envolvente

Además de las Envolventes, también puede elegir otras envolventes que están a su disposición. Por ejemplo, Price Channel (Canal de precios), Bollinger Bands (Bandas de Bollinger) o una envolvente basada en promedios móviles.

En el archivo adjunto Maboll.mq5, se puede encontrar un ejemplo de un Expert Advisor que usa el Promedio móvil y las Bandas de Bollinger.

5.3. Seleccionar otro período de tiempo

Vamos a cambiar el período de tiempo de mayor a menor. Escogemos H4 como período de tiempo mayor y M15 como el menor, y después probamos y optimizamos nuestro sistema.

Para hacer esto, sólo sustituimos una línea del código:

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

En el caso del período H4:

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

Para el período M15: 

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

5.4. Cambiar las condiciones del trading

Como experimento, vamos a cambiar también las condiciones del trading.  

  1. Hacer que el sistema sea capaz de invertir. Compraremos en el salto del límite inferior de la envolvente, y venderemos en el salto del límite superior de la envolvente.
  2. Comprobaremos el sistema sin seguir la tendencia del día. Esto se hace insertando el siguiente código en el bloque de la operación:
    //------------------------------------------------------------------ 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. Cerraremos la posición corta cuando el precio no baja mucho, pero da la vuelta y sube.

     4. Cerraremos la posición larga cuando el precio no sube mucho, pero da la vuelta y baja.

Puede inventar muchas otras maneras de optimizar una estrategia de trading, algunas de ellas están descritas en la documentación pertinente.

Más búsquedas dependen de ti.


6. Pruebas en distintos intervalos de tiempo

Probamos nuestro Expert Advisor en intervalos iguales de tiempo con un desplazamiento de 1 mes. Vamos a escoger el "Último año" como intervalo de prueba. Período de tiempo - 3 meses

Intervalo de la prueba
Ganancia, USD
Operaciones rentables
 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%
Resumen: No se recomienda utilizar el Expert Advisor con una gestión de fondos tan agresiva. Reduzca el riesgo.


Conclusión

Una breve conclusión: en base a las plantillas, puede implementar rápidamente su idea de trading con un mínimo de tiempo y esfuerzo.

La optimización de los parámetros del sistema y los criterios del trading se hacen también sin problemas.

Para crear un sistema de trading con un funcionamiento más estable, se recomienda optimizar todos los parámetros en intervalos de tiempo más largos.

Lista de los recursos utilizados:
  1. El artículo 20 señales de trading en MQL5.
  2. El artículo El prototipo del Robot de trading.
  3. El artículo Distintas maneras de averiguar la tendencia en MQL5.
  4. El artículo Asesores Expertos basados ​​en los sistemas de trading populares y la alquimia de la optimización del robot de trading.
  5. El artículo Limitaciones y verificaciones en Expert Advisors.
  6. El artículo Escribir un Expert Advisor mediante la programación orientada a objetos de MQL5.
  7. El artículo Funciones para la Gestión de fondos en un Expert Advisor.