- 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
Solicitar validación: OrderCheck
Para realizar cualquier operación de trading, el programa MQL debe rellenar primero la estructura MqlTradeRequest con los datos necesarios. Antes de enviarla al servidor mediante funciones de trading, tiene sentido comprobar su corrección formal y evaluar las consecuencias de la solicitud; en concreto, la cantidad de margen que se requerirá y los fondos libres restantes. Esta comprobación la realiza la función OrderCheck.
bool OrderCheck(const MqlTradeRequest &request, MqlTradeCheckResult &result)
Si no hay fondos suficientes o si los parámetros se rellenan incorrectamente, la función devuelve false. Además, la función también reacciona con un rechazo cuando se desactiva el trading, tanto en el terminal en su conjunto como para un programa específico. Para el código de error, compruebe el campo retcode de la estructura result.
La comprobación satisfactoria de la estructura request y el entorno de trading finaliza con el estado true; sin embargo, esto no garantiza que la operación solicitada vaya a tener éxito con toda seguridad si se repite utilizando las funciones OrderSend o OrderSendAsync. Las condiciones de trading pueden cambiar entre llamadas o el bróker del servidor puede tener ajustes aplicados para un sistema de trading externo específico que no puedan satisfacerse en el algoritmo de verificación formal que realiza OrderCheck.
Para obtener una descripción del resultado financiero previsto, debe analizar los campos de la estructura result.
A diferencia de la función OrderCalcMargin, que calcula el margen estimado necesario para una única posición u orden propuesta, OrderCheck tiene en cuenta, aunque de modo simplificado, el estado general de la cuenta de trading. Así, rellena el campo margin de la estructura MqlTradeCheckResult y otros campos relacionados (margin_free, margin_level) con variables acumulativas que se formarán tras la ejecución de la orden. Por ejemplo, si una posición ya está abierta para cualquier instrumento en el momento de la llamada a OrderCheck y la solicitud que se está comprobando aumenta la posición, el campo margin reflejará el importe del depósito, incluidas las obligaciones de margen anteriores. Si la nueva orden contiene una operación en sentido opuesto, el margen no aumentará (en realidad, debería disminuir, porque una posición debería cerrarse completamente en una cuenta de compensación y el margen de cobertura debería aplicarse para posiciones opuestas en una cuenta de cobertura; sin embargo, la función no realiza cálculos tan precisos).
En primer lugar, OrderCheck es útil para los programadores que se encuentran en la fase inicial de familiarización con la API de trading, a fin de experimentar con las solicitudes sin enviarlas al servidor.
Vamos a probar el rendimiento de la función OrderCheck utilizando un simple Asesor Experto no de trading CustomOrderCheck.mq5. Lo hemos convertido en un Asesor Experto y no en un script para facilitar su uso: de esta manera permanecerá en el gráfico después de ser lanzado con la configuración actual, que se puede editar fácilmente cambiando los parámetros de entrada individuales. Con un script, tendríamos que empezar de nuevo configurando los campos cada vez a partir de los valores por defecto.
Para ejecutar la comprobación, pongamos un temporizador en OnInit.
void OnInit()
|
En cuanto al manejador del temporizador, el algoritmo principal se implementará allí. Al principio cancelamos el temporizador ya que necesitamos que el código se ejecute una vez, y luego esperamos a que el usuario cambie los parámetros.
void OnTimer()
|
Los parámetros de entrada del Asesor Experto repiten completamente el conjunto de campos de la estructura de solicitud de operación.
input ENUM_TRADE_REQUEST_ACTIONS Action = TRADE_ACTION_DEAL;
|
Muchos de ellos no afectan a la comprobación ni a los resultados financieros, pero se dejan para que pueda estar seguro de ello.
Por defecto, el estado de las variables corresponde a la solicitud de abrir una posición con el lote mínimo del instrumento actual. En concreto, el parámetro Type sin inicialización explícita obtendrá el valor 0, que es igual al miembro ORDER_TYPE_BUY de la estructura ENUM_ORDER_TYPE. En el parámetro Action, especificamos una inicialización explícita porque 0 no corresponde a ningún elemento de la enumeración ENUM_TRADE_REQUEST_ACTIONS (el primer elemento de TRADE_ACTION_DEAL es 1).
void OnTimer()
|
Completemos la estructura. Los robots reales normalmente sólo necesitan asignar unos pocos campos, pero como esta prueba es genérica, debemos asegurarnos de que se pasen todos los parámetros que introduzca el usuario.
request.action = Action;
|
Tenga en cuenta que aquí aún no normalizamos precios ni lotes, aunque ello es necesario en el programa real. Así, esta prueba permite introducir valores «desiguales» y asegurarse de que conducen a un error. En los siguientes ejemplos se activará la normalización.
A continuación, llamamos a OrderCheck y registramos las estructuras request y result. Sólo nos interesa el campo retcode de este último, por lo que se imprime adicionalmente con «descifrado» como texto, macro TRCSTR (TradeRetcode.mqh). También puede analizar un campo de cadena comment, pero su formato puede cambiar para que sea más adecuado para mostrarlo al usuario.
ResetLastError();
|
La salida de estructuras la proporciona una función auxiliar StructPrint basada en ArrayPrint. Por ello, seguiremos obteniendo una visualización «en bruto» de los datos. En concreto, los elementos de las enumeraciones se representan mediante números «tal cual». Más adelante desarrollaremos una función para que la salida de la estructura de MqlTradeRequest sea más transparente (fácil de usar) (véase TradeUtils.mqh).
Para facilitar el análisis de los resultados, al principio de la función OnTimer mostraremos el estado actual de la cuenta, y al final, para comparar, calcularemos el margen para una operación de trading determinada utilizando la función OrderCalcMargin.
void OnTimer()
|
A continuación se muestra un ejemplo de registros para XAUUSD con la configuración predeterminada:
AccountInfoDouble(ACCOUNT_EQUITY)=15565.22 / ok AccountInfoDouble(ACCOUNT_PROFIT)=0.0 / ok AccountInfoDouble(ACCOUNT_MARGIN)=0.0 / ok AccountInfoDouble(ACCOUNT_MARGIN_FREE)=15565.22 / ok AccountInfoDouble(ACCOUNT_MARGIN_LEVEL)=0.0 / ok OrderCheck(request,result)=true / ok [action] [magic] [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] » 1 0 0 "XAUUSD" 0.01 1899.97 0.00 0.00 0.00 0 0 » » [type_filling] [type_time] [expiration] [comment] [position] [position_by] [reserved] » 0 0 1970.01.01 00:00:00 "" 0 0 0 OK_0 [retcode] [balance] [equity] [profit] [margin] [margin_free] [margin_level] [comment] [reserved] 0 15565.22 15565.22 0.00 19.00 15546.22 81922.21 "Done" 0 OrderCalcMargin(Type,symbol,volume,price,margin)=true / ok margin=19.0 / ok |
En el siguiente ejemplo se muestra una estimación del aumento previsto del margen en la cuenta, en la que ya existe una posición abierta que vamos a doblar.
AccountInfoDouble(ACCOUNT_EQUITY)=9999.540000000001 / ok AccountInfoDouble(ACCOUNT_PROFIT)=-0.83 / ok AccountInfoDouble(ACCOUNT_MARGIN)=79.22 / ok AccountInfoDouble(ACCOUNT_MARGIN_FREE)=9920.32 / ok AccountInfoDouble(ACCOUNT_MARGIN_LEVEL)=12622.49431961626 / ok OrderCheck(request,result)=true / ok [action] [magic] [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] » 1 0 0 "PLZL.MM" 1.0 12642.0 0.0 0.0 0.0 0 0 » » [type_filling] [type_time] [expiration] [comment] [position] [position_by] [reserved] » 0 0 1970.01.01 00:00:00 "" 0 0 0 OK_0 [retcode] [balance] [equity] [profit] [margin] [margin_free] [margin_level] [comment] [reserved] 0 10000.87 9999.54 -0.83 158.26 9841.28 6318.43 "Done" 0 OrderCalcMargin(Type,symbol,volume,price,margin)=true / ok margin=79.04000000000001 / ok |
Pruebe a cambiar cualquier parámetro de la solicitud y compruebe si la solicitud tiene éxito. Las combinaciones incorrectas de parámetros provocarán códigos de error de la lista estándar, pero como hay muchas más opciones no válidas que reservadas (los errores más comunes), la función puede devolver a menudo el código genérico TRADE_RETCODE_INVALID (10013). A este respecto, se recomienda que emplee sus propias comprobaciones de estructura con un mayor grado de diagnóstico.
Al enviar solicitudes reales al servidor se utiliza el mismo código TRADE_RETCODE_INVALID en diversas circunstancias imprevistas; por ejemplo, al intentar reeditar una orden cuya operación de modificación ya se ha iniciado (pero aún no ha finalizado) en el sistema de trading externo.