En este artículo presentamos una técnica que utiliza ZeroMQ (una librería de código abierto para mensajería asíncrona destinada a su uso en aplicaciones distribuidas escalables o concurrentes) para crear un puente básico de alto rendimiento –aunque fácilmente ampliable– entre lenguajes externos de programación y MetaTrader 4.

Razones por las que hemos escrito este artículo:

  1. Falta de literatura detallada y disponible públicamente acerca de este tema en Internet.
  2. Los traders tradicionalmente han trabajado con soluciones basadas en Winsock/WinAPI que a menudo requieren ser revisadas cuando salen actualizaciones por parte de Microsoft y MetaQuotes.
  3. Las alternativas a ZeroMQ incluyen ‘named pipes’ y enfoques en los que una funcionalidad dependiente del sistema de archivos crea el puente entre MetaTrader y los lenguajes externos.

En este artículo, proporcionamos las bases para un sistema de trading distribuido en el que:

  1. Existirá una o más estrategias de trading desarrolladas fuera de MetaTrader 4 (por tanto, no escritas en MQL).
  2. Se utilizará MetaTrader 4 para la adquisición de datos de mercado, la ejecución de las operaciones y su posterior gestión.
  3. Se soportarán múltiples estrategias creadas con lenguajes externos que interactuarán con MetaTrader 4 simultáneamente.
  4. Se considerará cada estrategia de trading como un "Cliente" independiente.
  5. Se considerará MetaTrader 4 como el "Servidor", siendo el medio para acceder al mercado.
  6. Permitirá que tanto el Servidor como los Clientes se comunicarán entre sí bajo demanda.


 Infraestructura de Trading Distribuida basada en ZeroMQ (con MetaTrader 4)

¿Por Qué ZeroMQ?

  1. Permite a los programadores conectar cualquier código a otro código, de varias maneras.
  2. Elimina la dependencia del usuario de la tecnología soportada por MetaTrader (características, indicadores, construcciones de lenguaje, librerías, etc.)
  3. Los traders pueden desarrollar indicadores y estrategias en C/C#/C++, Python, R y Java entre otros, e implementarlos en el mercado a través de MetaTrader 4.
  4. Aprovechar las herramientas de machine learning disponibles en Python y R para el análisis de datos complejos y el desarrollo de estrategias, al mismo tiempo que se relaciona con MetaTrader 4 para la ejecución y gestión de las operaciones.
  5. ZeroMQ puede ser utilizado como una capa de transporte de alto rendimiento en sistemas sofisticados y distribuidos, que de otro modo serían difíciles de implementar con MQL.
  6. Podemos construir diferentes componentes de una estrategia usando distintos lenguajes si es necesario, y de manera transparente comunicarse entre sí a través de los protocolos TCP, in-process, interprocess o multicast.
  7. Múltiples patrones de comunicación y funcionamiento desconectado.


ZeroMQ: Lenguajes de Programación Soportados

Aunque en este artículo nos centraremos en MQL interactuando con Python y R, el proceso descrito aquí puede ser fácilmente implementado en otros lenguajes soportados por ZeroMQ.

Una lista detallada de vínculos de ZeroMQ con otros lenguajes podéis encontrarla aquí::

Vínculos de ZeroMQ con otros lenguajes


¿Quién más está usando ZeroMQ?

AT&T, Cisco, EA, Los Alamos Labs, NASA, Weta Digital, Zynga, Spotify, Samsung Electronics, Microsoft, CERN y Darwinex Labs.

Asimismo ZeroMQ está detrás de al menos 5 DARWINS en DARWIN Exchange, en los que las estrategias están escritas usando C++, Python y R.


Planificando el Control del Flujo

Este artículo no pretende ser un tutorial detallado de ZeroMQ.

Sin embargo, es importante entender algunas cosas acerca de ZeroMQ que lo hacen particularmente adecuado para la tarea de conectar lenguajes de programación externos como Python y R a MetaTrader 4.

  • Soporta redes TCP, inter-process, in-process, PGM y EPGM habilitado para multidifusión. Usaremos el tipo de transporte TCP para la implementación en este artículo.
  • ZeroMQ permite a los servidores y a los clientes conectarse “entre sí” bajo demanda, algo particularmente útil para diseñar infraestructuras distribuidas de trading.
  • Además del soporte para comunicación asíncrona y el funcionamiento desconectado, ZeroMQ soporta varios patrones de comunicación que permiten una transferencia de datos de nivel superior, lo que libera a los programadores para centrarse más en la lógica de transferencia que en los mecanismos de bajo nivel.
  • Estos patrones incluyen: Request (REQ) / Reply (REP), Publish (PUB) / Subscribe (SUB) y Push (PUSH) / Pull (PULL).

Para la implementación que veremos en este artículo, emplearemos los patrones de comunicación REQ/REP y PUSH/PULL de ZeroMQ. MetaTrader 4 será nuestro “Servidor”, y las estrategias de trading actuarán como “Clientes”.

Debemos tener en cuenta que esto (MT4 = Servidor, Estrategia = Cliente) no es un algo obligatorio - tendremos que decidir sobre cualquier control de flujo que se adapte mejor a nuestras necesidades particulares.

Por ejemplo, podemos designar una máquina independiente tanto de la estrategia de trading como de MetaTrader 4, como nuestro Servidor, y que tanto las Estrategias como MT4 actúen como Clientes. Hay varias maneras de alcanzar nuestro objetivo; planificar cuidadosamente el control de flujo conducirá a una funcionalidad eficiente.

 

Patrón Request (REQ) / Reply (REP)

El Servidor (MetaTrader 4 EA) empleará un socket TCP de tipo REP, para recibir solicitudes y enviar respuestas. Un socket REP SIEMPRE debe iniciarse con un par de llamadas: primero, una recepción de una solicitud, seguida de un envío de respuesta.

El Cliente (la Estrategia de Trading, por ejemplo, en Python) empleará un socket TCP de tipo REQ, para enviar solicitudes y recibir respuestas. Al igual que antes, un socket REQ SIEMPRE debe iniciarse con un par de llamadas: en primer lugar, un envío de una petición, seguido de una recepción de respuesta.

Para esta implementación, el patrón REQ / REP permitirá que nuestros Clientes envíen comandos al Servidor MetaTrader 4 y reciban confirmación de los mismos (por ejemplo, ABRIR/MODIFICAR/CERRAR operaciones, OBTENER COTIZACIONES BID / ASK, OBTENER DATOS HISTÓRICOS, etc.)

 

Patrón Push (PUSH) / Pull (PULL)

El Servidor (MetaTrader 4 EA) también empleará un segundo socket PUSH para enviar información adicional a los Clientes (Estrategias de Trading). Este es un socket unidireccional, y el Servidor sólo podrá enviar datos a este socket, sin poder recibir nada de nuevo a través del mismo socket.

El Cliente (Estrategia de Trading) también empleará un segundo socket PULL para recibir información adicional del Servidor. Esto también es un socket unidireccional, y el Cliente sólo podrá recibir datos de este socket, sin poder enviar nada a través del mismo socket.

El patrón PUSH / PULL permite a Servidores y Clientes intercambiar datos entre sí bajo demanda, pero en una dirección sin esperar una respuesta. Esto podría ser cambiado por otro patrón REQ / REP, dependiendo de los requisitos de control de flujo de nuestra aplicación.

En resumen, para esta implementación básica:

1. El Servidor empleará dos sockets, un REP y un PUSH.
2. Cada Cliente empleará dos sockets, un REQ y un PULL.



Aspecto del plan de control de flujo en la práctica


MetaTrader 4 Expert Advisor – Componentes

Como hemos visto en el gráfico anterior, el Expert Advisor de MT4 servirá como nuestro Servidor habilitado para ZeroMQ, con tres módulos principales:

1. ENRUTADOR DE MENSAJES - Esto permite que el EA reciba comandos y envíe confirmaciones de nuevo a los Clientes que se conecten (Estrategias de Trading) a través del socket REP. El enrutador pasa todos los mensajes al intérprete. Nota: Para este ejemplo, el enrutador no sirve para mucho, pero es una buena práctica tener este intermediario donde varias estrategias se conectan al Servidor (MT4) y seguramente sea necesario realizar algún pre-análisis.

2. INTÉRPRETE DE MENSAJES - Los mensajes recibidos por este módulo se descomponen en acciones para el siguiente módulo (Interpreter & Executor).

3. INTERPRETER & EXECUTOR - Este módulo literalmente "interpreta" mensajes descompuestos y realiza las acciones solicitadas en consecuencia. Por ejemplo, si el Cliente está solicitando datos de mercado, el módulo los recopila de la Base de Datos de Históricos de MetaTrader 4 y la envía al Cliente a través del socket PUSH. Alternativamente, si el Cliente solicita que se abra una operación de COMPRA o VENTA por ejemplo en EUR/USD, envía la operación al mercado y una notificación de éxito/fallo/número de ticket al Cliente a través del socket PUSH.

Requisitos para la Implementación

  1. Vínculos ZeroMQ – MQL4 -> Descargar e  instalar los archivos necesarios tal y como se explica aquí: https://github.com/dingmaotu/mql-zmq
  2. Para Python -> Librería “pyzmq”
  3. Para R -> Librería “rzmq”

 

Código de Ejemplo

Para que tengáis un punto de partida, hemos publicado un Experto Advisor para MetaTrader 4 con la implementación completa que acabamos de ver en este artículo.

El código MQL proporcionado es bastante extensible, y puede utilizarse como una plantilla para su propio código.

Enlaces en GitHub
1. Expert Advisor MT4 habilitado para ZeroMQ - GitHub

2. Ejemplo de cliente ZeroMQ en R - GitHub

3. Ejemplo de Cliente ZeroMQ en Python - GitHub


Notas:

1. Los ejemplos en Python y R demuestran cómo se implementan los patrones de comunicación.

2. Es bastante simple integrar este código en las estrategias de trading que haya creado ya en Python / R.