![Trabajando con las series temporales en la biblioteca DoEasy (Parte 54): Clases herederas del indicador abstracto básico](https://c.mql5.com/2/49/doeasy_054_600x314.jpg)
Trabajando con las series temporales en la biblioteca DoEasy (Parte 54): Clases herederas del indicador abstracto básico
Contenido
- Concepto
- Mejorando las clases de la biblioteca
- Clases de objetos de indicador
- Colección de objetos de indicador
- Prueba
- ¿Qué es lo próximo?
Concepto
En el artículo anterior, consideramos la creación de un objeto-indicador abstracto básico. Ahora vamos a crear sus objetos herederos que contienen la información más detallada sobre un determinado objeto de indicador creado. Colocaremos todos estos objetos en la colección de indicadores de la cual se podrá obtener los datos y propiedades de cada indicador creado.
El concepto de los objetos herederos corresponde por completo al concepto de la construcción de objetos en la biblioteca y sus interacciones. Pues, la colección de indicadores nos permitirá añadir rápidamente la funcionalidad de eventos a todos los objetos de indicador en el futuro, lo cual nos permitirá definir fácilmente los eventos investigados de los indicadores y usar estos eventos en nuestros programas.
Mejorando las clases de la biblioteca
Vamos a comenzar como siempre, añadiendo los mensajes de texto necesarios de la biblioteca.
En el archivo \MQL5\Include\DoEasy\Data.mqh escribimos los índices de nuevos mensajes:
//--- CIndicatorDE MSG_LIB_TEXT_IND_TEXT_STATUS, // Indicator status MSG_LIB_TEXT_IND_TEXT_STATUS_STANDART, // Standard indicator MSG_LIB_TEXT_IND_TEXT_STATUS_CUSTOM, // Custom indicator MSG_LIB_TEXT_IND_TEXT_TYPE, // Indicator type MSG_LIB_TEXT_IND_TEXT_TIMEFRAME, // Indicator timeframe MSG_LIB_TEXT_IND_TEXT_HANDLE, // Indicator handle MSG_LIB_TEXT_IND_TEXT_GROUP, // Indicator group MSG_LIB_TEXT_IND_TEXT_GROUP_TREND, // Trend indicator MSG_LIB_TEXT_IND_TEXT_GROUP_OSCILLATOR, // Oscillator MSG_LIB_TEXT_IND_TEXT_GROUP_VOLUMES, // Volumes MSG_LIB_TEXT_IND_TEXT_GROUP_ARROWS, // Arrow indicator MSG_LIB_TEXT_IND_TEXT_EMPTY_VALUE, // Empty value for plotting where nothing will be drawn MSG_LIB_TEXT_IND_TEXT_SYMBOL, // Indicator symbol MSG_LIB_TEXT_IND_TEXT_NAME, // Indicator name MSG_LIB_TEXT_IND_TEXT_SHORTNAME, // Indicator short name //--- CIndicatorsCollection MSG_LIB_SYS_FAILED_ADD_IND_TO_LIST, // Error. Failed to add indicator object to list }; //+------------------------------------------------------------------+
y después añadimos los nuevos mensajes que se correspondan con los índices nuevamente creados:
{"Статус индикатора","Indicator status"}, {"Стандартный индикатор","Standard indicator"}, {"Пользовательский индикатор","Custom indicator"}, {"Тип индикатора","Indicator type"}, {"Таймфрейм индикатора","Indicator timeframe"}, {"Хэндл индикатора","Indicator handle"}, {"Группа индикатора","Indicator group"}, {"Трендовый индикатор","Trend indicator"}, {"Осциллятор","Solid lineOscillator"}, {"Объёмы","Volumes"}, {"Стрелочный индикатор","Arrow indicator"}, {"Пустое значение для построения, для которого нет отрисовки","Empty value for plotting, for which there is no drawing"}, {"Символ индикатора","Indicator symbol"}, {"Имя индикатора","Indicator name"}, {"Короткое имя индикатора","Indicator shortname"}, {"Ошибка. Не удалось добавить объект-индикатор в список","Error. Failed to add indicator object to list"}, }; //+---------------------------------------------------------------------+
Al crear la clase del objeto del indicador abstracto en el artículo anterior, no añadimos una de las propiedades enteras (integer) del objeto: el tipo del indicador estándar. Este tipo va a corresponder a los tipos de la enumeración ENUM_INDICATOR, y lo necesitaremos para buscar un indicador concreto.
Si queremos encontrar todos los indicadores MACD almacenados en la colección, en primer lugar, tenemos que obtener la lista de todos los indicadores MACD que se encuentran en la colección. Para eso, necesitamos filtrar la lista completa de la colección de indicadores según el tipo IND_MACD, y luego hacer la selección según otras propiedades buscadas en la lista obtenida que va a contener sólo IND_MACD.
Añadimos la nueva propiedad del objeto de indicador al archivo \MQL5\Include\DoEasy\Defines.mqh:
//+------------------------------------------------------------------+ //| Indicator integer properties | //+------------------------------------------------------------------+ enum ENUM_INDICATOR_PROP_INTEGER { INDICATOR_PROP_STATUS = 0, // Indicator status (from enumeration ENUM_INDICATOR_STATUS) INDICATOR_PROP_TYPE, // Indicator type (from enumeration ENUM_INDICATOR) INDICATOR_PROP_TIMEFRAME, // Indicator timeframe INDICATOR_PROP_HANDLE, // Indicator handle INDICATOR_PROP_GROUP, // Indicator group }; #define INDICATOR_PROP_INTEGER_TOTAL (5) // Total number of indicator integer properties #define INDICATOR_PROP_INTEGER_SKIP (0) // Number of indicator properties not used in sorting //+------------------------------------------------------------------+
y aumentamos el número de propiedades enteras de 4 a 5.
Al añadir la nueva propiedad al objeto, tenemos que definir la posibilidad de la búsqueda y ordenación de objetos según esta propiedad.
Añadimos un criterio de ordenación nuevo a la enumeración:
//+------------------------------------------------------------------+ //| Possible indicator sorting criteria | //+------------------------------------------------------------------+ #define FIRST_INDICATOR_DBL_PROP (INDICATOR_PROP_INTEGER_TOTAL-INDICATOR_PROP_INTEGER_SKIP) #define FIRST_INDICATOR_STR_PROP (INDICATOR_PROP_INTEGER_TOTAL-INDICATOR_PROP_INTEGER_SKIP+INDICATOR_PROP_DOUBLE_TOTAL-INDICATOR_PROP_DOUBLE_SKIP) enum ENUM_SORT_INDICATOR_MODE { //--- Sort by integer properties SORT_BY_INDICATOR_INDEX_STATUS = 0, // Sort by indicator status SORT_BY_INDICATOR_TYPE, // Sort by indicator type SORT_BY_INDICATOR_TIMEFRAME, // Sort by indicator timeframe SORT_BY_INDICATOR_HANDLE, // Sort by indicator handle SORT_BY_INDICATOR_GROUP, // Sort by indicator group //--- Sort by real properties SORT_BY_INDICATOR_EMPTY_VALUE = FIRST_INDICATOR_DBL_PROP,// Sort by the empty value for plotting where nothing will be drawn //--- Sort by string properties SORT_BY_INDICATOR_SYMBOL = FIRST_INDICATOR_STR_PROP, // Sort by indicator symbol SORT_BY_INDICATOR_NAME, // Sort by indicator name SORT_BY_INDICATOR_SHORTNAME, // Sort by indicator short name }; //+------------------------------------------------------------------+
Vamos a mejorar la clase del objeto del indicador abstracto en el archivo \MQL5\Include\DoEasy\Objects\Indicators\IndicatorDE.mqh.
Trasladaremos la matriz de estructuras de los parámetros del indicador de la sección privada de la clase a la protegida (ahora esta matriz estará disponible para las clases heredadas), declararemos en la sección privada una variable para almacenar la descripción del tipo del indicador:
//+------------------------------------------------------------------+ //| Abstract indicator class | //+------------------------------------------------------------------+ class CIndicatorDE : public CBaseObj { protected: MqlParam m_mql_param[]; // Array of indicator parameters private: long m_long_prop[INDICATOR_PROP_INTEGER_TOTAL]; // Integer properties double m_double_prop[INDICATOR_PROP_DOUBLE_TOTAL]; // Real properties string m_string_prop[INDICATOR_PROP_STRING_TOTAL]; // String properties string m_ind_type; // Indicator type description
Añadimos dos métodos a la sección pública de la clase: para devolver el tipo del indicador y para devolver la descripción del tipo del indicador:
public: //--- Default constructor CIndicatorDE(void){;} //--- Destructor ~CIndicatorDE(void); //--- Set buffer's (1) integer, (2) real and (3) string properties void SetProperty(ENUM_INDICATOR_PROP_INTEGER property,long value) { this.m_long_prop[property]=value; } void SetProperty(ENUM_INDICATOR_PROP_DOUBLE property,double value) { this.m_double_prop[this.IndexProp(property)]=value; } void SetProperty(ENUM_INDICATOR_PROP_STRING property,string value) { this.m_string_prop[this.IndexProp(property)]=value; } //--- Return (1) integer, (2) real and (3) string buffer properties from the properties array long GetProperty(ENUM_INDICATOR_PROP_INTEGER property) const { return this.m_long_prop[property]; } double GetProperty(ENUM_INDICATOR_PROP_DOUBLE property) const { return this.m_double_prop[this.IndexProp(property)]; } string GetProperty(ENUM_INDICATOR_PROP_STRING property) const { return this.m_string_prop[this.IndexProp(property)]; } //--- Get description of buffer's (1) integer, (2) real and (3) string properties string GetPropertyDescription(ENUM_INDICATOR_PROP_INTEGER property); string GetPropertyDescription(ENUM_INDICATOR_PROP_DOUBLE property); string GetPropertyDescription(ENUM_INDICATOR_PROP_STRING property); //--- Return the flag of the buffer supporting the property virtual bool SupportProperty(ENUM_INDICATOR_PROP_INTEGER property) { return true; } virtual bool SupportProperty(ENUM_INDICATOR_PROP_DOUBLE property) { return true; } virtual bool SupportProperty(ENUM_INDICATOR_PROP_STRING property) { return true; } //--- Compare CIndicatorDE objects by all possible properties (for sorting the lists by a specified indicator object property) virtual int Compare(const CObject *node,const int mode=0) const; //--- Compare CIndicatorDE objects by all properties (to search for equal indicator objects) bool IsEqual(CIndicatorDE* compared_obj) const; //--- Set indicator’s (1) group, (2) empty value of buffers, (3) name, (4) short name void SetGroup(const ENUM_INDICATOR_GROUP group) { this.SetProperty(INDICATOR_PROP_GROUP,group); } void SetEmptyValue(const double value) { this.SetProperty(INDICATOR_PROP_EMPTY_VALUE,value); } void SetName(const string name) { this.SetProperty(INDICATOR_PROP_NAME,name); } void SetShortName(const string shortname) { this.SetProperty(INDICATOR_PROP_SHORTNAME,shortname); } //--- Return indicator’s (1) status, (2) group, (3) timeframe, (4) handle, (5) empty value of buffers, (6) name, (7) short name, (8) symbol, (9) type ENUM_INDICATOR_STATUS Status(void) const { return (ENUM_INDICATOR_STATUS)this.GetProperty(INDICATOR_PROP_STATUS);} ENUM_INDICATOR_GROUP Group(void) const { return (ENUM_INDICATOR_GROUP)this.GetProperty(INDICATOR_PROP_GROUP); } ENUM_TIMEFRAMES Timeframe(void) const { return (ENUM_TIMEFRAMES)this.GetProperty(INDICATOR_PROP_TIMEFRAME); } ENUM_INDICATOR TypeIndicator(void) const { return (ENUM_INDICATOR)this.GetProperty(INDICATOR_PROP_TYPE); } int Handle(void) const { return (int)this.GetProperty(INDICATOR_PROP_HANDLE); } double EmptyValue(void) const { return this.GetProperty(INDICATOR_PROP_EMPTY_VALUE); } string Name(void) const { return this.GetProperty(INDICATOR_PROP_NAME); } string ShortName(void) const { return this.GetProperty(INDICATOR_PROP_SHORTNAME); } string Symbol(void) const { return this.GetProperty(INDICATOR_PROP_SYMBOL); } //--- Return description of indicator’s (1) type, (2) status, (3) group, (4) timeframe, (5) empty value string GetTypeDescription(void) const { return m_ind_type; } string GetStatusDescription(void) const; string GetGroupDescription(void) const; string GetTimeframeDescription(void) const; string GetEmptyValueDescription(void) const; //--- Display the description of indicator object properties in the journal (full_prop=true - all properties, false - supported ones only) void Print(const bool full_prop=false); //--- Display a short description of indicator object in the journal (implementation in the descendants) virtual void PrintShort(void) {;} }; //+------------------------------------------------------------------+
En el constructor paramétrico cerrado, recuperaremos la subcadena del parámetro de entrada del tipo del indicador para dejar sólo el nombre del indicador (por ejemplo, de IND_MACD se queda sólo MACD, lo cual representará la descripción del tipo del indicador), y el propio tipo del indicador lo añadiremos a las propiedades del objeto:
//+------------------------------------------------------------------+ //| Closed parametric constructor | //+------------------------------------------------------------------+ CIndicatorDE::CIndicatorDE(ENUM_INDICATOR ind_type, string symbol, ENUM_TIMEFRAMES timeframe, ENUM_INDICATOR_STATUS status, ENUM_INDICATOR_GROUP group, string name, string shortname, MqlParam &mql_params[]) { //--- Set collection ID to the object this.m_type=COLLECTION_INDICATORS_ID; //--- Write description of indicator type this.m_ind_type=::StringSubstr(::EnumToString(ind_type),4); //--- If parameter array value passed to constructor is more than zero //--- fill in the array of object parameters with data from the array passed to constructor int count=::ArrayResize(m_mql_param,::ArraySize(mql_params)); for(int i=0;i<count;i++) { this.m_mql_param[i].type=mql_params[i].type; this.m_mql_param[i].double_value=mql_params[i].double_value; this.m_mql_param[i].integer_value=mql_params[i].integer_value; this.m_mql_param[i].string_value=mql_params[i].string_value; } //--- Create indicator handle int handle=::IndicatorCreate(symbol,timeframe,ind_type,count,this.m_mql_param); //--- Save integer properties this.m_long_prop[INDICATOR_PROP_STATUS] = status; this.m_long_prop[INDICATOR_PROP_TYPE] = ind_type; this.m_long_prop[INDICATOR_PROP_GROUP] = group; this.m_long_prop[INDICATOR_PROP_TIMEFRAME] = timeframe; this.m_long_prop[INDICATOR_PROP_HANDLE] = handle; //--- Save real properties this.m_double_prop[this.IndexProp(INDICATOR_PROP_EMPTY_VALUE)]=EMPTY_VALUE; //--- Save string properties this.m_string_prop[this.IndexProp(INDICATOR_PROP_SYMBOL)] = (symbol==NULL || symbol=="" ? ::Symbol() : symbol); this.m_string_prop[this.IndexProp(INDICATOR_PROP_NAME)] = name; this.m_string_prop[this.IndexProp(INDICATOR_PROP_SHORTNAME)]= shortname; } //+------------------------------------------------------------------+
Añadimos el bloque del código para devolver la descripción del tipo del indicador al método que devuelve la descripción de una propiedad entera del indicador:
//+------------------------------------------------------------------+ //| Return description of indicator's integer property | //+------------------------------------------------------------------+ string CIndicatorDE::GetPropertyDescription(ENUM_INDICATOR_PROP_INTEGER property) { return ( property==INDICATOR_PROP_STATUS ? CMessage::Text(MSG_LIB_TEXT_IND_TEXT_STATUS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetStatusDescription() ) : property==INDICATOR_PROP_TYPE ? CMessage::Text(MSG_LIB_TEXT_IND_TEXT_TYPE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetTypeDescription() ) : property==INDICATOR_PROP_GROUP ? CMessage::Text(MSG_LIB_TEXT_IND_TEXT_GROUP)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetGroupDescription() ) : property==INDICATOR_PROP_TIMEFRAME ? CMessage::Text(MSG_LIB_TEXT_IND_TEXT_TIMEFRAME)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetTimeframeDescription() ) : property==INDICATOR_PROP_HANDLE ? CMessage::Text(MSG_LIB_TEXT_IND_TEXT_HANDLE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : "" ); } //+------------------------------------------------------------------+
Clase de objetos de indicador
Ahora, procedemos a desarrollar los objetos herederos del indicador abstracto básico que van a detallar toda la información sobre el objeto de indicador a crear. Precisamente estas clases serán usadas para crear indicadores de tipos diferentes y obtener datos sobre ellos.
En el directorio \MQL5\Include\DoEasy\Objects\Indicators\ creamos la carpeta nueva Standart, y dentro de ella, el archivo nuevo IndAC.mqh de la clase CIndAC del indicador estándar Accelerator Oscillator, heredada de la clase base del indicador abstracto cuyo archivo está conectado al listado de esta clase.
Dado que la clase no será grande, vamos a analizar su listado completo:
//+------------------------------------------------------------------+ //| IndAC.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/es/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/es/users/artmedia70" //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "..\\IndicatorDE.mqh" //+------------------------------------------------------------------+ //| Accelerator Oscillator standard indicator | //+------------------------------------------------------------------+ class CIndAC : public CIndicatorDE { private: public: //--- Constructor CIndAC(const string symbol,const ENUM_TIMEFRAMES timeframe,MqlParam &mql_param[]) : CIndicatorDE(IND_AC,symbol,timeframe, INDICATOR_STATUS_STANDART, INDICATOR_GROUP_OSCILLATOR, "Accelerator Oscillator", "AC("+symbol+","+TimeframeDescription(timeframe)+")",mql_param) {} //--- Supported indicator properties (1) real, (2) integer virtual bool SupportProperty(ENUM_INDICATOR_PROP_DOUBLE property); virtual bool SupportProperty(ENUM_INDICATOR_PROP_INTEGER property); //--- Display a short description of indicator object in the journal virtual void PrintShort(void); }; //+------------------------------------------------------------------+ //| Return 'true' if the indicator supports the passed | //| integer property, otherwise return 'false' | //+------------------------------------------------------------------+ bool CIndAC::SupportProperty(ENUM_INDICATOR_PROP_INTEGER property) { return true; } //+------------------------------------------------------------------+ //| Return 'true' if the indicator supports the passed | //| real property, otherwise return 'false' | //+------------------------------------------------------------------+ bool CIndAC::SupportProperty(ENUM_INDICATOR_PROP_DOUBLE property) { return true; } //+------------------------------------------------------------------+ //| Display a short description of indicator object in the journal | //+------------------------------------------------------------------+ void CIndAC::PrintShort(void) { ::Print(GetStatusDescription()," ",this.Name()," ",this.Symbol()," ",TimeframeDescription(this.Timeframe())); } //+------------------------------------------------------------------+
En total, tendremos que hacer 38 clases —de acuerdo con el número de indicadores estándar (todavía no hacemos el indicador personalizado porque su implementación será algo diferente).
Todas estas clases van a tener los métodos iguales, diferenciándose sólo en sus parámetros que se transmiten a la clase padre de su constructor:
//--- Constructor CIndAC(const string symbol,const ENUM_TIMEFRAMES timeframe,MqlParam &mql_param[]) : CIndicatorDE(IND_AC,symbol,timeframe, INDICATOR_STATUS_STANDART, INDICATOR_GROUP_OSCILLATOR, "Accelerator Oscillator", "AC("+symbol+","+TimeframeDescription(timeframe)+")",mql_param) {}
En los parámetros de entrada de la clase, transmitimos sólo el nombre del símbolo, marco temporal y la estructura de los parámetros del indicador ya rellenada (en este ejemplo es Accelerator Oscillator).
En la lista de inicialización, transmitimos al constructor paramétrico cerrado de la clase padre (por orden) lo siguiente:
- tipo del indicador — IND_AC, nombre del símbolo, marco temporal
- estatus del indicador — estándar
- grupo del indicador — osciladores
- nombre del indicador — Accelerator Oscillator
- nombre breve del indicador — AC (símbolo, marco temporal) y estructura rellenada de parámetros del indicador
Ya conocemos los demás métodos por haber creado los objetos anteriores de la biblioteca. Ellos realizan las mismas tareas.
Los métodos que devuelven la bandera del soporte de las propiedades enteras y reales por el objeto devuelven true —todas las propiedades se soportan por los objetos de indicador.
El método que devuelve la descripción breve del indicador devuelve la cadena del tipo siguiente:
Standard indicator Accelerator Oscillator EURUSD H4
En todos los demás archivos de clases semejantes de los objetos de indicador, la diferencia será en el constructor de la clase, es decir, los parámetros correspondientes al indicador van a transmitirse al constructor de la clase padre.
Por ejemplo, para el indicador Accumulation/Distribution el constructor de la clase tendrá este aspecto:
//--- Constructor CIndAD(const string symbol,const ENUM_TIMEFRAMES timeframe,MqlParam &mql_param[]) : CIndicatorDE(IND_AD,symbol,timeframe, INDICATOR_STATUS_STANDART, INDICATOR_GROUP_VOLUMES, "Accumulation/Distribution", "AD("+symbol+","+TimeframeDescription(timeframe)+")",mql_param) {}
Como vemos, aquí ya se transmiten los parámetros correspondientes al indicador estándar AD:
- tipo del indicador — IND_AD, nombre del símbolo, marco temporal
- estatus del indicador — estándar
- grupo del indicador — volúmenes
- nombre del indicador — Accumulation/Distribution
- nombre breve del indicador — AD (símbolo, marco temporal) y estructura rellenada de parámetros del indicador
Todos los archivos de las clases herederas de la clase base del indicador abstracto ya están implementados. Puede analizarlas por sí mismo accediendo a los archivos adjuntos al artículo ubicados en la carpeta \MQL5\Include\DoEasy\Objects\Indicators\Standart.
Colección de objetos de indicador
Conforme al concepto general de la construcción y almacenamiento de objetos de la biblioteca, ahora tenemos que colocar todos los objetos creados de los indicadores en la lista de colección. A partir de esta lista, siempre podemos obtener el puntero al indicador necesario según las propiedades indicadas, o bien, una lista de indicadores que poseen propiedades generales iguales. Usando el puntero al indicador, podemos acceder a todos los datos devueltos por el indicador para los cálculos posteriores.
En la carpeta \MQL5\Include\DoEasy\Collections\ creamos una nueva clase en el archivo con el nombre IndicatorsCollection.mqh.
Aparte de los métodos estándar para la biblioteca que devuelven las listas de objetos solicitadas de la colección, la clase va a contener un método privado para crear el objeto de indicador y varios métodos para crear objetos de indicador concretos de acuerdo con su tipo, así como varios métodos para obtener punteros a los objetos de indicador, también según sus tipos. En cuanto a su lógica, todos los métodos de cada grupo son idénticos, por eso, vamos a analizar sólo algunos de ellos como ejemplo.
Para que la clase de colección de los indicadores tenga acceso a las clases de los indicadores creados más arriba, tenemos que incluirlas en el listado del archivo:
//+------------------------------------------------------------------+ //| IndicatorsCollection.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/es/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/es/users/artmedia70" #property version "1.00" //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "ListObj.mqh" #include "..\Objects\Indicators\Standart\IndAC.mqh" #include "..\Objects\Indicators\Standart\IndAD.mqh" #include "..\Objects\Indicators\Standart\IndADX.mqh" #include "..\Objects\Indicators\Standart\IndADXW.mqh" #include "..\Objects\Indicators\Standart\IndAlligator.mqh" #include "..\Objects\Indicators\Standart\IndAMA.mqh" #include "..\Objects\Indicators\Standart\IndAO.mqh" #include "..\Objects\Indicators\Standart\IndATR.mqh" #include "..\Objects\Indicators\Standart\IndBands.mqh" #include "..\Objects\Indicators\Standart\IndBears.mqh" #include "..\Objects\Indicators\Standart\IndBulls.mqh" #include "..\Objects\Indicators\Standart\IndBWMFI.mqh" #include "..\Objects\Indicators\Standart\IndCCI.mqh" #include "..\Objects\Indicators\Standart\IndChaikin.mqh" #include "..\Objects\Indicators\Standart\IndDEMA.mqh" #include "..\Objects\Indicators\Standart\IndDeMarker.mqh" #include "..\Objects\Indicators\Standart\IndEnvelopes.mqh" #include "..\Objects\Indicators\Standart\IndForce.mqh" #include "..\Objects\Indicators\Standart\IndFractals.mqh" #include "..\Objects\Indicators\Standart\IndFRAMA.mqh" #include "..\Objects\Indicators\Standart\IndGator.mqh" #include "..\Objects\Indicators\Standart\IndIchimoku.mqh" #include "..\Objects\Indicators\Standart\IndMA.mqh" #include "..\Objects\Indicators\Standart\IndMACD.mqh" #include "..\Objects\Indicators\Standart\IndMFI.mqh" #include "..\Objects\Indicators\Standart\IndMomentum.mqh" #include "..\Objects\Indicators\Standart\IndOBV.mqh" #include "..\Objects\Indicators\Standart\IndOsMA.mqh" #include "..\Objects\Indicators\Standart\IndRSI.mqh" #include "..\Objects\Indicators\Standart\IndRVI.mqh" #include "..\Objects\Indicators\Standart\IndSAR.mqh" #include "..\Objects\Indicators\Standart\IndStDev.mqh" #include "..\Objects\Indicators\Standart\IndStoch.mqh" #include "..\Objects\Indicators\Standart\IndTEMA.mqh" #include "..\Objects\Indicators\Standart\IndTRIX.mqh" #include "..\Objects\Indicators\Standart\IndVIDYA.mqh" #include "..\Objects\Indicators\Standart\IndVolumes.mqh" #include "..\Objects\Indicators\Standart\IndWPR.mqh" //+------------------------------------------------------------------+
A continuación, vamos a ver el listado completo del cuerpo de la clase, y luego, analizaremos dos métodos en cada uno de los grupos.
//+------------------------------------------------------------------+ //| Indicator collection | //+------------------------------------------------------------------+ class CIndicatorsCollection : public CObject { private: CListObj m_list; // List of indicator objects MqlParam m_mql_param[]; // Array of indicator parameters //--- Create a new indicator object CIndicatorDE *CreateIndicator(const ENUM_INDICATOR ind_type,MqlParam &mql_param[],const string symbol_name=NULL,const ENUM_TIMEFRAMES period=PERIOD_CURRENT); public: //--- Return (1) itself, (2) indicator list, (3) list of indicators by type CIndicatorsCollection *GetObject(void) { return &this; } CArrayObj *GetList(void) { return &this.m_list; } //--- Return indicator list by (1) status, (2) type, (3) timeframe, (4) group, (5) symbol, (6) name, (7) short name CArrayObj *GetListIndByStatus(const ENUM_INDICATOR_STATUS status) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_STATUS,status,EQUAL); } CArrayObj *GetListIndByType(const ENUM_INDICATOR type) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_TYPE,type,EQUAL); } CArrayObj *GetListIndByTimeframe(const ENUM_TIMEFRAMES timeframe) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_TIMEFRAME,timeframe,EQUAL); } CArrayObj *GetListIndByGroup(const ENUM_INDICATOR_GROUP group) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_GROUP,group,EQUAL); } CArrayObj *GetListIndBySymbol(const string symbol) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_SYMBOL,symbol,EQUAL); } CArrayObj *GetListIndByName(const string name) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_NAME,name,EQUAL); } CArrayObj *GetListIndByShortname(const string shortname) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_SHORTNAME,shortname,EQUAL); } //--- Return the list of indicator objects by type of indicator, symbol and timeframe CArrayObj *GetListAC(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListAD(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListADX(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListADXWilder(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListAlligator(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListAMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListAO(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListATR(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListBands(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListBearsPower(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListBullsPower(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListChaikin(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListCCI(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListDEMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListDeMarker(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListEnvelopes(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListForce(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListFractals(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListFrAMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListGator(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListIchimoku(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListBWMFI(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListMomentum(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListMFI(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListOsMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListMACD(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListOBV(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListSAR(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListRSI(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListRVI(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListStdDev(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListStochastic(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListTEMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListTriX(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListWPR(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListVIDYA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListVolumes(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the pointer to indicator object in the collection by indicator type and by its parameters CIndicatorDE *GetIndAC(const string symbol,const ENUM_TIMEFRAMES timeframe); CIndicatorDE *GetIndAD(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndADX(const string symbol,const ENUM_TIMEFRAMES timeframe,const int adx_period); CIndicatorDE *GetIndADXWilder(const string symbol,const ENUM_TIMEFRAMES timeframe,const int adx_period); CIndicatorDE *GetIndAlligator(const string symbol,const ENUM_TIMEFRAMES timeframe, const int jaw_period, const int jaw_shift, const int teeth_period, const int teeth_shift, const int lips_period, const int lips_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndAMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ama_period, const int fast_ema_period, const int slow_ema_period, const int ama_shift, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndAO(const string symbol,const ENUM_TIMEFRAMES timeframe); CIndicatorDE *GetIndATR(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); CIndicatorDE *GetIndBands(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const double deviation, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndBearsPower(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); CIndicatorDE *GetIndBullsPower(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); CIndicatorDE *GetIndChaikin(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ma_period, const int slow_ma_period, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndCCI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndDEMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndDeMarker(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); CIndicatorDE *GetIndEnvelopes(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price, const double deviation); CIndicatorDE *GetIndForce(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndFractals(const string symbol,const ENUM_TIMEFRAMES timeframe); CIndicatorDE *GetIndFrAMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndGator(const string symbol,const ENUM_TIMEFRAMES timeframe, const int jaw_period, const int jaw_shift, const int teeth_period, const int teeth_shift, const int lips_period, const int lips_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndIchimoku(const string symbol,const ENUM_TIMEFRAMES timeframe, const int tenkan_sen, const int kijun_sen, const int senkou_span_b); CIndicatorDE *GetIndBWMFI(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndMomentum(const string symbol,const ENUM_TIMEFRAMES timeframe, const int mom_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndMFI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndOsMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ema_period, const int slow_ema_period, const int signal_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndMACD(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ema_period, const int slow_ema_period, const int signal_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndOBV(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndSAR(const string symbol,const ENUM_TIMEFRAMES timeframe, const double step, const double maximum); CIndicatorDE *GetIndRSI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndRVI(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); CIndicatorDE *GetIndStdDev(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndStochastic(const string symbol,const ENUM_TIMEFRAMES timeframe, const int Kperiod, const int Dperiod, const int slowing, const ENUM_MA_METHOD ma_method, const ENUM_STO_PRICE price_field); CIndicatorDE *GetIndTEMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndTriX(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndWPR(const string symbol,const ENUM_TIMEFRAMES timeframe,const int calc_period); CIndicatorDE *GetIndVIDYA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int cmo_period, const int ema_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndVolumes(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume); //--- Create a new indicator object by indicator type and places it to collection list int CreateAC(const string symbol,const ENUM_TIMEFRAMES timeframe); int CreateAD(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume); int CreateADX(const string symbol,const ENUM_TIMEFRAMES timeframe,const int adx_period); int CreateADXWilder(const string symbol,const ENUM_TIMEFRAMES timeframe,const int adx_period); int CreateAlligator(const string symbol,const ENUM_TIMEFRAMES timeframe, const int jaw_period, const int jaw_shift, const int teeth_period, const int teeth_shift, const int lips_period, const int lips_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); int CreateAMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ama_period, const int fast_ema_period, const int slow_ema_period, const int ama_shift, const ENUM_APPLIED_PRICE applied_price); int CreateAO(const string symbol,const ENUM_TIMEFRAMES timeframe); int CreateATR(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); int CreateBands(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const double deviation, const ENUM_APPLIED_PRICE applied_price); int CreateBearsPower(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); int CreateBullsPower(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); int CreateChaikin(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ma_period, const int slow_ma_period, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_VOLUME applied_volume); int CreateCCI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); int CreateDEMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); int CreateDeMarker(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); int CreateEnvelopes(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price, const double deviation); int CreateForce(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_VOLUME applied_volume); int CreateFractals(const string symbol,const ENUM_TIMEFRAMES timeframe); int CreateFrAMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); int CreateGator(const string symbol,const ENUM_TIMEFRAMES timeframe, const int jaw_period, const int jaw_shift, const int teeth_period, const int teeth_shift, const int lips_period, const int lips_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); int CreateIchimoku(const string symbol,const ENUM_TIMEFRAMES timeframe, const int tenkan_sen, const int kijun_sen, const int senkou_span_b); int CreateBWMFI(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_APPLIED_VOLUME applied_volume); int CreateMomentum(const string symbol,const ENUM_TIMEFRAMES timeframe, const int mom_period, const ENUM_APPLIED_PRICE applied_price); int CreateMFI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_VOLUME applied_volume); int CreateMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); int CreateOsMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ema_period, const int slow_ema_period, const int signal_period, const ENUM_APPLIED_PRICE applied_price); int CreateMACD(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ema_period, const int slow_ema_period, const int signal_period, const ENUM_APPLIED_PRICE applied_price); int CreateOBV(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_APPLIED_VOLUME applied_volume); int CreateSAR(const string symbol,const ENUM_TIMEFRAMES timeframe, const double step, const double maximum); int CreateRSI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); int CreateRVI(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); int CreateStdDev(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); int CreateStochastic(const string symbol,const ENUM_TIMEFRAMES timeframe, const int Kperiod, const int Dperiod, const int slowing, const ENUM_MA_METHOD ma_method, const ENUM_STO_PRICE price_field); int CreateTEMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); int CreateTriX(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); int CreateWPR(const string symbol,const ENUM_TIMEFRAMES timeframe,const int calc_period); int CreateVIDYA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int cmo_period, const int ema_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); int CreateVolumes(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume); //--- Constructor CIndicatorsCollection(); }; //+------------------------------------------------------------------+
El listado parece bastante grande pero, en realidad, tenemos sólo varios grupos de los métodos del mismo tipo que se diferencian según el tipo del indicador requerido.
Los métodos que devuelven las listas con tipos necesarios de los indicadores son estandarizados para la biblioteca, y ya han sido considerados varias veces:
//--- Return (1) itself, (2) indicator list, (3) list of indicators by type CIndicatorsCollection *GetObject(void) { return &this; } CArrayObj *GetList(void) { return &this.m_list; } //--- Return indicator list by (1) status, (2) type, (3) timeframe, (4) group, (5) symbol, (6) name, (7) short name CArrayObj *GetListIndByStatus(const ENUM_INDICATOR_STATUS status) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_STATUS,status,EQUAL); } CArrayObj *GetListIndByType(const ENUM_INDICATOR type) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_TYPE,type,EQUAL); } CArrayObj *GetListIndByTimeframe(const ENUM_TIMEFRAMES timeframe) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_TIMEFRAME,timeframe,EQUAL); } CArrayObj *GetListIndByGroup(const ENUM_INDICATOR_GROUP group) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_GROUP,group,EQUAL); } CArrayObj *GetListIndBySymbol(const string symbol) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_SYMBOL,symbol,EQUAL); } CArrayObj *GetListIndByName(const string name) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_NAME,name,EQUAL); } CArrayObj *GetListIndByShortname(const string shortname) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_SHORTNAME,shortname,EQUAL); }
En el constructor de la clase, reseteamos la matriz de estructuras de los parámetros del indicador, limpiamos la lista de colección, establecemos la bandera de la lista ordenada para la lista y le asignamos un identificador de la colección de indicadores:
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CIndicatorsCollection::CIndicatorsCollection() { ::ArrayResize(this.m_mql_param,0); this.m_list.Clear(); this.m_list.Sort(); this.m_list.Type(COLLECTION_INDICATORS_ID); } //+------------------------------------------------------------------+
El método privado para crear el objeto de indicador simplemente crea un nuevo objeto de indicador dependiendo del tipo del indicador a crear transmitido al método y devuelve el puntero al objeto creado:
//+------------------------------------------------------------------+ //| Create a new indicator object | //+------------------------------------------------------------------+ CIndicatorDE *CIndicatorsCollection::CreateIndicator(const ENUM_INDICATOR ind_type,MqlParam &mql_param[],const string symbol_name=NULL,const ENUM_TIMEFRAMES period=PERIOD_CURRENT) { string symbol=(symbol_name==NULL || symbol_name=="" ? ::Symbol() : symbol_name); ENUM_TIMEFRAMES timeframe=(period==PERIOD_CURRENT ? ::Period() : period); CIndicatorDE *indicator=NULL; switch(ind_type) { case IND_AC : indicator=new CIndAC(symbol,timeframe,mql_param); break; case IND_AD : indicator=new CIndAD(symbol,timeframe,mql_param); break; case IND_ADX : indicator=new CIndADX(symbol,timeframe,mql_param); break; case IND_ADXW : indicator=new CIndADXW(symbol,timeframe,mql_param); break; case IND_ALLIGATOR : indicator=new CIndAlligator(symbol,timeframe,mql_param); break; case IND_AMA : indicator=new CIndAMA(symbol,timeframe,mql_param); break; case IND_AO : indicator=new CIndAO(symbol,timeframe,mql_param); break; case IND_ATR : indicator=new CIndATR(symbol,timeframe,mql_param); break; case IND_BANDS : indicator=new CIndBands(symbol,timeframe,mql_param); break; case IND_BEARS : indicator=new CIndBears(symbol,timeframe,mql_param); break; case IND_BULLS : indicator=new CIndBulls(symbol,timeframe,mql_param); break; case IND_BWMFI : indicator=new CIndBWMFI(symbol,timeframe,mql_param); break; case IND_CCI : indicator=new CIndCCI(symbol,timeframe,mql_param); break; case IND_CHAIKIN : indicator=new CIndCHO(symbol,timeframe,mql_param); break; case IND_DEMA : indicator=new CIndDEMA(symbol,timeframe,mql_param); break; case IND_DEMARKER : indicator=new CIndDeMarker(symbol,timeframe,mql_param); break; case IND_ENVELOPES : indicator=new CIndEnvelopes(symbol,timeframe,mql_param); break; case IND_FORCE : indicator=new CIndForce(symbol,timeframe,mql_param); break; case IND_FRACTALS : indicator=new CIndFractals(symbol,timeframe,mql_param); break; case IND_FRAMA : indicator=new CIndFRAMA(symbol,timeframe,mql_param); break; case IND_GATOR : indicator=new CIndGator(symbol,timeframe,mql_param); break; case IND_ICHIMOKU : indicator=new CIndIchimoku(symbol,timeframe,mql_param); break; case IND_MA : indicator=new CIndMA(symbol,timeframe,mql_param); break; case IND_MACD : indicator=new CIndMACD(symbol,timeframe,mql_param); break; case IND_MFI : indicator=new CIndMFI(symbol,timeframe,mql_param); break; case IND_MOMENTUM : indicator=new CIndMomentum(symbol,timeframe,mql_param); break; case IND_OBV : indicator=new CIndOBV(symbol,timeframe,mql_param); break; case IND_OSMA : indicator=new CIndOsMA(symbol,timeframe,mql_param); break; case IND_RSI : indicator=new CIndRSI(symbol,timeframe,mql_param); break; case IND_RVI : indicator=new CIndRVI(symbol,timeframe,mql_param); break; case IND_SAR : indicator=new CIndSAR(symbol,timeframe,mql_param); break; case IND_STDDEV : indicator=new CIndStDev(symbol,timeframe,mql_param); break; case IND_STOCHASTIC : indicator=new CIndStoch(symbol,timeframe,mql_param); break; case IND_TEMA : indicator=new CIndTEMA(symbol,timeframe,mql_param); break; case IND_TRIX : indicator=new CIndTRIX(symbol,timeframe,mql_param); break; case IND_VIDYA : indicator=new CIndVIDYA(symbol,timeframe,mql_param); break; case IND_VOLUMES : indicator=new CIndVolumes(symbol,timeframe,mql_param); break; case IND_WPR : indicator=new CIndWPR(symbol,timeframe,mql_param); break; case IND_CUSTOM : break; default: break; } return indicator; } //+------------------------------------------------------------------+
Por defecto, así como de forma temporal para el indicador personalizado también (su creación será implementada en los siguientes artículos), el método devuelve NULL.
El método para crear el objeto de indicador Accelerator Oscillator:
//+------------------------------------------------------------------+ //| Create a new indicator object Accelerator Oscillator | //| and place it to the collection list | //+------------------------------------------------------------------+ int CIndicatorsCollection::CreateAC(const string symbol,const ENUM_TIMEFRAMES timeframe) { //--- AC indicator possesses no parameters - resize the array of parameter structures ::ArrayResize(this.m_mql_param,0); //--- Create indicator object CIndicatorDE *indicator=this.CreateIndicator(IND_AC,this.m_mql_param,symbol,timeframe); if(indicator==NULL) return INVALID_HANDLE; int index=this.m_list.Search(indicator); //--- If such indicator is already in the list if(index!=WRONG_VALUE) { //--- Get indicator object from the list and return indicator handle indicator=this.m_list.At(index); return indicator.Handle(); } //--- If such indicator is not in the list else { //--- If failed to add indicator object to the list //--- display the appropriate message and return INVALID_HANDLE if(!this.m_list.Add(indicator)) { Print(CMessage::Text(MSG_LIB_SYS_FAILED_ADD_IND_TO_LIST)); return INVALID_HANDLE; } //--- Return the handle of a new indicator added to the list return indicator.Handle(); } //--- Return INVALID_HANDLE return INVALID_HANDLE; } //+------------------------------------------------------------------+
La lógica del método está descrita en su listado, y creo que no debe provocar dudas. Cabe notar que el objeto de indicador se crea en el método de su creación CreateIndicator() considerado anteriormente. El método recibe el tipo del indicador IND_AC. Como indicador AC no tiene parámetros de entrada, pues, la matriz de estructuras de los parámetros del indicador tampoco es necesaria. Por esa razón, la matriz se resetea, lo cual indica en la inutilidad de su uso durante la creación del indicador en la clase CIndicatorDE considerada en el artículo anterior.
Los demás métodos de la creación de otros indicadores estándar son idénticos en su lógica al método que acabamos de analizar, diferenciándose sólo en la especificación del indicador necesario y el relleno de la matriz de estructuras de los parámetros del indicador donde sea necesario.
Como ejemplo, vamos a analizar el método de la creación del indicador Alligator que requiere ocho parámetros de entrada. Todos ellos se añaden a la matriz de parámetros del indicador de acuerdo con el orden de secuencia de estos parámetros para el indicador Alligator, y el tipo IND_ALLIGATOR se transmite al método de la creación del objeto de indicador:
//+------------------------------------------------------------------+ //| Create new indicator object Alligator | //| and place it to the collection list | //+------------------------------------------------------------------+ int CIndicatorsCollection::CreateAlligator(const string symbol,const ENUM_TIMEFRAMES timeframe, const int jaw_period, const int jaw_shift, const int teeth_period, const int teeth_shift, const int lips_period, const int lips_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price) { //--- Add required indicator parameters to the array of parameter structures ::ArrayResize(this.m_mql_param,8); this.m_mql_param[0].type=TYPE_INT; this.m_mql_param[0].integer_value=jaw_period; this.m_mql_param[1].type=TYPE_INT; this.m_mql_param[1].integer_value=jaw_shift; this.m_mql_param[2].type=TYPE_INT; this.m_mql_param[2].integer_value=teeth_period; this.m_mql_param[3].type=TYPE_INT; this.m_mql_param[3].integer_value=teeth_shift; this.m_mql_param[4].type=TYPE_INT; this.m_mql_param[4].integer_value=lips_period; this.m_mql_param[5].type=TYPE_INT; this.m_mql_param[5].integer_value=lips_shift; this.m_mql_param[6].type=TYPE_INT; this.m_mql_param[6].integer_value=ma_method; this.m_mql_param[7].type=TYPE_INT; this.m_mql_param[7].integer_value=applied_price; //--- Create indicator object CIndicatorDE *indicator=this.CreateIndicator(IND_ALLIGATOR,this.m_mql_param,symbol,timeframe); if(indicator==NULL) return INVALID_HANDLE; int index=this.m_list.Search(indicator); //--- If such indicator is already in the list if(index!=WRONG_VALUE) { //--- Get indicator object from the list and return indicator handle indicator=this.m_list.At(index); return indicator.Handle(); } //--- If such indicator is not in the list else { //--- If failed to add indicator object to the list //--- display the appropriate message and return INVALID_HANDLE if(!this.m_list.Add(indicator)) { Print(CMessage::Text(MSG_LIB_SYS_FAILED_ADD_IND_TO_LIST)); return INVALID_HANDLE; } //--- Return the handle of a new indicator added to the list return indicator.Handle(); } //--- Return INVALID_HANDLE return INVALID_HANDLE; } //+------------------------------------------------------------------+
Estas son todas las diferencias entre los métodos. No vamos a analizar los demás métodos de la creación de indicadores. Están disponibles en los archivos adjuntos al artículo.
El método que devuelve la lista de todos los objetos de indicador Accelerator Oscillator ubicados en la lista de colección, según el símbolo y marco temporal:
//+------------------------------------------------------------------+ //| Return the list of Accelerator Oscillator indicator objects | //| by symbol and timeframe | //+------------------------------------------------------------------+ CArrayObj *CIndicatorsCollection::GetListAC(const string symbol,const ENUM_TIMEFRAMES timeframe) { CArrayObj *list=GetListIndByType(IND_AC); list=CSelect::ByIndicatorProperty(list,INDICATOR_PROP_SYMBOL,symbol,EQUAL); return CSelect::ByIndicatorProperty(list,INDICATOR_PROP_TIMEFRAME,timeframe,EQUAL); } //+------------------------------------------------------------------+
Primero, obtenemos la lista de todos los objetos de indicador de Accelerator Oscillator que se encuentran en la lista de colección.
Luego, filtramos las lista obtenida según el símbolo
y devolvemos la lista obtenida que ha sido filtrada de nuevo, ya según el marco temporal.
Los demás métodos son absolutamente idénticos al método analizado antes. La única diferencia es que primero obtenemos la lista de todos los indicadores necesarios de acuerdo con el cometido del método.
Por ejemplo, para obtener la lista de todos los objetos de indicador Accumulation/Distribution ubicados en la lista de colección, según el símbolo y marco temporal, el método será el siguiente:
//+------------------------------------------------------------------+ //| Return the list of indicator objects Accumulation/Distribution | //| by symbol and timeframe | //+------------------------------------------------------------------+ CArrayObj *CIndicatorsCollection::GetListAD(const string symbol,const ENUM_TIMEFRAMES timeframe) { CArrayObj *list=GetListIndByType(IND_AD); list=CSelect::ByIndicatorProperty(list,INDICATOR_PROP_SYMBOL,symbol,EQUAL); return CSelect::ByIndicatorProperty(list,INDICATOR_PROP_TIMEFRAME,timeframe,EQUAL); } //+------------------------------------------------------------------+
Aquí, primero, obtenemos la lista de todos los indicadores AD ubicados en la colección. Luego, filtramos la lista según el símbolo y el marco temporal como en el método analizado más arriba.
Hoy, implementamos sólo un método que devuelve el puntero al objeto de indicador en la colección según el tipo del indicador y sus parámetros (para el indicador Accelerator Oscillator):
//+------------------------------------------------------------------+ //| Return the pointer to Accelerator Oscillator indicator object | //+------------------------------------------------------------------+ CIndicatorDE *CIndicatorsCollection::GetIndAC(const string symbol,const ENUM_TIMEFRAMES timeframe) { CArrayObj *list=GetListAC(symbol,timeframe); return(list==NULL || list.Total()==0 ? NULL : list.At(0)); } //+------------------------------------------------------------------+
Puesto que este indicador (y algunos otros) no tiene parámetros de entrada, al seleccionarlo de la lista de colección según el símbolo y marco temporal, la lista va a contener sólo un objeto de indicador (por el índice 0) que corresponda al tipo IND_AC y al símbolo y marco temporal solicitados.
Mientras que los indicadores que poseen parámetros de entrada requieren los métodos adicionales de búsqueda en la matriz de estructuras de los parámetros del indicador para realizar su búsqueda según los parámetros especificados. Y eso ya excede de los límites del presente artículo. Por eso, analizaremos estos métodos en el siguiente artículo.
Como este artículo tiene una orientación más bien educativa y no pretende a estar completada, pues, vamos a simular solamente la creación de un objeto de indicador Accelerator Oscillator. En el artículo anterior, ya simulamos la creación de un objeto-indicador AC en la clase de colección de los búferes:
//+------------------------------------------------------------------+ //| Create multi-symbol multi-period AC | //+------------------------------------------------------------------+ int CBuffersCollection::CreateAC(const string symbol,const ENUM_TIMEFRAMES timeframe,const int id=WRONG_VALUE) { //--- To check it, create indicator object, print its data and remove it at once ::ArrayResize(this.m_mql_param,0); CIndicatorDE *indicator=new CIndicatorDE(IND_AC,symbol,timeframe,INDICATOR_STATUS_STANDART,INDICATOR_GROUP_OSCILLATOR,"Accelerator Oscillator","AC("+symbol+","+TimeframeDescription(timeframe)+")",this.m_mql_param); indicator.Print(); delete indicator; //--- Create the indicator handle and set the default ID
Hoy, hacemos la misma cosa. Es decir, en el mismo método, vamos a crear un objeto del indicador Accelerator Oscillator, pero en este caso, usando las clases nuevamente escritas.
Adelantándonos un poco, diremos que vamos a necesitar «ver» la lista de colección en la clase de colección de series temporales para que se nos abra la posibilidad de almacenar datos de todos los indicadores creados en los objetos de barras que «se encuentran» en las listas de series temporales.
Por eso, tenemos que incluir previamente la clase de colección de indicadores en la clase de colección de series temporales en el archivo \MQL5\Include\DoEasy\Collections\TimeSeriesCollection.mqh:
//+------------------------------------------------------------------+ //| TimeSeriesCollection.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/es/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/es/users/artmedia70" #property version "1.00" //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "ListObj.mqh" #include "..\Objects\Series\TimeSeriesDE.mqh" #include "..\Objects\Symbols\Symbol.mqh" #include "IndicatorsCollection.mqh" //+------------------------------------------------------------------+
Luego, declaramos el puntero a la clase de colección de indicadores en la sección privada de la clase:
//+------------------------------------------------------------------+ //| Symbol timeseries collection | //+------------------------------------------------------------------+ class CTimeSeriesCollection : public CBaseObjExt { private: CListObj m_list; // List of applied symbol timeseries CIndicatorsCollection *m_indicators; // Pointer to collection object of indicators //--- Return the timeseries index by symbol name int IndexTimeSeries(const string symbol); public:
Al final del listado de la clase, creamos el método de inicialización a través del cual vamos a transmitir el puntero al objeto de la colección de indicadores a la clase en el objeto principal de la biblioteca CEngine:
//--- Constructor CTimeSeriesCollection(); //--- Get pointers to the indicator collection (the method is called in CollectionOnInit() method of the CEngine object) void OnInit(CIndicatorsCollection *indicators) { this.m_indicators=indicators; } }; //+------------------------------------------------------------------+
En el archivo de la clase de colección de los búferes \MQL5\Include\DoEasy\Collections\BuffersCollection.mqh también declaramos el puntero al objeto de la colección de los indicadores:
//+------------------------------------------------------------------+ //| Collection of indicator buffers | //+------------------------------------------------------------------+ class CBuffersCollection : public CObject { private: CListObj m_list; // Buffer object list CTimeSeriesCollection *m_timeseries; // Pointer to the timeseries collection object CIndicatorsCollection *m_indicators; // Pointer to collection object of indicators MqlParam m_mql_param[]; // Array of indicator parameters //--- Return the index of the (1) last, (2) next drawn and (3) basic buffer int GetIndexLastPlot(void); int GetIndexNextPlot(void); int GetIndexNextBase(void); //--- Create a new buffer object and place it to the collection list bool CreateBuffer(ENUM_BUFFER_STATUS status); //--- Get data of the necessary timeseries and bars for working with a single buffer bar, and return the number of bars int GetBarsData(CBuffer *buffer,const int series_index,int &index_bar_period); public:
Al método de la clase OnInit() le añadimos la asignación a este puntero de un valor que se transmite por el parámetro de entrada:
//--- Constructor CBuffersCollection(); //--- Get pointers to collections of timeseries and indicators (the method is called in CollectionOnInit() method of the CEngine object) void OnInit(CTimeSeriesCollection *timeseries,CIndicatorsCollection *indicators) { this.m_timeseries=timeseries; this.m_indicators=indicators; } }; //+------------------------------------------------------------------+
En el método de la creación del indicador AC, cambiamos la creación del objeto de indicador realizada en el artículo anterior por su creación y obtención a través de la clase de colección de los indicadores:
//+------------------------------------------------------------------+ //| Create multi-symbol multi-period AC | //+------------------------------------------------------------------+ int CBuffersCollection::CreateAC(const string symbol,const ENUM_TIMEFRAMES timeframe,const int id=WRONG_VALUE) { //--- To check it, create indicator object, print its data and remove it at once //--- Parameters are not needed for AC, therefore, reset the array of indicator parameter structures ::ArrayResize(this.m_mql_param,0); //--- Create AC indicator and add it to collection this.m_indicators.CreateAC(symbol,timeframe); //--- Get from collection of AC indicator object CIndicatorDE *indicator=this.m_indicators.GetIndAC(symbol,timeframe); //--- Display all data of the created indicator in the journal, display its short description and remove indicator object indicator.Print(); indicator.PrintShort(); delete indicator; //--- Create the indicator handle and set the default ID
Ahora, vamos a mejorar la clase del objeto principal de la biblioteca CEngine.
En el archivo \MQL5\Include\DoEasy\Engine.mqh escribimos la inclusión del archivo de la colección de los indicadores en el listado de la clase:
//+------------------------------------------------------------------+ //| Engine.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/es/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/es/users/artmedia70" #property version "1.00" //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "Services\TimerCounter.mqh" #include "Collections\HistoryCollection.mqh" #include "Collections\MarketCollection.mqh" #include "Collections\EventsCollection.mqh" #include "Collections\AccountsCollection.mqh" #include "Collections\SymbolsCollection.mqh" #include "Collections\ResourceCollection.mqh" #include "Collections\TimeSeriesCollection.mqh" #include "Collections\BuffersCollection.mqh" #include "Collections\IndicatorsCollection.mqh" #include "TradingControl.mqh" //+------------------------------------------------------------------+
Declaramos el objeto de la clase de colección de los indicadores en la sección privada de la clase:
//+------------------------------------------------------------------+ //| Library basis class | //+------------------------------------------------------------------+ class CEngine { private: CHistoryCollection m_history; // Collection of historical orders and deals CMarketCollection m_market; // Collection of market orders and deals CEventsCollection m_events; // Event collection CAccountsCollection m_accounts; // Account collection CSymbolsCollection m_symbols; // Symbol collection CTimeSeriesCollection m_time_series; // Timeseries collection CBuffersCollection m_buffers; // Collection of indicator buffers CIndicatorsCollection m_indicators; // Indicator collection CResourceCollection m_resource; // Resource list CTradingControl m_trading; // Trading management object CPause m_pause; // Pause object CArrayObj m_list_counters; // List of timer counters int m_global_error; // Global error code bool m_first_start; // First launch flag bool m_is_hedge; // Hedge account flag bool m_is_tester; // Flag of working in the tester bool m_is_market_trade_event; // Account trading event flag bool m_is_history_trade_event; // Account history trading event flag bool m_is_account_event; // Account change event flag bool m_is_symbol_event; // Symbol change event flag ENUM_TRADE_EVENT m_last_trade_event; // Last account trading event int m_last_account_event; // Last event in the account properties int m_last_symbol_event; // Last event in the symbol properties ENUM_PROGRAM_TYPE m_program; // Program type string m_name; // Program name //--- Return the counter index by id int CounterIndex(const int id) const; //--- Return the first launch flag bool IsFirstStart(void); //--- Work with (1) order, deal and position, (2) account events void TradeEventsControl(void); void AccountEventsControl(void); //--- (1) Working with a symbol collection and (2) symbol list events in the market watch window void SymbolEventsControl(void); void MarketWatchEventsControl(void); //--- Return the last (1) market pending order, (2) market order, (3) last position, (4) position by ticket COrder *GetLastMarketPending(void); COrder *GetLastMarketOrder(void); COrder *GetLastPosition(void); COrder *GetPosition(const ulong ticket); //--- Return the last (1) removed pending order, (2) historical market order, (3) historical order (market or pending one) by its ticket COrder *GetLastHistoryPending(void); COrder *GetLastHistoryOrder(void); COrder *GetHistoryOrder(const ulong ticket); //--- Return the (1) first and the (2) last historical market orders from the list of all position orders, (3) the last deal COrder *GetFirstOrderPosition(const ulong position_id); COrder *GetLastOrderPosition(const ulong position_id); COrder *GetLastDeal(void); //--- Retrieve a necessary 'ushort' number from the packed 'long' value ushort LongToUshortFromByte(const long source_value,const uchar index) const; public:
En la sección pública, vamos a escribir dos métodos para devolver el puntero al objeto de colección de los indicadores y puntero a la lista de indicadores de esta colección:
//--- Return the bar index on the specified timeframe chart by the current chart's bar index int IndexBarPeriodByBarCurrent(const int series_index,const string symbol,const ENUM_TIMEFRAMES timeframe) { return this.m_time_series.IndexBarPeriodByBarCurrent(series_index,symbol,timeframe); } //--- Return (1) the indicator collection, (2) the indicator list from the collection CIndicatorsCollection *GetIndicatorsCollection(void) { return &this.m_indicators; } CArrayObj *GetListIndicators(void) { return this.m_indicators.GetList(); }
Estos métodos nos serán útiles para invocar la colección de los indicadores desde nuestros programas.
Añadimos al método CollectionOnInit() la transmisión del puntero a la colección de los indicadores a las clases de colección de los búferes y series temporales:
//--- Pass the pointers to all the necessary collections to the trading class and the indicator buffer collection class void CollectionOnInit(void) { this.m_trading.OnInit(this.GetAccountCurrent(),m_symbols.GetObject(),m_market.GetObject(),m_history.GetObject(),m_events.GetObject()); this.m_buffers.OnInit(this.m_time_series.GetObject(),this.m_indicators.GetObject()); this.m_time_series.OnInit(this.m_indicators.GetObject()); }
Ahora, al inicializar la biblioteca, el puntero al objeto de colección de los indicadores será transmitido a todas las clases donde se requiere el acceso a la colección de los indicadores. Por tanto, ellas podrán trabajar con esta colección.
De momento, éstas son todas las mejoras necesarias para crear la clase de colección de los indicadores.
Prueba
Para la prueba, necesitaremos el indicador del artículo anterior sin ningunas alteraciones.
Simplemente, lo guardamos en la carpeta nueva \MQL5\Indicators\TestDoEasy\Part54\ con el nombre nuevo TestDoEasyPart54.mq5.
Compilamos el indicador y lo iniciamos en el gráfico.
En el diario, se mostrarán todos los parámetros del indicador creado Accelerator Oscillator y su descripción breve:
Account 8550475: Artyom Trishkin (MetaQuotes Software Corp.) 10425.23 USD, 1:100, Hedge, MetaTrader 5 demo --- Initializing "DoEasy" library --- Working with the current symbol only. The number of used symbols: 1 "EURUSD" Working with the specified timeframe list: "H4" "H1" EURUSD symbol timeseries: - Timeseries "EURUSD" H1: Requested: 1000, Actual: 0, Created: 0, On the server: 0 - Timeseries "EURUSD" H4: Requested: 1000, Actual: 1000, Created: 1000, On the server: 6231 Library initialization time: 00:00:00.156 ============= Parameter list start: "Standard indicator" ============= Indicator status: Standard indicator Type of indicator: AC Indicator timeframe: H4 Indicator handle: 10 Indicator group: Oscillator ------ Empty value for plotting where nothing will be drawn: EMPTY_VALUE ------ Indicator symbol: EURUSD Indicator name: "Accelerator Oscillator" Indicator short name: "AC(EURUSD,H4)" ================== Parameter list end: "Standard indicator" ================== Standard indicator Accelerator Oscillator EURUSD H4 Buffer(P0/B0/C1): Histogram from the zero line EURUSD H4 Buffer[P0/B2/C2]: Calculated buffer "EURUSD" H1 timeseries created successfully: - Timeseries "EURUSD" H1: Requested: 1000, Actual: 1000, Created: 1000, On the server: 6256
¿Qué es lo próximo?
En el próximo artículo, continuaremos trabajando con la clase de colección de los indicadores.
.
Más abajo se adjuntan todos los archivos de la versión actual de la biblioteca y el archivo del indicador de prueba para MQL5. Puede descargarlo todo y ponerlo a prueba por sí mismo.
Nótese que, por el momento, la clase de colección de los indicadores se encuentra en el proceso del desarrollo. Por tanto, se recomienda estrictamente no usarla en sus programas.
Si tiene preguntas, observaciones o sugerencias, podrá concretarlas en los comentarios al artículo.
Artículos de esta serie:
Trabajando con las series temporales en la biblioteca DoEasy (Parte 35): El objeto "Barra" y la lista de serie temporal del símbolo
Trabajando con las series temporales en la biblioteca DoEasy (Parte 36): El objeto de series temporales de todos los periodos utilizados del símbolo
Trabajando con las series temporales en la biblioteca DoEasy (Parte 37): Colección de series temporales - Base de datos de series temporales según el símbolo y el periodo
Trabajando con las series temporales en la biblioteca DoEasy (Parte 38): Colección de series temporales - Actualización en tiempo real y acceso a los datos desde el programa
Trabajando con las series temporales en la biblioteca DoEasy (Parte 39): Indicadores basados en la biblioteca - Preparación de datos y eventos de la series temporales
Trabajando con las series temporales en la biblioteca DoEasy (Parte 40): Indicadores basados en la biblioteca - actualización de datos en tiempo real
Trabajando con las series temporales en la biblioteca DoEasy (Parte 41): Ejemplo de indicador de símbolo y periodo múltiples
Trabajando con las series temporales en la biblioteca DoEasy (Parte 42): La clase del objeto de búfer de indicador abstracto
Trabajando con las series temporales en la biblioteca DoEasy (Parte 43): Las clases de los objetos de búferes de indicador
Trabajando con las series temporales en la biblioteca DoEasy (Parte 44): Las clases de colección de los objetos de búferes de indicador
Trabajando con las series temporales en la biblioteca DoEasy (Parte 45): Búferes de indicador de periodo múltiple
Trabajando con las series temporales en la biblioteca DoEasy (Parte 46): Búferes de indicador de periodo y símbolos múltiples
Trabajando con las series temporales en la biblioteca DoEasy (Parte 47): Indicadores estándar de periodo y símbolo múltiples
Trabajando con las series temporales en la biblioteca DoEasy (Parte 48): Indicadores de periodo y símbolo múltiples en un búfer en una subventana
Trabajando con las series temporales en la biblioteca DoEasy (Parte 49): Indicadores estándar de periodo, símbolo y búfer múltiples
Trabajando con las series temporales en la biblioteca DoEasy (Parte 50): Indicadores estándar de periodo y símbolo múltiples con desplazamiento
Trabajando con las series temporales en la biblioteca DoEasy (Parte 51): Indicadores estándar compuestos de período y símbolo múltiples
Trabajando con las series temporales en la biblioteca DoEasy (Parte 52): Concepto multiplataforma de indicadores estándar de periodo y símbolo múltiples de búfer único
Trabajando con las series temporales en la biblioteca DoEasy (Parte 53): Clase del indicador abstracto básico
Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/8508
![Optimización móvil continua (Parte 8): Mejorando el programa y corrigiendo los errores encontrados](https://c.mql5.com/2/40/MQL5-avatar-continuous_optimization__4.png)
![Trabajando con las series temporales en la biblioteca DoEasy (Parte 53): Clase del indicador abstracto básico](https://c.mql5.com/2/40/MQL5-avatar-doeasy-library__5.png)
![Redes neuronales: así de sencillo (Parte 3): Redes convolucionales](https://c.mql5.com/2/48/Neural_networks_made_easy_003.png)
![Trabajando con las series temporales en la biblioteca DoEasy (Parte 52): Concepto multiplataforma de indicadores estándar de período y símbolo múltiples de búfer único](https://c.mql5.com/2/40/MQL5-avatar-doeasy-library__4.png)
![MQL5 - Lenguaje de estrategias comerciales para el terminal de cliente MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- 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