Permiso de trading

Como continuación del tema relacionado con la correcta preparación de las órdenes de trading que iniciamos en la sección anterior, vamos a pasar al siguiente par de propiedades que desempeñan un papel muy importante en el desarrollo de Asesores Expertos.

Identificador

Descripción

SYMBOL_TRADE_MODE

Permisos para los distintos modos de trading del símbolo (véase ENUM_SYMBOL_TRADE_MODE)

SYMBOL_ORDER_MODE

Banderas de los tipos de orden permitidos, máscara de bits (véase más adelante)

Ambas propiedades son de tipo entero y están disponibles a través de la función SymbolInfoInteger.

Ya hemos utilizado la propiedad SYMBOL_TRADE_MODE en el script SymbolPermissions.mq5. Su valor es uno de los elementos de la enumeración ENUM_SYMBOL_TRADE_MODE.

Identificador

Valor

Descripción

SYMBOL_TRADE_MODE_DISABLED

0

El trading está desactivado para el símbolo

SYMBOL_TRADE_MODE_LONGONLY

1

Sólo se permiten operaciones de compra

SYMBOL_TRADE_MODE_SHORTONLY

2

Sólo se permiten operaciones de venta

SYMBOL_TRADE_MODE_CLOSEONLY

3

Sólo se permiten operaciones de cierre

SYMBOL_TRADE_MODE_FULL

4

Sin restricciones en las operaciones comerciales

Recordemos que la clase Permissions contiene el método isTradeOnSymbolEnabled, que comprueba varios aspectos que afectan a la disponibilidad de trading de símbolos, y uno de ellos es la propiedad SYMBOL_TRADE_MODE. Por defecto, consideramos que nos interesa el pleno acceso al trading, es decir, vender y comprar: SYMBOL_TRADE_MODE_FULL. Dependiendo de la estrategia de trading, el programa MQL puede considerar suficientes, por ejemplo, permisos sólo para comprar, sólo para vender o sólo para cerrar operaciones.

   static bool isTradeOnSymbolEnabled(string symbolconst datetime now = 0,
      const ENUM_SYMBOL_TRADE_MODE mode = SYMBOL_TRADE_MODE_FULL)
   {
      // checking sessions
      bool found = now == 0;
      ...
      // checking the trading mode for the symbol
      return found && (SymbolInfoInteger(symbolSYMBOL_TRADE_MODE) == mode);
   }

Además del modo de trading, en el futuro tendremos que analizar los permisos para órdenes de distintos tipos: se indican mediante bits separados en la propiedad SYMBOL_ORDER_MODE y pueden combinarse arbitrariamente con un OR lógico ('|'). Por ejemplo, el valor 127 (0x7F) corresponde a todos los bits activados, es decir, la disponibilidad de todos los tipos de órdenes.

Identificador

Valor

Descripción

SYMBOL_ORDER_MARKET

1

Se permiten órdenes de mercado (compra y venta)

LIMITE_ORDEN_SIMBOLO

2

Se permiten órdenes Limit (Buy Limit y Sell Limit)

SYMBOL_ORDER_STOP

4

Se permiten órdenes Stop (Buy Stop y Sell Stop)

SYMBOL_ORDER_STOP_LIMIT

8

Se permiten las órdenes Stop Limit (Buy Stop Limit y Sell Stop Limit)

SYMBOL_ORDER_SL

16

Se permite fijar niveles de Stop Loss

SYMBOL_ORDER_TP

32

Se permite establecer niveles de Take Profit

SYMBOL_ORDER_CLOSEBY

64

Permiso para cerrar una posición por otra opuesta para el mismo símbolo, operación Close By.

La propiedad SYMBOL_ORDER_CLOSEBY sólo se establece para las cuentas con contabilidad de cobertura (ACCOUNT_MARGIN_MODE_RETAIL_HEDGING, véase Tipo de cuenta).

En el script de prueba SymbolFilterTradeMode.mq5, solicitaremos un par de propiedades descritas para símbolos visibles en Market Watch. La salida de bits y sus combinaciones como números no es muy informativa, así que utilizaremos el hecho de que en la clase SymbolMonitor tenemos un método stringify que resulta práctico para imprimir los miembros de la enumeración y las máscaras de bits de todas las propiedades.

void OnStart()
{
   SymbolFilter f;                      // filter object
   string symbols[];                    // array for names 
   long permissions[][2];               // array for data (property values)
   
   // list of requested symbol properties
   ENUM_SYMBOL_INFO_INTEGER modes[] =
   {
      SYMBOL_TRADE_MODE,
      SYMBOL_ORDER_MODE
   };
   
   // apply the filter, get arrays with results
   f.let(SYMBOL_VISIBLEtrue).select(truemodessymbolspermissions);
   
   const int n = ArraySize(symbols);
   PrintFormat("===== Trade permissions for the symbols (%d) ====="n);
   for(int i = 0i < n; ++i)
   {
      Print(symbols[i] + ":");
      for(int j = 0j < ArraySize(modes); ++j)
      {
         // display bit and number descriptions "as is"
         PrintFormat("  %s (%d)",
            SymbolMonitor::stringify(permissions[i][j], modes[j]),
            permissions[i][j]);
      }
   }
}

A continuación se muestra parte del registro resultante de ejecutar el script.

===== Trade permissions for the symbols (13) =====
EURUSD:
  SYMBOL_TRADE_MODE_FULL (4)
  [ _SYMBOL_ORDER_MARKET _SYMBOL_ORDER_LIMIT _SYMBOL_ORDER_STOP
  _SYMBOL_ORDER_STOP_LIMIT _SYMBOL_ORDER_SL _SYMBOL_ORDER_TP
  _SYMBOL_ORDER_CLOSEBY ] (127)
GBPUSD:
  SYMBOL_TRADE_MODE_FULL (4)
  [ _SYMBOL_ORDER_MARKET _SYMBOL_ORDER_LIMIT _SYMBOL_ORDER_STOP
  _SYMBOL_ORDER_STOP_LIMIT _SYMBOL_ORDER_SL _SYMBOL_ORDER_TP
  _SYMBOL_ORDER_CLOSEBY ] (127)
... 
SP500m:
  SYMBOL_TRADE_MODE_DISABLED (0)
  [ _SYMBOL_ORDER_MARKET _SYMBOL_ORDER_LIMIT _SYMBOL_ORDER_STOP
  _SYMBOL_ORDER_STOP_LIMIT _SYMBOL_ORDER_SL _SYMBOL_ORDER_TP ] (63)

Tenga en cuenta que la negociación para el último símbolo SP500m está completamente desactivada (sus cotizaciones se proporcionan únicamente a título «indicativo»). Al mismo tiempo, su conjunto de banderas por tipos de orden no es 0, pero no hace ninguna diferencia.

Dependiendo de los acontecimientos en el mercado, el bróker puede cambiar las propiedades del símbolo a su discreción; por ejemplo, dejando sólo la oportunidad de cerrar posiciones durante algún tiempo, por lo que un robot de trading correcto debe controlar estas propiedades antes de cada operación.