Descargar MetaTrader 5

Ampliación de la librería estándar de MQL5 y la reutilización del código

7 mayo 2014, 13:21
Jordi Bassaganas
0
496

Introducción

La librería estándar de MQL5 es un marco de trabajo (framework) compuesto por un conjunto de clases listas para usar, que hacen que su vida como desarrollador sea más sencilla. No obstante, no abarca todas las necesidades de todos los desarrolladores alrededor del mundo, con lo cual querrá tener a su disposición más material personalizado para dar un paso más y ampliarla. En este artículo se describe la integración del indicador técnico Zig-Zag de MetaQuotes en la librería estándar. Para conseguir nuestro objetivo, nos basaremos en la filosofía de diseño de MetaQuotes.

En pocas palabras, la interfaz de programación de aplicaciones (API por sus siglas en inglés) está diseñada para proporcionarle fiabilidad, flexibilidad y facilidad de mantenimiento, así como la ventaja de reutilizar el código. Esto es lo que dice la teoría, pero más allá de todo esto, si planea seguir progresando en MQL5 y desarrollar cosas más sofisticadas, como los Asesores Expertos multidivisa, tendrá primero que dominar la librería estándar para garantizar el éxito de sus aplicaciones.

Con el aumento de la complejidad de sus Asesores Expertos e indicadores, se hace más necesario dominar los conceptos implicados en el desarrollo de un marco (framework). Como ejemplo real, necesito desarrollar personalmente un Asesor Experto multidivisa complejo que responde a la necesidad de reforzar la base de mi proyecto desde cero.

Figura 1. Los poliedros regulares son objetos perfectos. Representan muy bien el enfoque de la implementación de aplicaciones en conceptos sólidos.

Figura 1. Los poliedros regulares son objetos perfectos. Representan muy bien el enfoque de la implementación de aplicaciones en conceptos sólidos

1. Descarga de ZigZag

Comenzamos con la descarga del indicador ZigZag de MetaQuotes, que está disponible en la biblioteca de códigos fuente, desde nuestro terminal de MetaTrader 5. Esto creará los archivos Indicators\zigzag.mq5 e Indicators\zigzag.ex5.

Figura 2. Comenzamos descargando el indicador ZigZag de MetaQuotes desde nuestro terminal de MetaTrader 5

Figura 2. Comenzamos descargando el indicador ZigZag de MetaQuotes desde nuestro terminal de MetaTrader 5

Las siguientes líneas de código corresponden a Indicators\zigzag.mq5, que contiene los parámetros de entrada del indicador, las variables globales y el controlador OnInit(). Solo he puesto esta parte, ya que el archivo entero contiene 298 líneas. Esto es simplemente para la comodidad y la comprensión del concepto general que vamos a describir a continuación.

//+------------------------------------------------------------------+
//|                                                       ZigZag.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   1
//---- plot Zigzag
#property indicator_label1  "Zigzag"
#property indicator_type1   DRAW_SECTION
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input int      ExtDepth=12;
input int      ExtDeviation=5;
input int      ExtBackstep=3;
//--- indicator buffers
double         ZigzagBuffer[];      // main buffer
double         HighMapBuffer[];     // highs
double         LowMapBuffer[];      // lows
int            level=3;             // recounting depth
double         deviation;           // deviation in points
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ZigzagBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,HighMapBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,LowMapBuffer,INDICATOR_CALCULATIONS);

//--- set short name and digits   
   PlotIndexSetString(0,PLOT_LABEL,"ZigZag("+(string)ExtDepth+","+(string)ExtDeviation+","+(string)ExtBackstep+")");
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- set empty value
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//--- to use in cycle
   deviation=ExtDeviation*_Point;
//---
   return(INIT_SUCCEEDED);
  }


2. Resumen: de lo general a lo específico (Top-Down)

Vamos a utilizar ahora el enfoque de arriba hacia abajo (top-down) para pensar en nuestro nuevo indicador ZigZag orientado a objetos que queremos integrar en la librería estándar de MQL5. Esto significa que primero debemos tener en cuenta todo el sistema y luego analizar sus partes más pequeñas. Entonces, ¿por qué no escribimos un par de Asesores Expertos de prueba para tener una visión más general? Escribamos un Asesor Experto por procedimientos junto con su versión orientada a objetos.


2.1. El indicador ZigZag estándar

Probablemente, los desarrolladores intermedios de MQL5 usarían el indicador ZigZag en sus Asesores Expertos de esta forma:

//+----------------------------------------------------------------------+
//|                                            ExpertOriginalZigZag.mq5  |
//|                   Copyright © 2013, Laplacianlab - Jordi Bassagañas  | 
//+----------------------------------------------------------------------+
//--- EA properties
#property copyright     "Copyright © 2013, Laplacianlab - Jordi Bassagañas"
#property link          "https://www.mql5.com/es/articles"
#property version       "1.00"
#property description   "This dummy Expert Advisor is just for showing how to use the original MetaQuotes' ZigZag indicator."
//--- EA inputs
input ENUM_TIMEFRAMES   EAPeriod=PERIOD_H1;
input string            CurrencyPair="EURUSD";
//--- global variables
int      zigZagHandle;
double   zigZagBuffer[];
double   zigZagHigh[];
double   zigZagLow[];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   zigZagHandle=iCustom(CurrencyPair,EAPeriod,"zigzag",12,5,3);
   ArraySetAsSeries(zigZagBuffer,true);
   ArraySetAsSeries(zigZagHigh,true);
   ArraySetAsSeries(zigZagLow,true);  
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   IndicatorRelease(zigZagHandle);
   ArrayFree(zigZagBuffer);
   ArrayFree(zigZagHigh);
   ArrayFree(zigZagLow);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   //--- refresh data   
   if(CopyBuffer(zigZagHandle,0,0,2,zigZagBuffer)<0)
   {
      Print("Can't copy ZigZag buffer 0!");
      return;
   }
   if(CopyBuffer(zigZagHandle,1,0,2,zigZagHigh)<0)
   {
      Print("Can't copy ZigZag buffer 1!");
      return;
   }
   if(CopyBuffer(zigZagHandle,2,0,2,zigZagLow)<0)
   {
      Print("Can't copy ZigZag buffer 2!");
      return;
   }
   //--- print values
   if(zigZagBuffer[0]!=0) Print("zigZagBuffer[0]: ", zigZagBuffer[0]);
   if(zigZagHigh[0]!=0) Print("zigZagHigh[0]: ", zigZagHigh[0]);
   if(zigZagLow[0]!=0) Print("zigZagLow[0]: ", zigZagLow[0]);
  }
//+------------------------------------------------------------------+


2.2. El indicador ZigZag integrado en la librería estándar

Por otra parte, los desarrolladores MQL5 avanzados querrán trabajar con el indicador ZigZag del mismo modo que ya lo hacen con los indicadores de la librería estándar, a saber:

//+----------------------------------------------------------------------+
//|                                                  ExpertOOZigZag.mq5  |
//|                   Copyright © 2013, Laplacianlab - Jordi Bassagañas  | 
//+----------------------------------------------------------------------+
#include <..\Include\Indicators\Custom\Trend.mqh>
//--- EA properties
#property copyright     "Copyright © 2013, Laplacianlab - Jordi Bassagañas"
#property link          "https://www.mql5.com/es/articles"
#property version       "1.00"
#property description   "This dummy Expert Advisor is just for showing how to use the object-oriented version of MetaQuotes' ZigZag indicator."
//--- EA inputs
input ENUM_TIMEFRAMES   EAPeriod=PERIOD_H1;
input string            CurrencyPair="EURUSD";
//--- global variables
CiZigZag *ciZigZag;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   ciZigZag=new CiZigZag;
   ciZigZag.Create(CurrencyPair,EAPeriod,12,5,3);
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   delete(ciZigZag);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {   
   //--- refresh data
   ciZigZag.Refresh();
   //--- print values
   if(ciZigZag.ZigZag(0)!=0) Print("OO ZigZag buffer: ", ciZigZag.ZigZag(0));
   if(ciZigZag.High(0)!=0) Print("OO ZigZag high: ", ciZigZag.High(0));
   if(ciZigZag.Low(0)!=0) Print("OO ZigZag low: ",ciZigZag.Low(0));
  }
//+------------------------------------------------------------------+


2.3. Conclusión

La segunda solución es mejor porque está orientada a objetos. Una vez desarrolladas las clases OO, es intuitivo observar que es mucho más fácil interactuar con la funcionalidad el indicador Zig-Zag orientado a objetos que trabajar con el indicador implementado por procedimientos. Sin embargo, vamos a recordar brevemente las ventajas de trabajar con una librería orientada a objetos:

  • La POO facilita el modelado de los problemas.
  • La POO facilita la reutilización del código, que a su vez le beneficia al coste, la fiabilidad, la flexibilidad y el mantenimiento.
  • Este paradigma permite la creación de los TAD (tipos abstractos de datos). Un TAD es una abstracción del concepto tradicional de datos que está presente en todos los lenguajes de programación.

Figura 3. Icosaedro regular. La implementación de nuestras aplicaciones en conceptos sólidos es una garantía de calidad que hace que nuestros diseños persisten en el tiempo.

Figura 3. Icosaedro regular La implementación de nuestras aplicaciones en conceptos sólidos es una garantía de calidad que hace que nuestros diseños persisten en el tiempo


3. Integración de nuestro nuevo ZigZag OO en la librería estándar de MQL5

Como mencioné en la introducción de este artículo, no estamos basando en el estilo orientado a objetos de MetaQuotes para implementar nuestro nuevo conjunto de clases destinadas a envolver el indicador ZigZag descargado antes. Esto es fácil, solo tenemos que echar un vistazo a los archivos dentro de Include\Indicators, para estudiar y comprender algunos de los conceptos que hay detrás de la librería estándar de MQL5. Cuando vea lo que hay dentro del archivo Trend.mqh de MetaQuotes, se dará cuenta pronto de que está lleno de clases representando algunos indicadores técnicos: ADX, bandas de Bollinger, SAR, Promedios móviles, etc. Todas estas clases están heredadas de CIndicator. Así que, vamos a implementar esta estructura. Por cierto, otra alternativa a la implementación de este ejercicio hubiera sido una extensión del nuevo indicador OO a partir de la clase CiCustom de MQL5.

Comenzemos con la creación de la carpeta Include\Indicators\Custom y, a continuación, crearemos el nuevo archivo Include\Indicators\Custom\Trend.mqh para que podamos escribir en él nuestros propios indicadores técnicos, tal y como lo hace MetaQuotes en su Include\Indicators\Trend.mqh. Este es nuestro archivo de extensión Include\Indicators\Custom\Trend.mqh ya implementado. A continuación, voy a comentar algunos aspectos técnicos necesarios para la escritura del código.

//+------------------------------------------------------------------+
//|                              Include\Indicators\Custom\Trend.mqh |
//|                  Copyright 2013, Laplacianlab - Jordi Bassagañas |
//|                     https://www.mql5.com/en/users/laplacianlab |
//+------------------------------------------------------------------+
#include <..\Include\Indicators\Indicator.mqh>
//+------------------------------------------------------------------+
//| Class CiZigZag.                                                  |
//| Purpose: Class of the "ZigZag" indicator.                        |
//|          Derives from class CIndicator.                          |
//+------------------------------------------------------------------+
class CiZigZag : public CIndicator
  {
protected:
   int               m_depth;
   int               m_deviation;
   int               m_backstep;

public:
                     CiZigZag(void);
                    ~CiZigZag(void);
   //--- methods of access to protected data
   int               Depth(void)          const { return(m_depth);      }
   int               Deviation(void)      const { return(m_deviation);  }
   int               Backstep(void)       const { return(m_backstep);   }
   //--- method of creation
   bool              Create(const string symbol,const ENUM_TIMEFRAMES period,
                            const int depth,const int deviation_create,const int backstep);
   //--- methods of access to indicator data
   double            ZigZag(const int index) const;
   double            High(const int index) const;
   double            Low(const int index) const;
   //--- method of identifying
   virtual int       Type(void) const { return(IND_CUSTOM); }

protected:
   //--- methods of tuning
   virtual bool      Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam &params[]);
   bool              Initialize(const string symbol,const ENUM_TIMEFRAMES period,
                                const int depth,const int deviation_init,const int backstep);
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CiZigZag::CiZigZag(void) : m_depth(-1),
                         m_deviation(-1),
                         m_backstep(-1)
  {
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CiZigZag::~CiZigZag(void)
  {
  }
//+------------------------------------------------------------------+
//| Create indicator "Zig Zag"                                       |
//+------------------------------------------------------------------+
bool CiZigZag::Create(const string symbol,const ENUM_TIMEFRAMES period,
                      const int depth,const int deviation_create,const int backstep)
  {
//--- check history
   if(!SetSymbolPeriod(symbol,period))
      return(false);
//--- create
   m_handle=iCustom(symbol,period,"zigzag",depth,deviation_create,backstep);
//--- check result
   if(m_handle==INVALID_HANDLE)
      return(false);
//--- indicator successfully created
   if(!Initialize(symbol,period,depth,deviation_create,backstep))
     {
      //--- initialization failed
      IndicatorRelease(m_handle);
      m_handle=INVALID_HANDLE;
      return(false);
     }
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Initialize the indicator with universal parameters               |
//+------------------------------------------------------------------+
bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam &params[])
  {
   return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value,(int)params[2].integer_value));
  }
//+------------------------------------------------------------------+
//| Initialize indicator with the special parameters                 |
//+------------------------------------------------------------------+
bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period,
                        const int depth,const int deviation_init,const int backstep)
  {
   if(CreateBuffers(symbol,period,3))
     {
      //--- string of status of drawing
      m_name  ="ZigZag";
      m_status="("+symbol+","+PeriodDescription()+","+
               IntegerToString(depth)+","+IntegerToString(deviation_init)+","+
               IntegerToString(backstep)+") H="+IntegerToString(m_handle);
      //--- save settings
      m_depth=depth;
      m_deviation=deviation_init;
      m_backstep=backstep;       
      //--- create buffers
      ((CIndicatorBuffer*)At(0)).Name("ZIGZAG");
      ((CIndicatorBuffer*)At(1)).Name("HIGH");
      ((CIndicatorBuffer*)At(2)).Name("LOW");
      //--- ok
      return(true);
     }
//--- error
   return(false);
  }
//+------------------------------------------------------------------+
//| Access to ZigZag buffer of "Zig Zag"                             |
//+------------------------------------------------------------------+
double CiZigZag::ZigZag(const int index) const
  {
   CIndicatorBuffer *buffer=At(0);
//--- check
   if(buffer==NULL)
      return(EMPTY_VALUE);
//---
   return(buffer.At(index));
  }
//+------------------------------------------------------------------+
//| Access to High buffer of "Zig Zag"                               |
//+------------------------------------------------------------------+
double CiZigZag::High(const int index) const
  {
   CIndicatorBuffer *buffer=At(1);
//--- check
   if(buffer==NULL)
      return(EMPTY_VALUE);
//---
   return(buffer.At(index));
  }
//+------------------------------------------------------------------+
//| Access to Low buffer of "Zig Zag"                                |
//+------------------------------------------------------------------+
double CiZigZag::Low(const int index) const
  {
   CIndicatorBuffer *buffer=At(2);
//--- check
   if(buffer==NULL)
      return(EMPTY_VALUE);
//---
   return(buffer.At(index));
  }
//+------------------------------------------------------------------+


3.1. Encapsulamiento orientado a objetos

El encapsulamiento OO es una buena práctica de programación que implica que la modificación de los datos de los objetos solo se puede hacer mediante las operaciones definidas en los mismos. Todas las clases definidas en Trend.mqh de MetaQuotes implementan este concepto, de modo que estamos haciendo lo mismo.

Por otra parte, hay unas propiedades protegidas de CiZigZag:

protected:
   int               m_depth;
   int               m_deviation;
   int               m_backstep;

Por consiguiente, hay una interfaz pública de CiZigZag para acceder a las propiedades protegidos definidas antes, desde el exterior de un determinado objeto de tipo CiZigZag:

public:
   //--- methods of access to protected data
   int               Depth(void)          const { return(m_depth);      }
   int               Deviation(void)      const { return(m_deviation);  }
   int               Backstep(void)       const { return(m_backstep);   }

Se trata de una medida de seguridad para aislar a los objetos. Este encapsulamiento proporciona una protección frente a cambios arbitrarios realizados por alguien o algo, sin derecho de acceso a los datos de los objetos.


3.2. Accediendo a los datos de ZigZag

Como pudimos ver en la primera parte de este artículo, zigzag.mq5 crea estos buffers:

//--- indicator buffers mapping
   SetIndexBuffer(0,ZigzagBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,HighMapBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,LowMapBuffer,INDICATOR_CALCULATIONS);

Mediante el encapsulamiento orientado a objetos, los métodos ZigZag(const int index), High(const int index) y Low(const int index) de CiZigZag devuelven los buffers de indicador que fueron creados anteriormente en el método de inicialización. Es importante señalar que el encapsulador orientado a objetos CIndicatorBuffer está definido en la clase Include\Indicators\Indicator.mqh de MQL5. CIndicatorBuffer es el núcleo de estos tres métodos. ¡Ya estamos inmersos en al API de MQL5!

El siguiente ejemplo es el código para acceder al buffer del precio máximo de CiZigZag:

//+------------------------------------------------------------------+
//| Access to High buffer of "Zig Zag"                               |
//+------------------------------------------------------------------+
double CiZigZag::High(const int index) const
  {
   CIndicatorBuffer *buffer=At(1);
//--- check
   if(buffer==NULL)
      return(EMPTY_VALUE);
//---
   return(buffer.At(index));
  }


3.3.
Polimorfismo, sobrecarga de métodos y funciones virtuales

En el apartado anterior, hemos comentado brevemente el tema del encapsulamiento, que es una de las características más importantes de la programación orientada a objetos. Las clases que contiene Include\Indicators\Indicator.mqh y el archivo Include\Indicators\Custom\Trend.mqh tratan con otros dos aspectos del paradigma de la POO, el polimorfismo y la sobrecarga de los métodos.

El polimorfismo proporciona el acceso a varios métodos a través de la misma interfaz. Por lo tanto, un identificador concreto puede tomar varias formas en función del contexto en el que se encuentra. El polimorfismo requiere los mecanismos de herencia para su implementación. Por otra parte, la sobrecarga de los métodos es otra característica de la POO que permite crear varios métodos compartiendo el mismo nombre, pero con distintas declaraciones de parámetros.

Esta es una descripción muy corta. No hay bastante espacio para describir estos temas en este artículo, así que puede considerarlos como ejercicios adicionales. Consulte las secciones Polimorfismo y Sobrecarga. En cualquier caso, vemos que la librería estándar implementa todas las características de la POO, por consiguiente, mejor las conocemos, mejor podemos ampliar nuestra API para adaptarla a nuestras necesidades.

Con todo lo dicho, sólo hay una cosa más que señalar. MQL5 implementa el polimorfismo mediante un mecanismo llamado Funciones virtuales. Una vez más, lea la sección Funciones virtuales de MQL5 para comprender su funcionamiento.

Es por ello que escribimos el código del método de inicialización de CiZigZag de este modo:

//+------------------------------------------------------------------+
//| Initialize the indicator with universal parameters               |
//+------------------------------------------------------------------+
bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam &params[])
  {
   return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value,(int)params[2].integer_value));
  }
//+------------------------------------------------------------------+
//| Initialize indicator with the special parameters                 |
//+------------------------------------------------------------------+
bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period,
                        const int depth,const int deviation_init,const int backstep)
  {
   if(CreateBuffers(symbol,period,3))
     {
      //--- string of status of drawing
      m_name  ="ZigZag";
      m_status="("+symbol+","+PeriodDescription()+","+
               IntegerToString(depth)+","+IntegerToString(deviation_init)+","+
               IntegerToString(backstep)+") H="+IntegerToString(m_handle);
      //--- save settings
      m_depth=depth;
      m_deviation=deviation_init;
      m_backstep=backstep;       
      //--- create buffers
      ((CIndicatorBuffer*)At(0)).Name("ZIGZAG");
      ((CIndicatorBuffer*)At(1)).Name("HIGH");
      ((CIndicatorBuffer*)At(2)).Name("LOW");
      //--- ok
      return(true);
     }
//--- error
   return(false);
  }

4. Prueba del nuevo ZigZag OO, ya disponible en la librería estándar

Por supuesto, antes de utilizar las extensiones que ha desarrollado mediante la POO, primero tiene que asegurarse de que funcionan según lo planeado. Le recomiendo realizar una serie de pruebas completas de sus nuevos componentes personalizados. Sin embargo, para facilitar la comprensión, vamos a ejecutar ahora una prueba simple con los tres métodos principales de CiZigZag, es decir, ZigZag(const int index), High(const int index) y Low(const int index).

Solo vamos a representar los valores calculados mediante estos tres métodos con cada tick del Asesor Experto y luego comparar la salida que ha generado ExpertOriginalZigZag.ex5, el Asesor Experto procedimental de prueba, con la salida que ha generado ExpertOOZigZag.ex5, el Asesor Experto orientado a objetos de prueba. Si los resultados coinciden, podemos concluir que la nueva extensión está bien, y podemos dar por bueno el nuevo indicador ZigZag OO integrado en la API de MQL5.

Figura 4. Estamos comparando la salida obtenida mediante ExpertOriginalZigZag.ex5 con la salida obtenida mediante ExpertOOZigZag.ex5

Figura 4. Estamos comparando la salida obtenida mediante ExpertOriginalZigZag.ex5 con la salida obtenida mediante ExpertOOZigZag.ex5

Así que ejecutamos tanto ExpertOriginalZigZag.ex5 como ExpertOOZigZag.ex5, los dos Asesores Expertos descritos al principio de este artículo, en el probador de estrategias con el siguiente conjunto de parámetros:

  • Símbolo: EURUSD, H1
  • Fecha: Período personalizado, entre 01.08.2013 y 15.08.2013
  • Ejecución: Normal, 1 Minuto OHLC
  • Depósito: 10 000 USD, 1:100
  • Optimización: Ninguna

Puesto que ambos robots muestran los mismos resultados, concluimos que nuestra clase CiZigZag está correctamente implementada, de modo que podemos utilizarla en nuestros desarrollos a partir de ahora.

Registro generado por ExpertOriginalZigZag.ex5:

DE      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:50:40   zigZagBuffer[0]: 1.32657
ML      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:50:40   zigZagLow[0]: 1.32657
FL      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:50:59   zigZagBuffer[0]: 1.32657
GE      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:50:59   zigZagLow[0]: 1.32657
KS      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:51:00   zigZagBuffer[0]: 1.32657
FR      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:51:00   zigZagLow[0]: 1.32657
GK      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:51:20   zigZagBuffer[0]: 1.32653
RJ      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:51:20   zigZagLow[0]: 1.32653
OR      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:51:40   zigZagBuffer[0]: 1.32653
FS      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:51:40   zigZagLow[0]: 1.32653
QJ      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:51:59   zigZagBuffer[0]: 1.32653
PH      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:51:59   zigZagLow[0]: 1.32653
JQ      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:52:00   zigZagBuffer[0]: 1.32653
KP      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:52:00   zigZagLow[0]: 1.32653
RH      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:52:20   zigZagBuffer[0]: 1.32653
GI      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:52:20   zigZagLow[0]: 1.32653
GP      0       18:45:39        ExpertOriginalZigZag (EURUSD,H1)        2013.08.01 08:52:40   zigZagBuffer[0]: 1.32614
// More data here!..

Registro generado por ExpertOOZigZag.ex5:

RP      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:50:40   OO ZigZag buffer(0): 1.32657
HQ      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:50:40   OO ZigZag low(0): 1.32657
DI      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:50:59   OO ZigZag buffer(0): 1.32657
RH      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:50:59   OO ZigZag low(0): 1.32657
QR      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:51:00   OO ZigZag buffer(0): 1.32657
GS      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:51:00   OO ZigZag low(0): 1.32657
IK      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:51:20   OO ZigZag buffer(0): 1.32653
GJ      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:51:20   OO ZigZag low(0): 1.32653
EL      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:51:40   OO ZigZag buffer(0): 1.32653
OD      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:51:40   OO ZigZag low(0): 1.32653
OE      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:51:59   OO ZigZag buffer(0): 1.32653
IO      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:51:59   OO ZigZag low(0): 1.32653
DN      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:52:00   OO ZigZag buffer(0): 1.32653
RF      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:52:00   OO ZigZag low(0): 1.32653
PP      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:52:20   OO ZigZag buffer(0): 1.32653
RQ      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:52:20   OO ZigZag low(0): 1.32653
MI      0       18:48:02        ExpertOOZigZag (EURUSD,H1)      2013.08.01 08:52:40   OO ZigZag buffer(0): 1.32614
// More data here!..

Conclusión

La librería estándar de MQL5 le facilita la vida como desarrollador. No obstante, no se pueden implementar todas las necesidades de todos los desarrolladores alrededor del mundo, por lo que tarde o temprano, tendrá que crear su material personalizado. Con el aumento de la complejidad de sus Asesores Expertos e indicadores, se hace más necesario dominar los conceptos implicados en el desarrollo de un marco de trabajo (framework). La ampliación de la librería estándar de MQL5 es una garantía de calidad para el éxito de sus aplicaciones.

En primer lugar, nos hemos aprovechado de la reutilización del código, descargando el indicador ZigZag desde la biblioteca de códigos fuente. Una vez disponible en nuestro terminal de MetaTrader 5, hemos utilizado el enfoque de arriba hacia abajo (top-down) para empezar a pensar en nuestro nuevo indicador ZigZag orientado a objetos. Hemos obtenido una visión general de todo el sistema y luego hemos seguido con al análisis. En la primera etapa del desarrollo, hemos comparado un Asesor Experto de prueba mediante el indicador ZigZag procedimental con su equivalente orientado a objetos.

Hemos envuelto el indicador ZigZag en una clase orientada a objetos que fue diseñada en base a la filosofía de diseño de MetaQuotes, la misma que se ha utilizado para la implementación de la librería estándar. Y finalmente, hemos realizado algunas pruebas sencillas, concluyendo que nuestro nuevo envoltorio CiZigZag, ya integrado en la API de MQL5, se ha implementado con éxito.

Traducción del inglés realizada por MetaQuotes Software Corp.
Artículo original: https://www.mql5.com/en/articles/741

Archivos adjuntos |
expertoozigzag.mq5 (2.03 KB)
trend.mqh (6.34 KB)
zigzag.mq5 (9.34 KB)
Indicadores técnicos y filtros digitales Indicadores técnicos y filtros digitales

En este artículo, se tratan los indicadores técnicos como si fueran filtros digitales. Se explican los principios de funcionamiento y las características básicas de los filtros digitales. Además, se van a tratar algunos métodos prácticos para obtener la respuesta al impulso (kernel) del filtro en el terminal de MetaTrader 5 y su integración con un analizador de espectro, que ya existe, descrito en el artículo "Construyendo un analizador de espectro". Como ejemplos, se usan las características del impulso y el espectro de los filtros digitales típicos.

Aumente la eficiencia de sus sistemas lineales de trading Aumente la eficiencia de sus sistemas lineales de trading

En el artículo de hoy se muestra a los programadores intermedios en MQL5 cómo pueden sacar mayor rendimiento a sus sistemas lineales de trading (lote fijo) mediante una simple implementación de la conocida técnica de potenciación. Se llama así, porque el crecimiento de la curva de patrimonio resultante es geométrico o exponencial, con forma de parábola. En particular, vamos a implementar una variante práctica de MQL5, se trata del método de fracción fija para determinar el tamaño de una posición, desarrollado por Ralph Vince.

Guía práctica de MQL5: Guardar los resultados de la optimización de un Asesor Experto en base a unos criterios especificados Guía práctica de MQL5: Guardar los resultados de la optimización de un Asesor Experto en base a unos criterios especificados

Continuamos con la serie de artículos sobre la programación en MQL5. Esta vez, veremos cómo obtener los resultados de cada pasada de optimización durante el proceso de optimización de los parámetros del Asesor Experto. Se hará la implementación de modo que si se cumplen las condiciones especificadas en los parámetros externos, se escriben los valores correspondientes a la pasada de optimización en un archivo. Además de los valores de las pruebas, guardaremos también los parámetros que han llevado a estos resultados.

Guía práctica de MQL5: Notificaciones sonoras para los eventos de trading de MetaTrader 5 Guía práctica de MQL5: Notificaciones sonoras para los eventos de trading de MetaTrader 5

En este artículo vamos a tratar el tema de la inclusión de archivos de sonido en el archivo del Asesor Experto y con ello añadir notificaciones sonoras a los eventos de trading. El hecho de que se incluyan los archivos significa que los archivos de sonido van a estar ubicados dentro del Asesor Experto. De modo que al proporcionar una versión compilada del Asesor Experto (*.ex5) a otro usuario, no tendrá que proporcionarle los archivos de sonido y explicarle dónde hay que guardarlos.