Permisos

MetaTrader 5 proporciona funciones para restringir la ejecución de ciertas acciones por parte de los programas MQL por razones de seguridad. Algunas de estas restricciones son de dos niveles, es decir, se establecen por separado para el terminal en su conjunto y para un programa específico. Los ajustes del terminal tienen prioridad o actúan como valores predeterminados para los ajustes de cualquier programa MQL. Por ejemplo, un operador de trading puede desactivar todas las operaciones de trading automatizadas marcando la casilla correspondiente en el cuadro de diálogo de configuración de MetaTrader 5. En este caso, los permisos de trading privados establecidos anteriormente para robots específicos en sus cuadros de diálogo pierden su validez.

En la API de MQL5, dichas restricciones (o viceversa, los permisos) están disponibles para su lectura a través de las funciones TerminalInfoInteger y MQLInfoInteger. Dado que tienen el mismo efecto en un programa MQL, el programa debe comprobar las prohibiciones generales y específicas con el mismo cuidado (para evitar generar un error al intentar realizar una acción ilegal). Por lo tanto, en esta sección se ofrece una lista de todas las opciones de los distintos niveles.

Todos los permisos son banderas booleanas, es decir, almacenan los valores de true o false.

Identificador

Descripción

TERMINAL_DLLS_ALLOWED

Permiso para utilizar la DLL

TERMINAL_TRADE_ALLOWED

Permiso para operar automáticamente en línea

TERMINAL_EMAIL_ENABLED

Permiso para enviar correos electrónicos (el servidor SMTP y el inicio de sesión deben especificarse en la configuración del terminal)

TERMINAL_FTP_ENABLED

Permiso para enviar archivos por FTP al servidor especificado (incluidos los informes para la cuenta de trading especificada en la configuración del terminal).

TERMINAL_NOTIFICATIONS_ENABLED

Permiso para enviar notificaciones push a un smartphone

MQL_DLLS_ALLOWED

Permiso para utilizar la DLL de este programa

MQL_TRADE_ALLOWED

Permiso para que un programa opere automáticamente

MQL_SIGNALS_ALLOWED

Permiso para que un programa trabaje con señales

El permiso para utilizar una DLL a nivel de terminal significa que, cuando se ejecuta un programa MQL que contiene un enlace a alguna biblioteca dinámica, la bandera 'Enable DLL Import' en la pestaña Dependencias se activará por defecto en su cuadro de diálogo de propiedades. Si la bandera está desactivada en la configuración del terminal, la opción en las propiedades del programa MQL estará desactivada por defecto. En cualquier caso, el usuario debe permitir las importaciones para el programa individual (hay una excepción para los scripts, que se aborda más adelante). De lo contrario, el programa no se ejecutará.

En otras palabras: las banderas TERMINAL_DLLS_ALLOWED y MQL_DLLS_ALLOWED pueden ser comprobadas tanto por un programa sin vinculación a una DLL, como por un programa con vinculación, pero para este programa, MQL_DLLS_ALLOWED debe ser inequívocamente igual a true (debido a que ya se ha iniciado). Así, como parte de los sistemas de software que requieren una DLL, probablemente tenga sentido proporcionar una utilidad independiente que controle el estado de la bandera y muestre diagnósticos para el usuario si se apaga repentinamente. Por ejemplo, un Asesor Experto puede necesitar un indicador que utilice una DLL. Entonces, antes de intentar cargar el indicador y obtener su manejador, el EA puede comprobar la bandera TERMINAL_DLLS_ALLOWED y generar una advertencia si la bandera se restablece.

En el caso de los scripts, el comportamiento es ligeramente diferente porque el cuadro de diálogo de configuración de scripts sólo se abre si la directiva #property script_show_inputs está presente en el código fuente. Si no lo está, el cuadro de diálogo aparece cuando se restablece la bandera TERMINAL_DLLS_ALLOWED en la configuración del terminal (y el usuario debe activar la bandera para que el script funcione). Cuando la bandera general TERMINAL_DLLS_ALLOWED está activada, el script se ejecuta sin confirmación del usuario, es decir, se asume que el valor de MQL_DLLS_ALLOWED es true (según TERMINAL_DLLS_ALLOWED).

Cuando se trabaja en el probador, las banderas TERMINAL_TRADE_ALLOWED y MQL_TRADE_ALLOWED son siempre iguales a true. Sin embargo, en los indicadores, el acceso a todas las funciones de trading está prohibido independientemente de estas banderas. El comprobador no permite probar programas MQL con dependencias DLL.

Las banderas TERMINAL_EMAIL_ENABLED, TERMINAL_FTP_ENABLED y TERMINAL_NOTIFICATIONS_ENABLED son críticas para las funciones send mail, SendFTP y send notification, que se describen en la sección Funciones de red. La bandera MQL_SIGNALS_ALLOWED afecta a la disponibilidad de un grupo de funciones que gestionan la suscripción de señales de trading mql5.com (no tratadas en este libro). Su estado corresponde a la opción 'Allow changing signal settings' en la pestaña Common de las propiedades del programa MQL.

Dado que la comprobación de algunas propiedades requiere un esfuerzo adicional, tiene sentido envolver las banderas en una clase que oculta múltiples llamadas a varias funciones del sistema en sus métodos. Esto es tanto más necesario por cuanto que algunos permisos no se limitan a las opciones anteriores. Por ejemplo, el permiso para operar se puede establecer (o eliminar) no sólo a nivel de terminal o programa MQL, sino también para un instrumento financiero individual, de acuerdo con su especificación por parte de su broker y las sesiones de intercambio. Por lo tanto, en este paso, presentaremos un borrador de la clase Permisos que sólo contendrá elementos familiares, y a continuación lo mejoraremos para API de aplicaciones particulares.

Gracias a la clase que actúa como capa del programa, el programador no tiene que recordar qué permisos están definidos para las funciones TerminalInfo y cuáles para las funciones MqlInfo.

El código fuente está en el archivo EnvPermissions.mq5.

class Permissions
{
public:
   static bool isTradeEnabled(const string symbol = NULLconst datetime session = 0)
   {
      // TODO: will be supplemented by applied checks of the symbol and sessions
      return PRTF(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
          && PRTF(MQLInfoInteger(MQL_TRADE_ALLOWED));
   }
   static bool isDllsEnabledByDefault()
   {
      return (bool)PRTF(TerminalInfoInteger(TERMINAL_DLLS_ALLOWED));
   }
   static bool isDllsEnabled()
   {
      return (bool)PRTF(MQLInfoInteger(MQL_DLLS_ALLOWED));
   }
   
   static bool isEmailEnabled()
   {
      return (bool)PRTF(TerminalInfoInteger(TERMINAL_EMAIL_ENABLED));
   }
   
   static bool isFtpEnabled()
   {
      return (bool)PRTF(TerminalInfoInteger(TERMINAL_FTP_ENABLED));
   }
   
   static bool isPushEnabled()
   {
      return (bool)PRTF(TerminalInfoInteger(TERMINAL_NOTIFICATIONS_ENABLED));
   }
   
   static bool isSignalsEnabled()
   {
      return (bool)PRTF(MQLInfoInteger(MQL_SIGNALS_ALLOWED));
   }
};

Todos los métodos de la clase son estáticos y se invocan en OnStart.

void OnStart()
{
   Permissions::isTradeEnabled();
   Permissions::isDllsEnabledByDefault();
   Permissions::isDllsEnabled();
   Permissions::isEmailEnabled();
   Permissions::isPushEnabled();
   Permissions::isSignalsEnabled();
}

A continuación se muestra un ejemplo de los registros generados.

TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)=1 / ok
MQLInfoInteger(MQL_TRADE_ALLOWED)=1 / ok
TerminalInfoInteger(TERMINAL_DLLS_ALLOWED)=0 / ok
MQLInfoInteger(MQL_DLLS_ALLOWED)=0 / ok
TerminalInfoInteger(TERMINAL_EMAIL_ENABLED)=0 / ok
TerminalInfoInteger(TERMINAL_NOTIFICATIONS_ENABLED)=0 / ok
MQLInfoInteger(MQL_SIGNALS_ALLOWED)=0 / ok

Para el autoaprendizaje, el script tiene incorporada (pero comentada) la capacidad de conectar DLL del sistema para leer el contenido del portapapeles de Windows. Consideraremos la creación y el uso de bibliotecas, en particular la directiva #import, en la séptima parte del libro, en la sección Bibliotecas.

Supongamos que la opción de importación global de DLL está desactivada en el terminal deshabilitado (esta es la configuración recomendada por razones de seguridad). Entonces, si las DLL están conectadas al script, sólo será posible ejecutar el script permitiendo la importación en su cuadro de diálogo de configuración individual, como resultado de lo cual MQLInfoInteger(MQL_DLLS_ALLOWED) devolverá 1 (true). Si se da el permiso global para la DLL, entonces obtenemos TerminalInfoInteger(TERMINAL_DLLS_ALLOWED)=1, y MQL_DLLS_ALLOWED heredará este valor.