Discusión sobre el artículo "La escritura de un Expert Advisor mediante las librerías estándar de las clase de trading de MQL5" - página 3

 

También hay líneas en la clase COrderInfo

return(FormatType(str,Type()));
...
FormatType(type,Type())
...
if(m_type==Type() && m_state==State() &&

Pero la función Type() está ausente en la clase.

 

En el apartado 1.4 del artículo se proporcionan las características de la clase COrderInfo, que, a juzgar por la descripción, está diseñada para trabajar con órdenes pendientes activas. Se sugiere hacer lo siguiente:"Para utilizar esta clase para obtener las propiedades de las órdenes pendientes, primero solicitamos el número total de órdenes y las seleccionamos por ticket de orden"

//Seleccionar todas las órdenes históricas para el periodo de tiempo especificado
if (HistorySelect(0,TimeCurrent()))   // todos los pedidos
   {    
     // obtener el número total de pedidos
     int o_total = OrdersTotal();
   }
Pero si la función HistorySelect() está diseñada para consultarel "histórico de transacciones y órdenes", es decir, para consultar órdenes históricas, ¿por qué utilizar esta función cuando se consulta el número total de órdenes pendientes activas?
 
Yedelkin:

En la clase COrderInfo ...

Pero la función Type() está ausente en la clase.

La misma situación con las clases CDealInfo y CPositionInfo
 

¿Puede alguien explicarlo? Aquí hay un trozo de código de la clase CDealInfo:

//+------------------------------------------------------------------+
//|DealInfo.mqh
//+------------------------------------------------------------------+
#include <Object.mqh>
#include "SymbolInfo.mqh"
//+------------------------------------------------------------------+
//| Clase CDealInfo.|
//| Cita: Clase para acceder a la información del trato del historial. |||
//| Deriva de la clase CObject.|
//+------------------------------------------------------------------+
class CDealInfo : public CObject
  {
   ...
public:
   ...
   //--- métodos de acceso rápido a las propiedades de posición de las cadenas
   string            Symbol()           const;
   ...
  };
...
//+------------------------------------------------------------------+
//| Obtener el valor de la propiedad "DEAL_SYMBOL." |||
//| INPUT: no.|
//| OUTPUT: el valor de la propiedad "DEAL_SYMBOL". |||
//|| OBSERVACIÓN: no.|
//+------------------------------------------------------------------+
string CDealInfo::Symbol() const
  {
   return(HistoryDealGetString(m_ticket,DEAL_SYMBOL));                           /volver estúpidamente
  }
...
//+------------------------------------------------------------------+
//| Convierte los parámetros del trato en texto. |||
//| INPUT:str - cadena de recepción,|
//| deal - puntero a la instancia de la clase. |||
//| SALIDA: cadena formateada.|
//|| OBSERVACIÓN: no.|
//+------------------------------------------------------------------+
string CDealInfo::FormatDeal(string& str) const
  {
   string type,volume,price,date;
   CSymbolInfo symbol;                                                    
//--- set up
   symbol.Name(Symbol());
   int digits=symbol.Digits();
//--- formar la descripción del acuerdo
   switch(Type())
     {
      ...
     }
//--- devuelve el resultado
   return(str);
  }
...
//+------------------------------------------------------------------+

Aquí la función CDealInfo::FormatDeal(string& str) contiene esta línea:

   symbol.Name(Symbol());
A su vez, la función Symbol() está definida tanto en la propia clase CDealInfo como entre las funciones estándar del terminal cliente. ¿Qué función se pasa como argumento a la función symbol.Name()? ¿Por qué regla?
 
Yedelkin:

¿Puede alguien explicarlo? Aquí hay un trozo de código de la clase CDealInfo:

Aquí la función CDealInfo::FormatDeal(string& str) contiene esta línea:

A su vez, la función Symbol() está definida tanto en la propia clase CDealInfo como entre las funciones estándar del terminal cliente. ¿Qué función se pasa como argumento a la función symbol.Name()? ¿Por qué regla?

Aquí funciona la misma regla que con el ámbito de las variables. Si una variable se declara con un mismo nombre a nivel global y local, dentro del ámbito local el nombre apuntará a la variable local y fuera a la global.

Resulta que si una función estándar se sobrecarga dentro de una clase, el cuerpo de la sobrecarga se llamará en la propia clase y el cuerpo de la función estándar se llamará a nivel global. El cuerpo de la función sobrecargada puede ser llamado a nivel global a través del puntero de la clase.

 
Urain:

Aquí funciona la misma regla que con el ámbito de las variables. Si una variable se declara con el mismo nombre a nivel global y local, dentro del ámbito local el nombre apuntará a la variable local, y fuera a la global.

Resulta que si una función estándar se sobrecarga dentro de una clase, el cuerpo de la sobrecarga se llamará en la propia clase y el cuerpo de la función estándar se llamará a nivel global. El cuerpo de la función sobrecargada puede ser llamado a nivel global a través del puntero de la clase.

Muchas gracias. ¡Es claro y comprensible!
 
Gracias Samuel por escribir un artículo tan profundo. Se agradece.
 
Agradable y fácil de entender
[Eliminado]  
Muy buen artículo. Lo estoy utilizando como referencia.
 
El capítulo 1.4 utiliza el historial de pedidos para describir COrderInfo, ¿es correcto?