Un Gestor de Órdenes Virtuales para rastrear órdenes dentro del entorno centrado en posiciones de MetaTrader 5

Paul | 21 febrero, 2014


1. Introducción

Se podría decir que el mayor cambio en la transición de MetaTrader 4 a MetaTrader 5 es la gestión de operaciones de trading abiertas como posiciones. En cualquier momento solo puede haber una posición para cada símbolo, y el tamaño de esta posición se ajusta hacia arriba y hacia abajo cada vez que el broker procesa las órdenes temporales. Esto coincide con la regla NFA 2-43(b) FIFO introducida en Estados Unidos, y también se adapta al modo de trading de muchas otras entidades como mercancías o contratos por diferencia (CFDs).

Un ejemplo claro de esta diferencia se da cuando dos EAs (Asesores Expertos, por sus siglas en inglés) ejecutándose contra el mismo símbolo envían órdenes en direcciones opuestas.  Esta puede ser una situación frecuente con dos EAs trabajando en intervalos diferentes, tales como un especulador o un seguidor de tendencias.  En MetaTrader 4, la lista de comercio abierto mostraría órdenes abiertas de compra y venta con un margen de cero. En MetaTrader 5, no habría posición abierta alguna.

Observando el código del EA, podemos ver que funciones como OpenOrders(), comúnmente usada en MQL4, o una variante similar, no funcionarán de la forma en que se espera al trasladarlas a MQL5.

int OpenOrders()  // MetaTrader 4 code to count total open orders for this EA
{
  int nOpenOrders=0;
  for (int i=OrdersTotal()-1; i>=0; i--)
  {
    OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
    if (OrderMagicNumber()==magic)
      if (OrderType()==OP_BUY || OrderType()==OP_SELL)
        if (OrderSymbol()==Symbol())
          nOpenOrders++;
  }
  return(nOpenOrders);
}

De modo que el entorno centrado en posiciones MetaTrader 5 es todo un reto para los programadores acostumbrados al enfoque de procesamiento de órdenes usado en MetaTrader 4. Lo que antes eran funciones de gestión de órdenes sencillas en MetaTrader 4, ahora son operaciones más complejas en MetaTrader 5, cuando órdenes múltiples se pueden unir en una sola posición, tal como los múltiples EAs trabajando con un símbolo, u órdenes múltiples de un EA a un símbolo.


2. Formas de trabajar con posiciones en MetaTrader 5  

Hay varias formas de gestionar este entorno centrado en posiciones en MetaTrader 5, dependiendo de la complejidad de las estrategias de trading.

Primero, tenga en cuenta que la gestión de MetaTrader 5 de las órdenes pendientes es parecida a la de MetaTrader 4, de modo que solo el código de MQL5 escrito para las órdenes pendientes podría traspasarse de forma relativamente fácil del código MQL4.

2.1 EA directo; un EA por símbolo, por cuenta

El enfoque más sencillo es limitar el trading a una cuenta para un EA directo por símbolo. “EA directo” significa, en este caso, un EA que solo envía una orden cada vez: un método común pero que excluye estrategias tales como la piramidal y el trading en cuadrícula.  Los EAs directos se pueden escribir en MQL5 de forma similar a MQL4, quizás usando la envoltura de la biblioteca CTrade facilitada en include\trade\trade.mqh.

2.2 EA complejo; un EA por símbolo, por cuenta

En el caso de EAs complejos, tales como aquellos que tienen una estrategia de trading piramidal o de cuadrícula que pueden requerir más de una orden abierta por símbolo, es posible que lo único que necesitemos para gestionar la estrategia sea añadir al EA un código de rastreo de orden relativamente sencillo. Esto solo será posible si el EA nunca comparte posiciones con otro EA funcionando con el mismo símbolo.

2.3 Más de un EA para cualquier tipo por símbolo, por cuenta

Esta posibilidad presenta los requisitos de trading y codificación más complejos, y es la razón para el desarrollo de la biblioteca del Gestor de Órdenes Virtuales (Virtual Order Manager, o VOM). Esta biblioteca tiene por objetivo simplificar en gran medida el desarrollo de un código de EA robusto que sea perfectamente funcional con otros EAs.

El resto de este artículo describe la biblioteca de Gestión de Órdenes Virtuales en detalle.


3. Diseñar objetivos, beneficios y desventajas del Gestor de Órdenes Virtuales (VOM, por sus siglas en inglés) 

El VOM tiene cuatro objetivos principales:

  1. Sociabilidad: el comportamiento de los EAs escritos correctamente usando las funciones de trading del VOM se aislará del resto de actividades del EA.
  2. Robustez: gestión elegante de eventos no ordinarios tales como errores, rupturas en la comunicación entre cliente y servidor, y órdenes incompletas.
  3. Facilidad de uso: provisión de funciones de trading sencillas y bien documentadas.
  4. Capacidad de uso en el Probador de Estrategias

Estos objetivos se implementan del siguiente modo:

El VOM permite a un programador de un EA de MQL5 EA:

También debemos apuntar que un efecto secundario del VOM es que los stoplosses, takeprofits y órdenes pendientes virtuales tiene de forma inherente un comportamiento "sigiloso" (“stealth”), es decir, no pueden ser vistos por el servidor de broker. Ocultar los niveles de stoploss es algo que muchos consideran necesario para poder salir "a la caza" de stops.

El VOM también tiene desventajas. La cantidad de riesgo de capital aumenta a causa de la posibilidad de depender del servidor protector más lejano durante un fallo duradero del PC o de la conexión de internet. Asimismo, el deslizamiento al dar con una orden pendiente, stoploss o takeprofit podría ser mucho más alto que en su equivalente basado en el servidor durante tiempos de alta volatilidad, tales como eventos y noticias.  El impacto de estas desventajas se puede minimizar si los EAs del VOM se ejecutan desde un ordenador virtual de alta seguridad con un ping de corta duración al servidor de broker.


4. El VOM en la práctica: un EA sencillo

Antes de seguir, es el momento de demostrar cómo se puede escribir un EA de VOM. Escribiremos un EA "cross MA" sencillo, empezando con la plantilla del EA facilitada en el paquete de distribución. Utilizaremos la Media Móvil Fractal, que tiene el potencial de reducir operaciones de trading innecesarias en mercados apartados, un problema notorio con estrategias de cross MA. Debemos destacar que este EA se ha facilitado como ejemplo sencillo, y no se recomienda para operaciones de trading reales: aunque la simulación resulta rentable, las bajas cifras de operaciones de trading significan que los resultados no serán estadísticamente significativos.

El EA se guarda en experts\Virtual Order Manager\VOM EAs.

//+------------------------------------------------------------------+
//|                                           FraMA Cross EA VOM.mq5 |
//+------------------------------------------------------------------+
#property copyright "Paul Hampton-Smith"
#property link      "http://paulsfxrandomwalk.blogspot.com"
#property version   "1.00"

// this is the only include required.  It points to the parent folder
#include "..\VirtualOrderManager.mqh"

input double   Lots=0.1;
input int      Fast_MA_Period=2;
input int      Slow_MA_Period=58;
/* 
Because the broker is 3/5 digit, stoplosses and takeprofits should be x10.  
It seems likely that all brokers offering MetaTrader 5 will be 3/5 digit brokers, 
but if this turns out to be incorrect it will not be a major task to add 
digit size detection. */
input int      Stop_Loss=5000;
input int      Take_Profit=0;
/*
We can also change the level of logging.  LOG_VERBOSE is the most prolific 
log level.  Once an EA has been fully debugged the level can be reduced to 
LOG_MAJOR.  Log files are written under the files\EAlogs folder and are 
automatically deleted after 30 days.  */
input ENUM_LOG_LEVEL Log_Level=LOG_VERBOSE;

// The following global variables will store the handles and values for the MAs 
double g_FastFrAMA[];
double g_SlowFrAMA[];
int g_hFastFrAMA;
int g_hSlowFrAMA;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   LogFile.LogLevel(Log_Level);

// Need to include this line in all EAs using CVirtualOrderManager  
   VOM.Initialise();
   Comment(VOM.m_OpenOrders.SummaryList());

   g_hFastFrAMA = iFrAMA(_Symbol,_Period,Fast_MA_Period,0,PRICE_CLOSE);
   g_hSlowFrAMA = iFrAMA(_Symbol,_Period,Slow_MA_Period,0,PRICE_CLOSE);
   ArraySetAsSeries(g_FastFrAMA,true);
   ArraySetAsSeries(g_SlowFrAMA,true);

   return(0);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
// Need to include this line in all EAs using CVirtualOrderManager  
   VOM.OnTick();
   Comment(VOM.m_OpenOrders.SummaryList());

// We now obtain copies of the most recent two FrAMA values in the 
// g_FastFrAMA and  g_SlowFrAMA arrays.  
   if(CopyBuffer(g_hFastFrAMA,0,Shift,2,g_FastFrAMA)!=2) || 
      CopyBuffer(g_hSlowFrAMA,0,Shift,2,g_SlowFrAMA)!=2)
     {
      Print("Not enough history loaded");
      return;
     }

// And now we detect a cross of the fast FrAMA over the slow FrAMA,
// close any opposite orders and Buy a single new one
   if(g_FastFrAMA[0]>g_SlowFrAMA[0] && g_FastFrAMA[1]<=g_SlowFrAMA[1])
     {
      VOM.CloseAllOrders(_Symbol,VIRTUAL_ORDER_TYPE_SELL);
      if(VOM.OpenedOrdersInSameBar()<1 && VOM.OpenOrders()==0)
        {
         VOM.Buy(_Symbol,Lots,Stop_Loss,Take_Profit);
        }
     }

// Opposite for Sell
   if(g_FastFrAMA[0]<g_SlowFrAMA[0] && g_FastFrAMA[1]>=g_SlowFrAMA[1])
     {
      VOM.CloseAllOrders(_Symbol,VIRTUAL_ORDER_TYPE_BUY);
      if(VOM.OpenedOrdersInSameBar()<1 && VOM.OpenOrders()==0)
        {
         VOM.Sell(_Symbol,Lots,Stop_Loss,Take_Profit);
        }
     }
  }
//+------------------------------------------------------------------+

Y ahora, con el Probador de Estrategias, podemos proceder a la simulación, como se ve en la Figura 1:

 Figura 1. Simulación FrAMA Cross EA

Figura 1. Simulación FrAMA Cross EA

La sección de entrada a la cuenta se muestra en la Figura 2:

 Figura 2. Registro de simulación de estrategia

Figura 2. Registro de simulación de estrategia

 

5. Estructura del VOM

La Figura 3 muestra cómo se configuran múltiples EAs de VOM:

Figura 3. Múltiples EAs de VOM

Figura 3. Múltiples EAs de VOM

A continuación, mirando dentro del VOM, los principales componentes se muestran en la Figura 4:

Figura 4. Estructura interna del VOM

Figura 4. Estructura interna del VOM

 Explicación de los elementos de la Figura 4:

Los Asesores Expertos que usan el VOM interactúan con la biblioteca, tal y como se muestra en la Figura 5 abajo:

 Figura 5. Interacción del EA con la biblioteca del VOM

 Figura 5. Interacción del EA con la biblioteca del VOM


6. Más sobre el stoploss de protección contra desastres

Los stops virtuales eran muy comunes en los EAs de MetaTrader 4. Si un stoploss se mantiene solo en el lado del cliente, el nivel de salida para una operación de trading es invisible para el broker, una estrategia a menudo implementada con la creencia de que algunos brokers van a la caza de stops.  Por sí mismos, los stops virtuales aumentan significativamente el riesgo de trading, puesto que una conexión entre cliente y broker debe estar siempre activa para que se active el stop. 

El VOM controla este riesgo manteniendo un stop basado en el servidor a una distancia configurable del stop virtual más estricto. Esto se llama stoploss de protección contra desastres (DPSL, por sus siglas en inglés), porque normalmente solo se activará si la conexión entre cliente y broker se corta durante un tiempo, o si se da un fallo de conexión a internet o un fallo del PC. Puesto que las órdenes virtuales se abren, cierran, y se convierten en posiciones en el servidor continuamente, el mantenimiento del DPSL en el nivel correcto puede ser algo complejo, tal y como se ilustra en la siguiente secuencia.

Virtual order
action
Open
price
Virtual SL Position
at server
Stoploss
at server
Comment
0.1 lots BUY #1 2.00000 1.99000 0.1 lots BUY 1.98500 DPSL is 50 pips below virtual SL #1
0.1 lots BUY #2 2.00000 1.99500 0.2 lots BUY 1.99000 Virtual order #2 has a tighter SL so DPSL
is tightened to 50 pips below virtual SL #2
Close #2     0.1 lots BUY 1.98500 Revert to looser DPSL
0.1 lots SELL #3 2.00000 2.00500 none none Virtual orders #1 and #3 have cancelled each
other out at the server
Close #1     0.1 lots SELL 2.01000 Virtual Order #3 remains open - DPSL is
now 50 pips above virtual SL #3

7. Simulación del Gestor de Órdenes Virtuales

Un proyecto de este tamaño requiere su tiempo para llevar a cabo una simulación completa, de modo que escribí el EA VirtualOrderManaerTester.mq5 para permitir la creación, modificación, eliminación y fácil cierre de órdenes con botones de comando en el gráfico.  

La Figura 6 muestra una orden virtual de compra en lote 0.1 en la ventana M5 y una orden virtual de compra de otro lote 0.1 abierta en la ventana H4 contra EURUSD (vea las líneas de comentario), con el estado de servidor mostrando correctamente una posición en lotes 0.2 comprados. Puesto que la posición general es grande, el Stoploss de Protección contra Desastres se puede ver por debajo del stop más estricto 20.0 pip.

Figura 6. Dos EAs que coinciden en dirección

Figura 6. Dos EAs que coinciden en dirección

La Figura 7 muestra ahora los dos EAs con órdenes virtuales opuestas. No se abre posición alguna desde el broker:

Figura 7. Dos EAs con órdenes virtuales opuestas. No se abre posición alguna desde el broker

Figura 7. Dos EAs con órdenes virtuales opuestas. No se abre posición alguna desde el broker


8. Una muestra muy sencilla de todas las órdenes abiertas del VOM

Cada EA del VOM solo puede ver sus propias órdenes, de modo que he escrito un EA muy sencillo que coteja las órdenes abiertas de todos los VOMs. La muestra es muy sencilla, y cuando el tiempo me lo permita, escribiré una versión mucho mejor, quizás con botones de comando para realizar acciones de modificación, eliminación o cierre según se requiera en cada orden. El EA se incluye en el paquete de distribución como VOM_OrderDisplay.mq5.


9. Conclusión

En el momento en el que escribo este artículo, el código VOM se encuentra en fase Beta, al igual que el mismo MetaTrader 5, y solo el tiempo dirá si el concepto del VOM llegará a ser popular o acabará siendo considerado simplemente como un elemento interesante de programación de MQL5.

Volvamos a los objetivos de diseño de la sección 3 y veamos a dónde hemos llegado.

  1. Sociabilidad: el comportamiento de los EAs escritos correctamente usando las funciones de trading del VOM se aislará del resto de actividades del EA.
    • Resultado - sí, el VOM consiguió este objetivo.
  2. Robustez: gestión elegante de eventos no ordinarios tales como errores, rupturas en la comunicación entre cliente y servidor, y órdenes incompletas.
    • Resultado - se nota un grado de robustez, pero podría mejorarse si se dieran situaciones de trading reales y se pudieran analizar. 
  3. Facilidad de uso: provisión de funciones de trading sencillas y bien documentadas.
    • Resultado - como verá en el paquete de distribución de archivos, el archivo de ayuda a .chm está incluido.
  4. Capacidad de uso en el Probador de Estrategias
    • Resultado - las simulaciones iniciales en el Probador de Estrategias recién lanzado indica que el VOM puede pasar una simulación correctamente, aunque el VOM ralentiza el proceso considerablemente. Probablemente se puede seguir trabajando en algunas mejoras generales.  

No estarían de más algunos cambios en el futuro.

  • Al igual que con cualquier desarrollo de software complejo, es probable que quede bugs en el código.
  • Con cada versión Beta de MetaTrader 5, seguramente, se requerirán cambios en el VOM para mantener la compatibilidad.
  • Las funciones VomGetLastError() y VomErrorDescription()
  • Capacidad para leer la configuración de un archivo
  • Stops de rastreo de varios tipos


10. Archivos en el paquete de distribución comprimido

El paquete del VOM viene como un conjunto de archivos .mqh que se deben instalar en la carpeta Experts\Virtual Order Manager,

  • ChartObjectsTradeLines.mqh - CEntryPriceLine, CStopLossLine, CTakeProfitLine
  • StringUtilities.mqh - descriptores globales enum tales como ErrorDescription()
  • Log.mqh - CLog
  • GlobalVirtualStopList.mqh - CGlobalVirtualStopList
  • SimpleChartObject.mqh - CButton, CLabel y CEdit
  • VirtualOrder.mqh - CVirtualOrder
  • GlobalVariable.mqh - CGlobalVariable
  • VirtualOrderArray.mqh - CVirtualOrderArray
  • VirtualOrderManager.mqh - CVirtualOrderManager
  • VirtualOrderManagerConfig.mqh - CConfig
  • VirtualOrderManagerEnums.mqh - los varios enums definidos para el VOM
  • VOM_manual.mqh - esta página del manual
  • VOM_doc.chm***

Cinco archivos EA de mq5 se incluyen también en Experts\Virtual Order Manager\VOM EAs:

  • VOM_template_EA.mq5 - clónelo para crear sus propios EAs, y guárdelos en Experts\Virtual Order Manage\VOM EAs
  • VirtualOrderManagerTester.mq5
  • Support_Resistance_EA_VOM.mq5
  • FrAMA_Cross_EA_VOM.mq5
  • VOM_OrderDisplay.mq5 
***Tenga en cuenta que el archivo VOM_doc.chm podría requerir ser desbloqueado: