- Evento principal de Asesores Expertos: OnTick
- Principios y conceptos básicos: orden, transacción y posición
- Tipos de operaciones de trading
- Tipos de órdenes
- Modos de ejecución de órdenes por precio y volumen
- Fechas de vencimiento de órdenes pendientes
- Cálculo del margen para una orden futura: OrderCalcMargin
- Estimación del beneficio de una operación de trading: OrderCalcProfit
- Estructura MqlTradeRequest
- Estructura MqlTradeCheckResult
- Solicitar validación: OrderCheck
- Solicitar resultado del envío: estructura MqlTradeResult
- Enviar una solicitud de trading: OrderSend y OrderSendAsync
- Operaciones de compraventa
- Modificar los niveles de Stop Loss y/o Take Profit de una posición
- Trailing stop
- Cierre de una posición: total y parcial
- Cierre de posiciones opuestas: total y parcial
- Colocar una orden pendiente
- Modificar una orden pendiente
- Borrar una orden pendiente
- Obtener una lista de órdenes activas
- Propiedades de una orden (activas e históricas)
- Funciones para leer las propiedades de órdenes activas
- Seleccionar órdenes por propiedades
- Obtener la lista de posiciones
- Propiedades de posiciones
- Funciones de lectura de propiedades de posición
- Propiedades de transacción
- Seleccionar órdenes y transacciones del historial
- Funciones para leer propiedades de órdenes del historial
- Funciones para leer propiedades de transacciones del historial
- Tipos de transacciones de trading
- Evento OnTradeTransaction
- Peticiones síncronas y asíncronas
- Evento OnTrade
- Seguimiento de los cambios en el entorno de trading
- Crear Asesores Expertos multisímbolo
- Limitaciones y ventajas de los Asesores Expertos
- Crear Asesores Expertos en el Asistente MQL
Funciones para leer propiedades de órdenes del historial
Las funciones para la lectura de las propiedades de las órdenes históricas se dividen en 3 grupos, según el tipo básico de los valores de las propiedades, de acuerdo con la división de los identificadores de las propiedades disponibles en tres enumeraciones: ENUM_ORDER_PROPERTY_INTEGER, ENUM_ORDER_PROPERTY_DOUBLE y ENUM_ORDER_PROPERTY_STRING que abordamos anteriormente en una sección aparte al explorar las órdenes activas.
Antes de llamar a estas funciones, es necesario seleccionar de alguna manera el conjunto adecuado de tickets del historial.
Si intenta leer las propiedades de una orden o de una transacción que tenga tickets fuera del contexto de historial seleccionado, el entorno puede generar un error WRONG_INTERNAL_PARAMETER (4002), que puede analizarse a través de _LastError.
Para cada tipo de propiedad base, existen dos formas de función: una devuelve directamente el valor de la propiedad solicitada, la segunda lo escribe en un parámetro pasado por referencia y devuelve un indicador de éxito (true) o errores (false).
Para los tipos de enteros y compatibles (datetime, enums) de propiedades existe una función dedicada HistoryOrderGetInteger.
long HistoryOrderGetInteger(ulong ticket, ENUM_ORDER_PROPERTY_INTEGER property)
bool HistoryOrderGetInteger(ulong ticket, ENUM_ORDER_PROPERTY_INTEGER property,
long &value)
La función le permite encontrar la orden property del historial seleccionado por su número de ticket.
Para las propiedades reales, se asigna la función HistoryOrderGetDouble.
double HistoryOrderGetDouble(ulong ticket, ENUM_ORDER_PROPERTY_DOUBLE property)
bool HistoryOrderGetDouble(ulong ticket, ENUM_ORDER_PROPERTY_DOUBLE property,
double &value)
Por último, las propiedades de cadena pueden leerse con HistoryOrderGetString.
string HistoryOrderGetString(ulong ticket, ENUM_ORDER_PROPERTY_STRING property)
bool HistoryOrderGetString(ulong ticket, ENUM_ORDER_PROPERTY_STRING property,
string &value)
Ahora podemos complementar la clase OrderMonitor (OrderMonitor.mqh) para trabajar con órdenes históricas. En primer lugar, vamos a añadir una variable booleana a la clase history, que rellenaremos en el constructor en función del segmento en el que se seleccionó la orden con el ticket pasado: entre los activos (OrderSelect) o en el historial (HistoryOrderSelect).
class OrderMonitor: public OrderMonitorInterface
|
Necesitamos llamar a la función ResetLastError en una rama exitosa de if para restablecer el posible error que podría establecer la función OrderSelect (si la orden está en el historial).
De hecho, esta versión del constructor contiene un grave error lógico, y volveremos a él dentro de unos párrafos.
Para leer propiedades en métodos get, llamamos ahora a diferentes funciones integradas, dependiendo del valor de la variable history.
virtuallongget(constENUM_ORDER_PROPERTY_INTEGERproperty)constoverride { returnhistory?HistoryOrderGetInteger(ticket,property) :OrderGetInteger(property); }
virtualdoubleget(constENUM_ORDER_PROPERTY_DOUBLEproperty)constoverride { returnhistory?HistoryOrderGetDouble(ticket,property) :OrderGetDouble(property); }
virtualstringget(constENUM_ORDER_PROPERTY_STRINGproperty)constoverride { returnhistory?HistoryOrderGetString(ticket,property) :OrderGetString(property); } ... |
El objetivo principal de la clase OrderMonitor es suministrar datos a otras clases analíticas. Los objetos OrderMonitor se utilizan para filtrar órdenes activas en la clase OrderFilter, y necesitamos una clase similar para seleccionar órdenes por condiciones arbitrarias en el historial: HistoryOrderFilter.
Escribamos esta clase en el mismo archivo OrderFilter.mqh, que utiliza dos nuevas funciones para trabajar con el historial: HistoryOrdersTotal y HistoryOrderGetTicket.
class HistoryOrderFilter: public TradeFilter<OrderMonitor,
|
Este sencillo código hereda de la clase de plantilla TradeFilter, donde la clase se pasa como primer parámetro de la plantilla OrderMonitor para leer las propiedades de los objetos correspondientes (vimos un análogo para posiciones, y pronto crearemos uno para transacciones).
Aquí radica el problema con el constructor OrderMonitor. Como descubrimos en la sección Seleccionar órdenes y transacciones del historial, para analizar la cuenta, primero debemos establecer el contexto con una de las funciones, como HistorySelect. Así que aquí en el código fuente HistoryOrderFilter se asume que el programa MQL ya ha seleccionado el fragmento de historial requerido. Sin embargo, la nueva versión intermedia del constructor OrderMonitor utiliza la llamada HistoryOrderSelect para comprobar la existencia de un ticket en el historial. Mientras tanto, esta función restablece el contexto anterior de órdenes históricas y selecciona una única orden.
Por tanto, necesitamos un método de ayuda historyOrderSelectWeak para validar el ticket de una manera «suave», sin romper el contexto existente. Para ello, basta con comprobar si la propiedad ORDER_TICKET es igual al ticket pasado t: (HistoryOrderGetInteger(t, ORDER_TICKET) == t). Si dicho ticket ya ha sido seleccionado (disponible), la comprobación tendrá éxito y el monitor no necesitará manipular el historial.
class OrderMonitor: public OrderMonitorInterface
|
Un ejemplo de aplicación del filtrado de órdenes en el historial se estudiará en la siguiente sección, después de que preparemos una funcionalidad similar para las transacciones.