Ampliación de la librería estándar de MQL5 y la reutilización del código
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
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
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. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2009, MetaQuotes Software Corp." #property link "https://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
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 ¶ms[]); 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 ¶ms[]) { 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 ¶ms[]) { 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
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 Ltd.
Artículo original: https://www.mql5.com/en/articles/741
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso