- 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 las propiedades de órdenes activas
Los conjuntos de funciones que pueden utilizarse para obtener los valores de todas las propiedades de las órdenes difieren para las órdenes activas y las históricas. En esta sección se describen las funciones para leer las propiedades de las órdenes activas. Para conocer las funciones que permiten acceder a las propiedades de las órdenes en el historial, consulte la sección correspondiente.
Las propiedades de los enteros pueden leerse utilizando la función OrderGetInteger, que tiene dos formas: la primera devuelve directamente el valor de la propiedad; la segunda devuelve un signo lógico de éxito (true) o error (false), y el segundo parámetro pasado por referencia se rellena con el valor de la propiedad.
long OrderGetInteger(ENUM_ORDER_PROPERTY_INTEGER property)
bool OrderGetInteger(ENUM_ORDER_PROPERTY_INTEGER property, long &value)
Ambas funciones permiten obtener la propiedad de orden solicitada de un tipo compatible con enteros (datetime, long/ulong o listado). Aunque el prototipo menciona long, desde un punto de vista técnico, el valor se almacena como una celda de 8 bytes, que puede convertirse a tipos compatibles sin ninguna conversión de la representación interna, en concreto, a ulong, que se utiliza para todos los tickets.
Un par de funciones similares están pensadas para propiedades de tipo real double.
double OrderGetDouble(ENUM_ORDER_PROPERTY_DOUBLE property)
bool OrderGetDouble(ENUM_ORDER_PROPERTY_DOUBLE property, double &value)
Por último, las propiedades de cadena están disponibles a través de un par de funciones OrderGetString.
string OrderGetString(ENUM_ORDER_PROPERTY_STRING property)
bool OrderGetString(ENUM_ORDER_PROPERTY_STRING property, string &value)
Como primer parámetro, todas las funciones toman el identificador de la propiedad que nos interesa. Debe ser un elemento de una de las enumeraciones (ENUM_ORDER_PROPERTY_INTEGER, ENUM_ORDER_PROPERTY_DOUBLE o ENUM_ORDER_PROPERTY_STRING) que se describen en la sección anterior.
Tenga en cuenta que antes de llamar a cualquiera de las funciones anteriores, debe seleccionar primero una orden utilizando OrderSelect o OrderGetTicket.
Para leer todas las propiedades de una orden específica, desarrollaremos la clase OrderMonitor (OrderMonitor.mqh) que funciona según el mismo principio que los monitores de símbolo (SymbolMonitor.mqh) y cuenta de trading (AccountMonitor.mqh) considerados anteriormente.
Estas y otras clases de monitores que se abordan en el libro ofrecen una forma unificada de analizar propiedades mediante versiones sobrecargadas de métodos get virtuales.
Mirando un poco más adelante, digamos que las transacciones y las posiciones tienen la misma agrupación de propiedades según los tres tipos principales de valores, y también necesitamos implementar monitores para ellos. A este respecto, tiene sentido separar el algoritmo general en una clase abstracta base MonitorInterface (TradeBaseMonitor.mqh). Esta es una clase de plantilla con tres parámetros destinados a especificar los tipos de enumeraciones concretas, para los grupos de propiedades entero (I), real (D) y cadena (S).
#include <MQL5Book/EnumToArray.mqh>
|
Debido al hecho de que encontrar una orden (transacción o posición) en el entorno de trading puede fallar por diversas razones, la clase tiene una variable reservada ready en la que las clases derivadas tendrán que escribir una señal de inicialización de éxito, es decir, la elección de un objeto para leer sus propiedades.
Varios métodos puramente virtuales declaran el acceso a propiedades de los tipos correspondientes.
virtual long get(const I property) const = 0;
|
En los tres primeros métodos, el tipo de propiedad se especifica mediante uno de los parámetros de la plantilla. En otros tres métodos, el tipo se especifica mediante el segundo parámetro del propio método: esto es necesario porque los últimos métodos no toman las constantes de una enumeración concreta, sino simplemente un número entero como primer parámetro. Por un lado, esto es conveniente para la numeración continua de identificadores (las constantes de enumeración de los tres tipos no se cruzan). Por otra parte, necesitamos otra fuente para determinar el tipo de valor, ya que el tipo devuelto por la función/método no participa en el proceso de elección de la sobrecarga pertinente.
Este enfoque le permite obtener propiedades basadas en varias entradas disponibles en el código de llamada. A continuación, crearemos clases basadas en OrderMonitor (así como en las futuras DealMonitor y PositionMonitor) para seleccionar objetos según un conjunto de condiciones arbitrarias, y allí todos estos métodos estarán en demanda.
Muy a menudo, los programas necesitan obtener una representación de cadena de cualquier propiedad; por ejemplo, para el registro. En los nuevos monitores, esto se implementa mediante los métodos stringify. Obviamente, obtienen los valores de las propiedades solicitadas a través de las llamadas a los métodos get mencionados anteriormente.
virtual string stringify(const long v, const I property) const = 0;
|
El único método que no ha recibido implementación es la primera versión de stringify para el tipo long. Esto se debe al hecho de que el grupo de propiedades de enteros, como vimos en la sección anterior, en realidad contienen diferentes tipos de aplicaciones, incluyendo fecha y hora, enumeraciones y enteros. Por lo tanto, sólo las clases derivadas pueden proporcionar su conversión a cadenas comprensibles. Esta situación es común a todas las entidades de trading, no sólo a las órdenes, sino también a las transacciones y posiciones, cuyas propiedades estudiaremos más adelante.
Cuando una propiedad de enteros contiene un elemento de enumeración (por ejemplo, ENUM_ORDER_TYPE, ORDER_TYPE_FILLING, etc.), debe utilizar la función EnumToString para convertirla en una cadena. Esta tarea se realiza por medio de un método auxiliar enumstr. Pronto veremos su uso generalizado en clases específicas de monitores, empezando por OrderMonitor tras un par de párrafos.
template<typename E>
|
Para registrar todas las propiedades de un tipo determinado, hemos creado el método list2log que utiliza stringify en un bucle.
template<typename E>
|
Por último, para facilitar el registro de las propiedades de los tres grupos, existe un método print que llama a list2log tres veces para cada grupo de propiedades.
virtual void print() const
|
Teniendo a nuestra disposición una clase de plantilla base MonitorInterface, describimos OrderMonitorInterface, donde especificamos ciertos tipos de enumeración para las órdenes de la sección anterior y proporcionamos una implementación de stringify para las propiedades de enteros de las órdenes.
class OrderMonitorInterface:
|
La macro STR_TIME_MSC para mostrar el tiempo en milisegundos se define como sigue:
#define STR_TIME_MSC(T) (TimeToString((T) / 1000, TIME_DATE | TIME_SECONDS) \
|
Ahora estamos listos para describir la clase final para leer las propiedades de cualquier orden: OrderMonitor derivada de OrderMonitorInterface. El ticket de la orden se pasa al constructor, y se selecciona en el entorno de trading mediante OrderSelect.
class OrderMonitor: public OrderMonitorInterface
|
La parte principal de trabajo del monitor consiste en redefiniciones de funciones virtuales para la lectura de propiedades. Aquí vemos las llamadas a las funciones OrderGetInteger, OrderGetDouble y OrderGetString.
virtual long get(const ENUM_ORDER_PROPERTY_INTEGER property) const override
|
Este fragmento de código se presenta de forma abreviada: se han eliminado de él los operadores para trabajar con órdenes en el historial. Veremos el código completo de OrderMonitor más adelante, cuando exploremos este aspecto en las secciones siguientes.
Es importante señalar que el objeto monitor no almacena copias de sus propiedades. Por lo tanto, el acceso a los métodos get debe realizarse inmediatamente después de la creación del objeto y, en consecuencia, la llamada OrderSelect. Para leer las propiedades en un período posterior, tendrá que volver a asignar la orden en la caché interna del programa MQL, por ejemplo, llamando al método refresh.
void refresh()
|
Probemos el funcionamiento de OrderMonitor añadiéndolo al Asesor Experto MarketOrderSend.mq5. Una nueva versión llamada MarketOrderSendMonitor.mq5 conecta el archivo OrderMonitor.mqh mediante la directiva #include, y en el cuerpo de la función OnTimer (en el bloque de confirmación exitosa de apertura de una posición en una orden) crea un objeto monitor y llama a su método print.
#include <MQL5Book/OrderMonitor.mqh>
|
En el registro, deberíamos ver nuevas líneas que contienen todas las propiedades de la orden.
OK Order: #=1287846602
|
La cuarta línea inicia la salida del método print, que incluye el nombre completo del objeto monitor MonitorInterface junto con los tipos de parámetros (en este caso, triple ENUM_ORDER_PROPERTY) y, a continuación, todas las propiedades de una orden concreta.
No obstante, la impresión de propiedades no es la acción más interesante que puede ofrecer un monitor. La tarea de seleccionar ordenes por condiciones (valores de propiedades arbitrarias) es mucho más demandada entre los Asesores Expertos. Utilizando el monitor como herramienta auxiliar, crearemos un mecanismo de filtrado de órdenes similar al que hemos hecho para los símbolos: SymbolFilter.mqh pertinente.