Descargar MetaTrader 5

Recetas MQL5 - procesamiento del evento TradeTransaction

18 septiembre 2014, 08:31
Dennis Kirichenko
0
408

Introducción

En este artículo me gustaría familiarizar al lector con uno de los métodos para controlar eventos comerciales con los medios de MQL5. Me gustaría decir de primeras que ya se han dedicado artículos a este tema, por ejemplo "Procesando los eventos de transacciones en el Expert Advisor por medio de la función OnTrade()". Pero a diferencia del material que acabamos de mencionar, yo utilizaré otro procesador, el OnTradeTransaction().

Me gustaría destacar el momento siguiente. En la versión actual del lenguaje MQL5, formalmente hay 14 procesadores de eventos del terminal de cliente. Además, el programador tiene la posibilidad de crear sus eventos personalizados mediante EventChartCustom() y procesarlos con ayuda de OnChartEvent(). Pero en ningún lugar de la Documentación se hace referencia a un término tal como «programación dirigida por eventos» (PED). Y es que precisamente teniendo en cuenta los principios de la PED se crea cualquier programa de MQL5. Tome cualquier plantilla de un futuro asesor, cuando en el paso «Procesadores de eventos para el asesor» se le propone al usuario que elija.

Resulta obvio que en MQL5, de una u otra forma, se utiliza un mecanismo de programación dirigida por eventos. En el lenguaje pueden haber bloques de programa que consten de dos partes: elección de evento y procesamiento de evento. Además, si se trata de eventos del terminal de cliente, entonces el programador solo tiene disponible la segunda parte, el procesador de eventos. Es cierto que para algunos eventos hay excepciones. A dichas excepciones pertenecen el temporizador y los eventos personalizados. El control de dichos eventos se cede por completo a los programadores.


1. Evento TradeTransaction

Y bien, vamos a reducir el objeto de nuestra atención al tema que ya hemos mencionado, recurramos a infomación oficial.

De acuerdo con la Documentación, el evento TradeTransaction es el resultado de la ejecución de determinadas acciones con la cuenta comercial. La propia acción consta de varias etapas, que son determinadas por las transacciones. Por ejemplo, una de las acciones más populares con la cuenta comercial - la apertura de posición mediante una orden de mercado - se realiza de la siguiente forma:

  1. Crear una orden comercial;
  2. Comprobar una orden comercial;
  3. Enviar la orden comercial al servidor;
  4. Obtener una respuesta sobre la ejecución de la orden comercial en el servidor.

Pero una secuencia así refleja más bien la lógica de trabajo de las conexiones terminal-servidor, lo cual se expresa en las líneas de código del asesor. Desde el punto de vista del evento comercial TradeTransaction, la apertura de posición según el mercado tiene lugar de la forma siguiente:

  1. El programa MQL5 recibe la notificación del servidor sobre el resultado de la realización de la solicitud;
  2. La solicitud en forma de orden, con un tiquet único, entra en la lista de órdenes abiertas;
  3. Tras ejecutarse, la orden es eliminada de la lista de órdenes abiertas;
  4. Después la orden pasa al historial;
  5. En la historia aparece la operación que constituye el resultado de la ejecución de la orden.

Al final, para abrir una posición se necesitaron 5 llamadas del procesador OnTradeTransaction().

Algo más tarde nos ocuparemos del código del programa, pero por ahora propongo dedicarnos al encabezado de la función-procesadora. Tiene 3 parámetros de entrada.

void  OnTradeTransaction(
   const MqlTradeTransaction&    trans,        // estructura de la transacción comercial
   const MqlTradeRequest&        request,      // estructura de la petitición
   const MqlTradeResult&         result        // estructura de la respuesta
   );

Hay información detallada sobre los parámetros en la Documentación. Me gustaría destacar aquí que el parámetro de la estructura de la transacción comercial es una especie de molde de la información que el procesador de la transacción pudo recibir en la llamada actual.

Pienso que hay que decir unas cuantas palabras más sobre el tipo de transacción comercial, ya que nos lo encontraremos con frecuencia.

En el lenguaje MQL5 hay una enumeración especial, responsable del tipo de transacción comercial, la ENUM_TRADE_TRANSACTION_TYPE. Para saber a qué tipo pertenece esta u otra transacción comercial, hay que recurrir al parámetro-constante del tipo MqlTradeTransaction.

struct MqlTradeTransaction
  {
   ulong                         deal;             // Tipo de operación
   ulong                         order;            // Tiquet de la orden
   string                        symbol;           // Nombre del instrumento comercial
   ENUM_TRADE_TRANSACTION_TYPE   type;             // Tipo de transacción comercial
   ENUM_ORDER_TYPE               order_type;       // Tipo de orden
   ENUM_ORDER_STATE              order_state;      // Estado de la orden
   ENUM_DEAL_TYPE                deal_type;        // Tipo de operación
   ENUM_ORDER_TYPE_TIME          time_type;        // Tipo de orden según su duración
   datetime                      time_expiration;  // Tiempo de expiración de la orden
   double                        price;            // Precio 
   double                        price_trigger;    // Precio de activación de la orden stop-limit
   double                        price_sl;         // Nivel de Stop Loss
   double                        price_tp;         // Nivel de Take Profit
   double                        volume;           // Volumen en lotes
  };

El cuarto campo de la estructura es precisamente la enumeración buscada.


2. Procesamiento de la posición

Prácticamente todas los operaciones comerciales que están relacionadas con el procesamiento de las posiciones conllevan 5 llamadas del procesador OnTradeTransaction(). A este tipo de operaciones pertenecen:

  • la apertura de posición;
  • las posiciones;
  • el viraje de posición;
  • el añadido a una posición;
  • la abreviación de una posición.

Solo una operación, la modificación de posición, llamará al procesador TradeTransactiondos veces.

Dado que en la documentación no hay información sobre qué tipo de transacciones son responsables de ciertos tipos concretos de acciones comerciales, podemos ponerlas a prueba independientemente con el método de prueba y error.

De manera preliminar habrá que crear la plantilla del futuro asesor, en el que debe estar presente necesariamente el procesador de eventos TradeTransaction. He llamado a mi versión de ese tipo de plantilla TradeProcessor.mq5. Le he añadido la posibilidad de mostrar información en el registro sobre los valores de los campos de estructura que sean parámetros de la función-desarrolladora. Con estas anotaciones habra que traérselas tiesas, como se dice, mientras las estemos analizando. Sin embargo, compensaremos los gastos posteriormente, ya que será posible ver la imagen general de lo que sucede.

En cualquier gráfico del terminal MetaTrader 5 hay que poner en marcha el asesor en el modo de depuración.

Abrimos de manera manual la posición y echamos un vistazo al código. La primera llamada del procesador será así (fig. 1).

Figura 1. El campo type es igual a TRADE_TRANSACTION_REQUEST

Fig. 1. El campo type es igual a TRADE_TRANSACTION_REQUEST

En el registro aparecerán las siguientes anotaciones:

IO      0       17:37:53.233    TradeProcessor (EURUSD,H1)      ---===Transacción===---
NK      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Tiquet de la operación: 0
RR      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Tipo de operación: DEAL_TYPE_BUY
DE      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Tiquet de la orden: 0
JS      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Estado de la orden: ORDER_STATE_STARTED
JN      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Tipo de la orden: ORDER_TYPE_BUY
FD      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Precio: 0.0000
FN      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Nivel de Stop Loss: 0.0000
HF      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Nivel de Take Profit: 0.0000
FQ      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Precio de activación de la orden stop-limit: 0.0000
RR      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Instrumento comercial: 
HD      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Fecha de expiración de la orden pendiente: 1970.01.01 00:00
GS      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Tipo de orden según el tiempo de duración: ORDER_TIME_GTC
DN      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Tipo de transacción comercial: TRADE_TRANSACTION_REQUEST
FK      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Volumen en lotes: 0.00

En este bloque resulta interesante solo la anotación que está relacionada con el tipo de transacción. Vemos que el tipo se refería a la petición (TRADE_TRANSACTION_REQUEST).

En el bloque «Petición» podemos obtener información sobre los detalles de la solicitud.

QG      0       17:37:53.233    TradeProcessor (EURUSD,H1)      ---===Petición===--- HL      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Tipo de acción ejecutada: TRADE_ACTION_DEAL EE      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Cometarios a la orden: JP      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Desviación con respecto al precio solicitado: 0 GS      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Plazo de expiración de la orden: 1970.01.01 00:00 LF      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Mágico del asesor: 0 FM      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Tiquet de la orden: 22535869 EJ      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Precio: 1.3137 QR      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Nivel de la orden Stop Loss: 0.0000 IJ      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Nivel de la orden Take Profit: 0.0000 KK      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Nivel de la orden StopLimit: 0.0000 FS      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Instrumento comercial: EURUSD RD      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Tipo de orden: ORDER_TYPE_BUY

Al bloque «Respuesta» llegarán los datos sobre el resultado de la ejecución de la solicitud.

KG      0       17:37:53.233    TradeProcessor (EURUSD,H1)      ---===Respuesta===---
JR      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Código del resultado de la operación: 10009
GD      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Tiquet de la operación: 15258202
NR      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Tiquet de la orden: 22535869
EF      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Volumen de la operación: 0.11
MN      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Precio en la operación: 1.3137
HJ      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Precio de la demanda: 1.3135
PM      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Precio de la oferta: 1.3137
OG      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Comentarios sobre la operación: 
RQ      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Identificador de la petición: 1

Precisamente en la primera llamada se puede conocer información adicional sobre la petición, analizando otros parámetros del procesador, las estructuras de la petición y la respuesta.

La segunda llamada del procesador se refiere a la adición de la orden a la lista de órdenes abiertas (fig. 2).

Fig.2. El campo type es igual a TRADE_TRANSACTION_ORDER_ADD

Fig.2. El campo type es igual a TRADE_TRANSACTION_ORDER_ADD

En el registro solo resulta de interés el bloque «Transacción».

MJ      0       17:41:12.280    TradeProcessor (EURUSD,H1)      ---===Transacción===---
JN      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Tiquet de la operación: 0
FG      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Tipo de operación: DEAL_TYPE_BUY
LM      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Tiquet de la orden: 22535869
LI      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Estado de la orden: ORDER_STATE_STARTED
LP      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Tipo de orden: ORDER_TYPE_BUY
QN      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Precio: 1.3137
PD      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Nivel de Stop Loss: 0.0000
NL      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Nivel de Take Profit: 0.0000
PG      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Precio de activación de la orden stop-limit: 0.0000
DL      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Instrumento comercial: EURUSD
JK      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Plazo de expiración de la orden pendiente: 1970.01.01 00:00
QD      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Tipo de orden según el tiempo de acción: ORDER_TIME_GTC
IQ      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Tipo de transacción comercial: TRADE_TRANSACTION_ORDER_ADD
PL      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Volumen en lotes: 0.11

Aquí podemos ver que la orden ya ha obtenido su tiquet y los parámetros por el estilo (símbolo, precio, volumen), y se encuentra en la lista de órdenes abiertas.

La tercera llamada del procesador está relacionada con la eliminación de la orden de la lista de órdenes abiertas (fig. 3).

Fig.3. El campo type es igual a TRADE_TRANSACTION_ORDER_DELETE

Fig.3. El campo type es igual a TRADE_TRANSACTION_ORDER_DELETE

En el registro solo resulta de interés el bloque «Transacción».

PF      0       17:52:36.722    TradeProcessor (EURUSD,H1)      ---===Transacción===---
OE      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Tiquet de la operación: 0
KL      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Tipo de operación: DEAL_TYPE_BUY
EH      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Tiquet de la orden: 22535869
QM      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Estado de la orden: ORDER_STATE_STARTED
QK      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Tipo de orden: ORDER_TYPE_BUY
HS      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Precio: 1.3137
MH      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Nivel de Stop Loss: 0.0000
OP      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Nivel de Take Profit: 0.0000
EJ      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Precio de activación de la orden stop-limit: 0.0000
IH      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Instrumento comercial: EURUSD
KP      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Plazo de expiración de la orden pendiente: 1970.01.01 00:00
LO      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Tipo de orden según el tiempo de acción: ORDER_TIME_GTC
HG      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Tipo de transacción comercial: TRADE_TRANSACTION_ORDER_DELETE
CG      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Volumen en lotes: 0.11

Aquí no hay nada nuevo, excepto el tipo de transacción.

El procesador se llama por cuarta vez cuando en la historia aparece una orden «histórica» nueva (fig. 4).

Fig.4. El campo type es igual a TRADE_TRANSACTION_HISTORY_ADD

Fig.4. El campo type es igual a TRADE_TRANSACTION_HISTORY_ADD

Veamos el registro en el bloque «Transacción».

QO      0       17:57:32.234    TradeProcessor (EURUSD,H1)      ---===Transacción===---
RJ      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Tiquet de la operación: 0
NS      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Tipo de operación: DEAL_TYPE_BUY
DQ      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Tiquet de la orden: 22535869
EH      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Estado de la orden: ORDER_STATE_FILLED
RL      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Tipo de orden: ORDER_TYPE_BUY
KJ      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Precio: 1.3137
NO      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Nivel de Stop Loss: 0.0000
PI      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Nivel de Take Profit: 0.0000
FS      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Precio de activación de la orden stop-limit: 0.0000
JS      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Instrumento comercial: EURUSD
LG      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Plazo de expiración de la orden pendiente: 1970.01.01 00:00
KP      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Tipo de orden según el tiempo de acción: ORDER_TIME_GTC
OL      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Tipo de transacción comercial: TRADE_TRANSACTION_HISTORY_ADD
JH      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Volumen en lotes: 0.00

En esta etapa vemos que la orden ha sido ejecutada.

Por última (y quinta) vez tiene lugar la llamada al añadir una operación a la historia (fig. 5).

Fig.5. El campo type es igual a TRADE_TRANSACTION_DEAL_ADD

Fig.5. El campo type es igual a TRADE_TRANSACTION_DEAL_ADD

En el registro de nuevo solo miramos el bloque «Transacción».

OE      0       17:59:40.718    TradeProcessor (EURUSD,H1)      ---===Transacción===---
MS      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Tiquet de la operación: 15258202
RJ      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Tipo de operación: DEAL_TYPE_BUY
HN      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Tiquet de la orden: 22535869
LK      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Estado de la orden: ORDER_STATE_STARTED
LE      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Tipo de orden: ORDER_TYPE_BUY
MM      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Precio: 1.3137
PF      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Nivel de Stop Loss: 0.0000
NN      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Nivel de Take Profit: 0.0000
PI      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Precio de activación de la orden stop-limit: 0.0000
DJ      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Instrumento comercial: EURUSD
JM      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Plazo de expiración de la orden pendiente: 1970.01.01 00:00
QI      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Tipo de orden según el tiempo de acción: ORDER_TIME_GTC
CK      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Tipo de transacción comercial: TRADE_TRANSACTION_DEAL_ADD
RQ      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Volumen en lotes: 0.11

Un punto importante aquí es el tiquet de la operación.

Adjunto las plantillas de las conexiones de los tipos de transacción. Para las posiciones serán dos en total. La primera tiene el aspecto siguiente (fig. 6).

Fig.6. Primera plantilla de conexiones de los tipos de transacción

Fig.6. Primera plantilla de conexiones de los tipos de transacción


A esta plantilla se subordinan todas las operaciones comerciales relacionadas con el procesamiento de la posición, excepto una sola, la modificación de posición. La última operación incluye entre sus componentes el procesamiento de las dos transacciones siguientes (fig. 7).

Fig.7. Segunda plantilla de conexiones de los tipos de transacción

Fig.7. Segunda plantilla de conexiones de los tipos de transacción

De esta forma, no es posible realizar un seguimiento de la modificación de posición en la historia de órdenes y operaciones.

En general, esto es todo en lo que respecta a las posiciones.



3. Procesamiento de órdenes pendientes

En lo que respecta a las órdenes pendientes, hay que destacar que se invierte un menor número de transacciones a la hora de operar con ellas. Pero, por otra parte, al trabajar con órdenes hay más combinaciones de tipos de transacciones.

Al modificar una orden, como en el caso de la modificación de la posición, se llamará dos veces al procesador. Aparecerán tres llamadas al establecer y cancelar una orden. El evento TradeTransaction ocurrirá cuatro veces al eliminar una orden o al activarse la misma.

Probemos a establecer una orden pendiente. En cualquier gráfico del terminal MetaTrader 5 hay que poner en marcha de nuevo el asesor en el modo de depuración.

La primera llamada del procesador estará relacionada con la petición (fig. 8).

Fig.8. El campo type es igual a TRADE_TRANSACTION_REQUEST

Fig.8. El campo type es igual a TRADE_TRANSACTION_REQUEST

En el registro veremos las anotaciones siguientes:

IO      0       18:13:33.195    TradeProcessor (EURUSD,H1)      ---===Transacción===---
NK      0       18:13:33.195    TradeProcessor (EURUSD,H1)     Tiquet de la operacion: 0
RR      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Tipo de operación: DEAL_TYPE_BUY
DE      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Tiquet de la orden: 0
JS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Estado de la orden: ORDER_STATE_STARTED
JN      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Tipo de orden: ORDER_TYPE_BUY
FD      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Precio: 0.0000
FN      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Nivel de Stop Loss: 0.0000
HF      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Nivel de Take Profit: 0.0000
FQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Precio de activación de la orden stop-limit: 0.0000
RR      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Instrumento comercial: 
HD      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Plazo de expiración de la orden pendiente: 1970.01.01 00:00
GS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Tipo de orden según el tiempo de acción: ORDER_TIME_GTC
DN      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Tipo de transacción comercial: TRADE_TRANSACTION_REQUEST
FK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Volumen en lotes: 0.00
NS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      

QG      0       18:13:33.195    TradeProcessor (EURUSD,H1)      ---===Petición===---
IQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Tipo de acción realizada: TRADE_ACTION_PENDING
OE      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Comentarios a la orden: 
PQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Desviación con respecto al precio requerido: 0
QS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Plazo de expiración de la orden: 1970.01.01 00:00
FI      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Mágico del asesor: 0
CM      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Tiquet de la orden: 22535983
PK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Precio: 1.6500
KR      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Nivel de la orden Stop Loss: 0.0000
OI      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Nivel de la ordenTake Profit: 0.0000
QK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Nivel de la orden StopLimit: 0.0000
QQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Instrumento comercial: GBPUSD
RD      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Tipo de orden: ORDER_TYPE_BUY_LIMIT
LS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Tipo de orden según la ejecución: ORDER_FILLING_RETURN
MN      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Tipo de orden según el tiempo de acción: ORDER_TIME_GTC
IK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Volumen en lotes: 0.14
NS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      
CD      0       18:13:33.195    TradeProcessor (EURUSD,H1)      ---===Respuesta===---
RQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Código del resultado de la operación: 10009
JI      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Tiquet de la operación: 0
GM      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Tiquet de la orden: 22535983
LF      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Volumen de la operación: 0.14
JN      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Precio en la operación: 0.0000
MK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Precio de demanda: 0.0000
CM      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Precio de oferta: 0.0000
IG      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Comentarios a la operación: 
DQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Identificador de la petición: 1

La segunda llamada al procesador añade la orden a la lista de órdenes abiertas (fig. 9).

Fig.9. El campo type es igual a TRADE_TRANSACTION_ORDER_ADDED

Fig.9. El campo type es igual a TRADE_TRANSACTION_ORDER_ADDED

En el registro solo nos interesa el bloque «Transacción».

HJ      0       18:17:02.886    TradeProcessor (EURUSD,H1)      ---===Transacción===---
GQ      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Tiquet de la operación: 0
CH      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Tipo de operación: DEAL_TYPE_BUY
RL      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Tiquet de la orden: 22535983
II      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Estado de la orden: ORDER_STATE_STARTED
OG      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Tipo de orden: ORDER_TYPE_BUY_LIMIT
GL      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Precio: 1.6500
IE      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Nivel de Stop Loss: 0.0000
CO      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Nivel de Take Profit: 0.0000
IF      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Precio de activación de la orden stop-limit: 0.0000
PL      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Instrumento comercial: GBPUSD
OL      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Plazo de expiración de la orden pendiente: 1970.01.01 00:00
HJ      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Tipo de orden según tiempo de acción: ORDER_TIME_GTC
LF      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Tipo de transacción comercial: TRADE_TRANSACTION_ORDER_ADD
FR      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Volumen en lotes: 0.14

La tercera llamada del procesador actualiza los datos sobre la orden establecida (fig. 10).

En concreto, el estado de la orden obtiene el valor ORDER_STATE_PLACED.

Fig.10. El campo type es igual a TRADE_TRANSACTION_ORDER_UPDATE

Fig.10. El campo type es igual a TRADE_TRANSACTION_ORDER_UPDATE

En el registro veremos las anotaciones sobre el bloque «Transacciones».

HS      0       18:21:27.004    TradeProcessor (EURUSD,H1)      ---===Transacción===---
GF      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Tiquet de la operación: 0
CO      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Tipo de operación: DEAL_TYPE_BUY
RE      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Tiquet de la orden: 22535983
KM      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Estado de la orden: ORDER_STATE_PLACED
QH      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Tipo de orden: ORDER_TYPE_BUY_LIMIT
EG      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Precio: 1.6500
GL      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Nivel de Stop Loss: 0.0000
ED      0       18:21:27.004    TradeProcessor (EURUSD,H1)      NIvel de Take Profit: 0.0000
GO      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Precio de activación de la orden stop-limit: 0.0000
RE      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Instrumento comercial: GBPUSD
QS      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Plazo de expiración de la orden pendiente: 1970.01.01 00:00
JS      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Tipo de orden según el tiempo de acción: ORDER_TIME_GTC
RD      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Tipo de transacción comercial: TRADE_TRANSACTION_ORDER_UPDATE
JK      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Volumen en lotes: 0.14

Una línea muy importante aquí es la del estado de la orden.

A diferencia de las posiciones, las órdenes pendientes, o más bien su procesamiento, no se pueden adaptar a una plantilla. Cada acción comercial relacionada con una orden pendiente será única desde el punto de vista del conjunto de tipos de transacciones comerciales.

Para el establecimiento de una orden pendiente será necesario realizar 3 transacciones (fig. 11).

Fig.11. Transacciones que procesan la creación de una orden pendiente

Fig.11. Transacciones que procesan la creación de una orden pendiente

La modificación de una orden pendiente generará 2 transacciones (fig. 12).

Fig.12 Transacciones que procesan el cambio de una orden pendiente

Fig.12. Transacciones que procesan el cambio de una orden pendiente


Si es necesario eliminar una orden pendiente, enotnces el procesador OnTradeTransaction() será llamado 4 veces (fig. 13).

Fig.13. Transacciones que procesan la eliminación de una orden pendiente

Fig.13. Transacciones que procesan la eliminación de una orden pendiente

La cancelación de una orden pendiente tiene lugar según el siguiente esquema (fig. 14).

Fig.14. Transacciones que procesan la cancelación de una orden pendiente

Fig.14. Transacciones que procesan la cancelación de una orden pendiente


Y la última operación comercial - la activación de una orden pendiente - da lugar a 4 transacciones diferentes (fig. 15).

Fig.15. Transacciones que procesan la activación de una orden pendiente

Fig.15. Transacciones que procesan la activación de una orden pendiente

No voy a mostrar anotaciones del registro sobre cada combinación de las transacciones. Si así lo desea el lector, puede estudiarlas por sí mismo, poniendo en marcha el código para su ejecución.


4. Procesador universal

Vamos a ver con los ojos del usuairio final un programa que sabe cómo trabajar con el evento TradeTransaction. Seguramente, el usuario necesitará justamente aquel que pueda trabajar bien tanto con órdenes, como con posiciones. Entones el programador debe escribir el código para el procesador OnTradeTransaction() de tal forma que el último sepa identificar todas las transacciones y sus combinaciones, independientemente de qué sea lo que se ha procesado, una orden o una posición. Además, es preferible que al terminar el procesamiento de la serie de transacciones, el programa pueda decir qué operación comercial se ha ejecutado.

En mi ejemplo se usa el procesamiento consecutivo de transacciones. Sin embargo, un desarrollador del lenguaje MQL5 afirma lo siguiente:

...Una petición comercial enviada desde el terminal manualmente o través de las funciones comerciales OrderSend()/OrderSendAsync(), puede generar en el servidor comercial varias transacciones comerciales consecutivas. En este caso, la sucesión de llegada de estas transacciones al terminal no está garantizada, por eso no se debe construir el algoritmo comercial basándose en que vayan a llegar unas transacciones comerciales después de que lleguen otras. Además, las transacciones pueden perderse al hacerlas llegar desde el servidor al terminal...

Por eso surge la necesidad de crear algo que funcione de manera casi ideal, hay que perfeccionar el ejemplo que propongo aquí y realizar el procesamiento de las transacciones independientemente de su sucesión en la llegada.

Hablando en general, las posiciones y órdenes pueden tener tipos de transacción comunes. Hay en total 11 tipos de transacciones. De ellas, 4 tipos tienen poca relación con el comercio desde el terminal:

  • TRADE_TRANSACTION_DEAL_UPDATE;
  • TRADE_TRANSACTION_DEAL_DELETE;
  • TRADE_TRANSACTION_HISTORY_UPDATE;
  • TRADE_TRANSACTION_HISTORY_DELETE.

Sobre estos tipos no se hablará en el artículo. Estos tipos, como anuncia el desarrollador, están contemplados para ampliar la funcionalidad por parte del servidor comercial. El autor del artículo reconoce que no se ha encontrado con dichos tipos de datos.

Solo quedan 7 tipos de pleno valor, que se suelen procesar en el bloque OnTradeTransaction().

En el cuerpo del procesador ocupará un lugar importante el apartado que determina el tipo de transacción actual.

//--- ========== Tipos de transacciones [START]
   switch(trans_type)
     {
      //--- 1) si se trata de una petición
      case TRADE_TRANSACTION_REQUEST:
        {

         //---
         break;
        }
      //--- 2) si se trata de la adición de una nueva orden abierta
      case TRADE_TRANSACTION_ORDER_ADD:
        {

         //---
         break;
        }
      //--- 3) si se trata de la eliminación de una orden de la lista de órdenes abiertas
      case TRADE_TRANSACTION_ORDER_DELETE:
        {

         //---     
         break;
        }
      //--- 4) si se trata de la adición de una orden a la historia
      case TRADE_TRANSACTION_HISTORY_ADD:
        {

         //---     
         break;
        }
      //--- 5) si se trata de la adición de una operación a la historia
      case TRADE_TRANSACTION_DEAL_ADD:
        {

         //---
         break;
        }
      //--- 6) si trata de la modificación de una posición
      case TRADE_TRANSACTION_POSITION:
        {

         //---
         break;
        }
      //--- 7) si se trata del cambio de una posición abierta
      case TRADE_TRANSACTION_ORDER_UPDATE:
        {

         //---
         break;
        }
     }
//--- ========== Tipos de transacciones [END]

Dependiendo de el tipo actual de transacción, probaremos a diagnosticar la operación comercial procesada. Para determinar con qué estamos trabajando, con una posición o con una orden, encargaremos al módulo case del procesamiento de la petición recordar el tipo de operación comercial.

Entonces, ese módulo tendrá el siguiente aspecto:

//--- 1) si se trata de una petición
      case TRADE_TRANSACTION_REQUEST:
        {
         //---
         last_action=request.action;
         string action_str;

         //--- ¿una petición de qué?
         switch(last_action)
           {
            //--- а) según el mercado
            case TRADE_ACTION_DEAL:
              {
               action_str="poner una orden de mercado";
               trade_obj=TRADE_OBJ_POSITION;
               break;
              }
            //--- б) establecer una orden pendiente
            case TRADE_ACTION_PENDING:
              {
               action_str="establecer una orden pendiente";
               trade_obj=TRADE_OBJ_ORDER;
               break;
              }
            //--- в) cambiar la posición
            case TRADE_ACTION_SLTP:
              {
               trade_obj=TRADE_OBJ_POSITION;
               //---
               StringConcatenate(action_str,request.symbol,": cambiar el valor de Stop Loss",
                                 " y Take Profit");

               //---
               break;
              }
            //--- г) cambiar una orden
            case TRADE_ACTION_MODIFY:
              {
               action_str="cambiar los parámetros de una orden pendiente";
               trade_obj=TRADE_OBJ_ORDER;
               break;
              }
            //--- д) eliminar una orden
            case TRADE_ACTION_REMOVE:
              {
               action_str="eliminar una orden pendiente";
               trade_obj=TRADE_OBJ_ORDER;
               break;
              }
           }
         //---
         if(InpIsLogging)
            Print("Ha llegado una petición: "+action_str);

         //---
         break;
        }

No es complicado notar varias variables.

static ENUM_TRADE_REQUEST_ACTIONS last_action; // acción de mercado en la primera pasada

La variable last_action recordará para qué se inició el funcionamiento del procesador.

static ENUM_TRADE_OBJ trade_obj;               // establece un objeto comercial en la primera pasada

La variable trade_obj recordará qué se ha procesado, una posición o una orden. Para ello creará la enumeración ENUM_TRADE_OBJ.

A continuación, nos trasladamos al módulo que se ocuapará del procesamiento de la transacción del tipo TRADE_TRANSACTION_ORDER_ADD:

//--- 2) si se trata de la adición de una nueva orden abierta
      case TRADE_TRANSACTION_ORDER_ADD:
        {
         if(InpIsLogging)
           {
            if(trade_obj==TRADE_OBJ_POSITION)
               Print("Abrir una nueva orden de mercado: "+
                     EnumToString(trans.order_type));
            //---
            else if(trade_obj==TRADE_OBJ_ORDER)
               Print("Establecer una nueva orden pendiente: "+
                     EnumToString(trans.order_type));
           }
         //---
         break;
        }

Aquí todo es bastante sencillo. Si en el primer paso se ha procesado la posición, entonces en el paso actual aparecerá la entrada en el registro "Abrir una nueva orden de mercado: ", de lo contrario, aparecerá "Establecer una nueva orden pendiente:". Aparte de las acciones informativas, en este bloque no hay ningunas otras acciones.

Ahora echemos un vistazo al tercer módulo, el procesamiento del tipo TRADE_TRANSACTION_ORDER_DELETE:

//--- 3) si se trata de la eliminación de una orden de la lista de órdenes abiertas
      case TRADE_TRANSACTION_ORDER_DELETE:
        {
         if(InpIsLogging)
            PrintFormat("Eliminado de la lista de órdenes abiertas: #%d, "+
                        EnumToString(trans.order_type),trans.order);
         //---     
         break;
        }

El módulo, igualmente, lleva solo contenido de tipo informativo.

El cuarto módulo case procesa el tipo TRADE_TRANSACTION_HISTORY_ADD:

//--- 4) si se trata de la adición de una orden a la historia
      case TRADE_TRANSACTION_HISTORY_ADD:
        {
         if(InpIsLogging)
            PrintFormat("Se ha añadido a la historia una orden: #%d, "+
                        EnumToString(trans.order_type),trans.order);

         //--- si se procesa una orden pendiente
         if(trade_obj==TRADE_OBJ_ORDER)
           {
            //--- si se trata de la tercera pasada
            if(gTransCnt==2)
              {
               //--- si la orden ha sido cancelada, comprobar las operaciones
               datetime now=TimeCurrent();

               //--- solicitar la historia de las órdenes y posiciones
               HistorySelect(now-PeriodSeconds(PERIOD_H1),now);

               //--- intento de encontrar una orden o posición
               CDealInfo myDealInfo;
               int all_deals=HistoryDealsTotal();
               //---
               bool is_found=false;
               for(int deal_idx=all_deals;deal_idx>=0;deal_idx--)
                  if(myDealInfo.SelectByIndex(deal_idx))
                     if(myDealInfo.Order()==trans.order)
                        is_found=true;

               //---  si no se ha encontrado la operación
               if(!is_found)
                 {
                  is_to_reset_cnt=true;
                  //---
                  PrintFormat("La orden ha sido cancelada: #%d",trans.order);
                 }
              }
            //--- si se trata de la cuarta pasada
            if(gTransCnt==3)
              {
               is_to_reset_cnt=true;
               PrintFormat("La orden ha sido eliminada: #%d",trans.order);
              }
           }
         //---     
         break;
        }

En ella, además de la anotación acerca de la adición de la orden a la historia, existe la comprobación de si nos hallamos ya de por sí trabajando con una orden pendiente. De ser así, entonces comprobamos en qué pasada se encuentra el procesador actualmente. La cuestión es que este tipo de transacción puede aparecer al trabajar con una orden en la tercera pasada, si la orden pendiente ha sido cancelada o se ha activado. En la cuarta pasada este tipo puede aparecer cuando la orden pendiente sea eliminada por fuerza.

En las líneas de comprobación de la tercera pasada hay que recurrir aún a la historia de operaciones. Si para la orden actual no se va a encontrar operación, entonces tal orden se considerará cancelada.

El quinto módulo case procesa el tipo TRADE_TRANSACTION_DEAL_ADD. Se trata del mayor bloque del programa en cuanto a tamaño de líneas de código.

En él comprobamos la operación. Es importante elegir la operación según el tiquet, para obtener acceso a sus propiedades. Según el tipo de operación, se puede saber si la operación ha sido abierta, cerrada, etc. Asimismo, se puede obtener información sobre si se ha activado una orden pendiente. Este es el único caso cuando una orden pendiente puede dar lugar a una operación en el contexto de trabajo del procesador de eventos TradeTransaction.

//--- 5) si se trata de la adición de una operación a la historia
      case TRADE_TRANSACTION_DEAL_ADD:
        {
         is_to_reset_cnt=true;
         //---
         ulong deal_ticket=trans.deal;
         ENUM_DEAL_TYPE deal_type=trans.deal_type;
         //---
         if(InpIsLogging)
            PrintFormat("Se ha añadido a la historia una operación: #%d, "+EnumToString(deal_type),deal_ticket);

         if(deal_ticket>0)
           {
            datetime now=TimeCurrent();

            //--- solicitar la historia de operaciones y órdenes
            HistorySelect(now-PeriodSeconds(PERIOD_H1),now);

            //--- elegir la operacion según el tiquet
            if(HistoryDealSelect(deal_ticket))
              {
               //--- comprobar la operación
               CDealInfo myDealInfo;
               myDealInfo.Ticket(deal_ticket);
               long order=myDealInfo.Order();

               //--- parámetros de la operacion
               ENUM_DEAL_ENTRY  deal_entry=myDealInfo.Entry();
               double deal_vol=0.;
               //---
               if(myDealInfo.InfoDouble(DEAL_VOLUME,deal_vol))
                  if(myDealInfo.InfoString(DEAL_SYMBOL,deal_symbol))
                    {
                     //--- posición
                     CPositionInfo myPos;
                     double pos_vol=WRONG_VALUE;
                     //---
                     if(myPos.Select(deal_symbol))
                        pos_vol=myPos.Volume();

                     //--- si se ha realizado una entrada al mercado
                     if(deal_entry==DEAL_ENTRY_IN)
                       {
                        //--- 1) apertura de posición
                        if(deal_vol==pos_vol)
                           PrintFormat("\n%s: se ha abierto una nueva posición",deal_symbol);

                        //--- 2) adición a la posición abierta        
                        else if(deal_vol<pos_vol)
                           PrintFormat("\n%s: adición a la posición actual",deal_symbol);
                       }

                     //--- si se ha realizado una salida del mercado
                     else if(deal_entry==DEAL_ENTRY_OUT)
                       {
                        if(deal_vol>0.0)
                          {
                           //--- 1) cierre de posición
                           if(pos_vol==WRONG_VALUE)
                              PrintFormat("\n%s: posición cerrada",deal_symbol);

                           //--- 2) reducción de la posición abierta        
                           else if(pos_vol>0.0)
                              PrintFormat("\n%s: reducción de la posición actual",deal_symbol);
                          }
                       }

                     //--- si se ha dado un viraje
                     else if(deal_entry==DEAL_ENTRY_INOUT)
                       {
                        if(deal_vol>0.0)
                           if(pos_vol>0.0)
                              PrintFormat("\n%s: viraje de posición",deal_symbol);
                       }
                    }

               //--- activación de una orden
               if(trade_obj==TRADE_OBJ_ORDER)
                  PrintFormat("Activación de una orden pendiente: %d",order);
              }
           }

         //---
         break;
        }

El tipo de transacción TRADE_TRANSACTION_POSITION es único y se procesa solo cuando se modifica la posición:

//--- 6) si se trata de la modificación de una posición
      case TRADE_TRANSACTION_POSITION:
        {
         is_to_reset_cnt=true;
         //---
         PrintFormat("Modificación de posición: %s",deal_symbol);
         //---
         if(InpIsLogging)
           {
            PrintFormat("Nuevo precio stop loss: %0."+
                        IntegerToString(_Digits)+"f",trans.price_sl);
            PrintFormat("Nuevo precio take profit: %0."+
                        IntegerToString(_Digits)+"f",trans.price_tp);
           }

         //---
         break;
        }

El último módulo case se incluye durante el procesamiento del tipo TRADE_TRANSACTION_ORDER_UPDATE.

La aparición de este tipo puede estar condicionada solo por el trabajo con una orden pendiente. Además, aparece al activarse cualquier operación comercial que esté relacionada con órdenes pendientes, pero en diferentes etapas.

//--- 7) si se trata del cambio de una orden pendiente
      case TRADE_TRANSACTION_ORDER_UPDATE:
        {

         //--- si se trataba de la primera pasada
         if(gTransCnt==0)
           {
            trade_obj=TRADE_OBJ_ORDER;
            PrintFormat("Quitar la orden: #%d",trans.order);
           }
         //--- si se trataba de la segunda pasada
         if(gTransCnt==1)
           {
            //--- si se trata de la modificación de la orden
            if(last_action==TRADE_ACTION_MODIFY)
              {
               PrintFormat("Orden pendiente modificada: #%d",trans.order);
               //--- poner contador a cero
               is_to_reset_cnt=true;
              }
            //--- si se trata de la eliminación de una orden
            if(last_action==TRADE_ACTION_REMOVE)
              {
               PrintFormat("Orden pendiente eliminada: #%d",trans.order);

              }
           }
         //--- si se trataba de la tercera pasada
         if(gTransCnt==2)
           {
            PrintFormat("Nueva orden pendiente establecida: #%d, "+
                        EnumToString(trans.order_type),trans.order);
            //--- poner contador a cero
            is_to_reset_cnt=true;
           }

         //---
         break;
        }

Bien, si este tipo aparece al activarse por primera vez OnTradeTransaction(), entonces la orden, o bien ha sido cancelada, o bien se ha activado.

Si el tipo ha aparecido en la segunda activación del procesador, entonces la orden, o bien ha sido eliminada, o bien ha sido modificada. Para saber qué ha sucedido precisamente, hay que recurrir a la variable estadística last_action, que recuerda la última acción comercial.

Y el último caso en el que puede aparecer este tipo, está relacionado con la tercera activación del procesador. Este efectúa el procedimiento de establecimiento de una orden pendiente.

Es fácil percibir que en el codigo se usa la variable booleana is_to_reset_cnt. Esta actúa como bandera para poner a cero el contador de pasadas del procesador OnTradeTransaction().

En principio, esto es todo en lo que respecta al procesamiento del evento TradeTransaction. Sí, añadiría además la pausa al principio de la llamada del procesador. Entonces se minimizará la probabilidad de que una operación u orden no haya entrado todavía en la historia.


Conclusión

En este artículo he intentado demostrar cómo se puede trabajar con diferentes operaciones comerciales y obtener información sobre lo que sucede en el terminal.

La ventaja de este enfoque consiste en que el programa puede obtener información sobre la ejecución por etapas de la operación comercial. Pienso que este enfoque se puede aplicar con toda tranquilidad para copiar las operaciones comerciales desde un terminal a otro.


Traducción del ruso hecha por MetaQuotes Software Corp.
Artículo original: https://www.mql5.com/ru/articles/1111

Archivos adjuntos |
TradeProcessor.mq5 (15.38 KB)
Cómo hemos desarrollado el servicio de señales comerciales MetaTrader y el trading social en general Cómo hemos desarrollado el servicio de señales comerciales MetaTrader y el trading social en general

Estamos perfeccionando activamente el servicio Señales, deshaciéndonos en el proceso de los anteriores desarrollos e introduciendo cambios en los mecanismos existentes. El MetaTrader Signals de hace dos años y el MetaTrader Signals actual son dos servicios totalmente diferentes.

Asistente MQL5: Ampliación de la biblioteca estándar para el establecimiento de órdenes, stops y objetivos según precios calculados Asistente MQL5: Ampliación de la biblioteca estándar para el establecimiento de órdenes, stops y objetivos según precios calculados

En el artículo se describe la ampliación de la biblioteca estándar MQL5, que permite, con ayuda del Asistente, crear asesores que pongan órdenes, stop loss y take profit según los precios obtenidos de los módulos conectados. Esta aproximación no supone limitaciones adicionales en la cantidad de módulos y no provoca conflictos en su trabajo conjunto.

Desarrollo de una Startup social tecnológica, Parte I: Publicamos las Señales de MetaTrader 5 en el Twitter Desarrollo de una Startup social tecnológica, Parte I: Publicamos las Señales de MetaTrader 5 en el Twitter

Hoy vamos a hablar sobre cómo podemos vincular el terminal MetaTrader 5 con una cuenta del Twitter para publicar las señales de su Asesor Experto. Estamos desarrollando el Sistema social del soporte para la toma de decisiones (SDSS por sus siglas en inglés Social Decision Support System, denominado en adelante como SDSS) con PHP a base del servicio web RESTful. Esta idea se basa en la concepción del trading automático, o así denominado el trading mediante los ordenadores. Queremos que las señales comerciales automáticas del Asesor Experto (EA) pasen por los filtros de las facultades cognitivas de la mente humana.

Desarrollo de una Startup social tecnológica, Parte II: Programamos el cliente REST en MQL5 Desarrollo de una Startup social tecnológica, Parte II: Programamos el cliente REST en MQL5

Hoy vamos a dar forma acabada a la idea de publicación de las señales comerciales del EA en el Twitter a base de PHP. Hemos empezado a hablar sobre eso en la primera parte del artículo. Vamos a reunir las partes separadas del SDSS. En cuanto al lado del cliente de la arquitectura del sistema, vamos a utilizar la nueva función WebRequest() del MQL5 para el envío de las señales comerciales vía HTTP.