Português
preview
Simulación de mercado (Parte 17): Sockets (X)

Simulación de mercado (Parte 17): Sockets (X)

MetaTrader 5Probador |
21 1
Daniel Jose
Daniel Jose

Introducción

En los dos últimos artículos, expliqué cómo preparar Excel para comunicarse con MetaTrader 5. En concreto, en el artículo anterior, Simulación de mercado (Parte 16): Sockets (X), expliqué cómo codificar en VBA. Esto es para que Excel pueda interactuar de manera adecuada con el servidor, que está escrito en Python. A pesar de que seguramente imagines que tal interacción no generaría ningún problema.

En esta pequeña fase, en la que expliqué qué son los sockets, mostré que, si no se hace bien, al usar Excel surgirán problemas. Esto ocurre cuando se utiliza el servidor en Python. Sin embargo, como quedó claro en los dos últimos artículos, una codificación correcta en la parte de VBA soluciona cualquier problema de interacción entre Excel y Python, y hace que ambos funcionen en perfecta armonía. No obstante, queda una última cosa por hacer. Esto es necesario para concluir realmente la implementación. Dicha cosa debe realizarse en la parte que involucra a MetaTrader 5, y aquí tenemos algunas decisiones que tomar.


Planeamiento antes de la implementación

La decisión principal que hay que tomar es qué lenguaje se usará para implementar la parte que se ejecutará en MetaTrader 5. Lo digo porque podemos hacer las cosas tanto usando Python como MQL5 puro. Ambos lenguajes nos permitirán hacer gran parte, si no la totalidad, de lo que queremos. No obstante, si elegimos Python, tendremos la limitación de que, al ser un script, deberá colocarse en un gráfico. En cambio, si usamos MQL5, podemos utilizar alguna técnica o modelo que se adecúe mejor al trabajo que se va a realizar.

Sin embargo, si vamos a usar MQL5, podemos orientar la solución hacia un servicio. Es decir, a diferencia de lo que ocurre con Python, que necesitará tener un gráfico abierto, si usamos MQL5 podremos utilizar un servicio para comunicarnos con Excel. Este enfoque tiene diversas ventajas. De hecho, puedo afirmarlo.

La mayor ventaja es que el servicio es independiente y puede interactuar con el gráfico o controlar casi por completo MetaTrader 5, o incluso no interactuar con él. Cuando usamos un servicio, podemos abrir y cerrar un gráfico, agregar cosas a él, cambiar lo que se está ejecutando, etc. Pero lo más importante es que, como el servicio se ejecuta fuera del gráfico, se puede utilizar incluso si MetaTrader 5 se está utilizando para otro propósito que no esté relacionado directamente con el mercado.

Y sí, podemos usar MetaTrader 5 para otras cosas, además de para negociar activos. Pero quizá lo explique en otro momento. Eso sí, solo si considero que es algo realmente interesante de mostrar. Entonces quedamos decididos. Vamos a usar MQL5 y a hacer que la parte del código que se ejecutará en MetaTrader 5 se realice en forma de servicio. Así que pasamos a la implementación.


Implementación

Implementar la parte que se ejecutará aquí en MetaTrader 5 no es complicado. Pero hay diversos aspectos a los que hay que prestar atención. Esto es para que tú, querido lector, consigas hacer que el sistema funcione de verdad. Recuerda una cosa: no se ejecutará un único programa. En realidad, estarás ejecutando tres programas a la vez. Es importante que cada uno se implemente y se construya de forma que trabajen y se comuniquen entre sí. Es crucial que cada uno sepa qué está intentando o deseando hacer el otro. Por esta razón, es muy importante que pruebes el sistema poco a poco.

En primer lugar, crea el código en Python, que será el servidor. Después, crea y prueba el código en VBA, que se ejecutará en Excel. Y solo cuando Excel se comunique efectivamente con el servidor en Python y logre darle órdenes, deberás pasar a esta parte en MetaTrader 5.

Por tanto, mi consejo para quienes deseen crear un sistema o implementación de este tipo y no tengan mucha experiencia en el uso de varios programas a la vez es que vayan poco a poco. No intentes implementar todo de una sola vez. Crea primero un plan y ve avanzando gradualmente. Dicho esto, veamos el código fuente, que se puede consultar completo justo a continuación:

01. //+------------------------------------------------------------------+
02. #property service
03. #property copyright "Daniel Jose"
04. #property version   "1.00"
05. //+------------------------------------------------------------------+
06. input string   user01 = "127.0.0.1";    //Address Server
07. input int      user02 = 9090;           //Port Server
08. //+------------------------------------------------------------------+
09. #define def_SizeBuff     2048
10. //+------------------------------------------------------------------+
11. void OnStart()
12. {
13.     bool tab;
14.     int sock;
15.     uint len, id, iMem;
16.     char buff[], ArrMem[];
17.     string szMsg, szCmd, szRet;
18.     
19.     sock = INVALID_HANDLE;
20.     ArrayResize(ArrMem, def_SizeBuff);
21.     while (!IsStopped())
22.     {
23.         Print("Trying to connect...");
24.         while (!IsStopped())
25.         {
26.             if (sock != INVALID_HANDLE)
27.                 SocketClose(sock);
28.             if ((sock = SocketCreate()) != INVALID_HANDLE)
29.                 if (SocketConnect(sock, user01, user02, 1000))
30.                     break;
31.                 else
32.                     Sleep(500);
33.         }
34.         if (!IsStopped())
35.         {
36.             szMsg = "<MT5 with Excel>:MT5";
37.             len = StringToCharArray(szMsg, buff) - 1;
38.             SocketSend(sock, buff, len);
39.             Print("Excel is online...");
40.         }
41.         ArrayInitialize(ArrMem, 0);
42.         iMem = 0;
43.         while (!IsStopped() && SocketIsConnected(sock))
44.         {
45.             szCmd = szRet = "";
46.             id = 0;
47.             do
48.             {
49.                 len = SocketIsReadable(sock);
50.                 len = ((iMem + len) < def_SizeBuff ? len : def_SizeBuff - iMem);
51.                 if (SocketRead(sock, buff, len, 500) > 0)
52.                     ArrayInsert(ArrMem, buff, iMem);
53.                 for (int c0 = 0; (ArrMem[c0] != 0) && (c0 < def_SizeBuff); c0++) switch (ArrMem[c0])
54.                 {
55.                     case '[':
56.                         id = 1;
57.                     case ';':
58.                         if ((SymbolExist(szMsg, tab)) && (id < 2))
59.                             szRet += StringFormat("%f%s", iClose(szMsg, PERIOD_D1, 0), (ArrMem[c0] == ';' ? ";" : ""));
60.                         szMsg = "";
61.                         break;
62.                     case ']':
63.                         id = 2;
64.                         iMem = 0;
65.                         break;
66.                     default:
67.                         switch (id)
68.                         {
69.                             case 0:
70.                                 szMsg += StringFormat("%c", ArrMem[c0]);
71.                                 break;
72.                             case 1:
73.                                 szCmd += StringFormat("%c", ArrMem[c0]);
74.                                 break;
75.                             case 2:
76.                                 for (iMem = 0; (ArrMem[c0 + iMem] != 0) && ((c0 + iMem) < def_SizeBuff); iMem++);
77.                                 ArrayCopy(ArrMem, ArrMem, 0, c0, iMem);
78.                                 break;
79.                     }
80.                 }
81.             }while (SocketIsConnected(sock) && (!IsStopped()) && (id != 2));
82.             if (!IsStopped() && SocketIsConnected(sock))
83.             {            
84.                 if (szCmd != "")
85.                 {
86.                     Print(szCmd, "<CMD<");
87.                     szRet = "N/D";
88.                 }
89.                 len = StringToCharArray(szRet, buff) - (szCmd != "" ? 1 : 0);
90.                 SocketSend(sock, buff, len);
91.             }
92.         }
93.     }
94.     if (sock != INVALID_HANDLE)
95.         SocketClose(sock);
96.     ArrayFree(ArrMem);
97.     Print("Shutting down...");
98. }
99. //+------------------------------------------------------------------+

Código en MQL5

Antes de empezar a explicar este código, quiero dejar claro que solo tiene fines didácticos. Lo que hacemos aquí es rascar solo la superficie. No consideres que esto es todo lo que podemos hacer. Pero, si entiendes lo que está ocurriendo, podrás hacer muchas cosas interesantes, querido lector y aspirante a programador de calidad. Para ello, utiliza estos códigos vistos hasta ahora como un primer paso y una posible referencia.

Muy bien, empecemos entonces a entender qué hace este código. Pero antes, para que estés aún más entusiasmado y atento a la explicación, ¿qué te parece si vemos qué sucede cuando todo está funcionando? Pues bien, eso es justo lo que puedes ver a continuación. Primero, observa lo que está ocurriendo en Excel. Recuerda que, mientras se producía esta animación, el servicio ya se estaba ejecutando en MetaTrader 5, como podrás ver en la otra animación.

Al observar la caja de mensajes de MetaTrader 5 mientras sucedían cosas en Excel, se podían ver las siguientes acciones:

Es interesante, ¿verdad? Hay que recordar que estas dos aplicaciones, tanto Excel como MetaTrader 5, pueden estar en máquinas diferentes. Aun así, obtendrías los mismos resultados. Ahora que ya te he picado la curiosidad, veamos cómo funciona este código en MQL5, ya que las demás partes ya fueron explicadas en los artículos anteriores.


Desmenuzando el código en MQL5

En la segunda línea, indicamos que el código será un servicio. Si esta línea no existiera, este mismo código sería un script. Ya expliqué en artículos anteriores la diferencia entre un servicio y un script. Pero, si tienes alguna duda, recuerda lo siguiente: un servicio no está directamente vinculado a un gráfico. En cambio, un script sí está ligado a un gráfico. No obstante, tanto el código de un servicio como el de un script serán básicamente idénticos. La única diferencia entre ellos es precisamente esta línea dos.

Lo siguiente que hay que entender son precisamente las líneas seis y siete. Estas sirven para que, cuando el usuario lance el ejecutable en MetaTrader 5, pueda pasarle algunos parámetros. Dichos parámetros son exactamente los que necesitan ajustarse. Es decir, la dirección donde se está ejecutando el servidor Python y el puerto de este.

Atención a este detalle: no se debe informar de dónde se está ejecutando Excel, sino de dónde se está ejecutando el servidor Python. Este tipo de cosas puede resultar un poco confuso. Pero recuerda lo siguiente: el servidor Python no está incorporado de ninguna forma en Excel y puede estar en otra máquina. Sin embargo, es necesario que Excel sepa cómo localizar ese servidor. Para entenderlo mejor, consulta el artículo anterior, donde expliqué la parte del código que existirá en Excel y que está escrita en VBA.

Una vez completada esta parte inicial y básica, llegamos a la línea 11, que es donde realmente comienza a ejecutarse el código. Entre las líneas 13 y 17 se declaran algunas variables que se usarán en este código en particular. Ahora viene la parte que quizá pueda resultar un poco confusa al principio, pero que tendrá todo el sentido después. Observa que en la línea 19 inicializamos una de las variables. El motivo es que todo el código está completamente contenido en un gran bucle. Este bucle se inicia en la línea 21 y se extiende hasta la línea 93, por lo que la única forma de finalizarlo es deteniendo el servicio manualmente o cerrando MetaTrader 5.

Para saber en qué estado nos encontramos en términos de conexión con el servidor, imprimiremos algunos mensajes en la caja de mensajes de MetaTrader 5, como viste en las animaciones anteriores. El primer mensaje se imprime en la línea 23. En él, simplemente indicamos que el cliente, es decir, MetaTrader 5, está intentando conectarse. Esto se debe a que, en la línea 24, entramos en un bucle infinito. Este bucle es infinito porque solo se finaliza cuando se finaliza el programa.

Pero espera un momento. La idea de colocar un bucle infinito dentro de otro no tiene ningún sentido. ¿Por qué hacer esto? Calma, querido lector, calma. Este bucle de la línea 24 es infinito, pero se finaliza en un momento muy concreto. Sin embargo, como la variable que contiene el socket ya puede contener algún valor, primero necesitamos liberar el socket antiguo. Esto se comprueba y se hace en la línea 26, y la liberación ocurre en la línea 27. Por esta razón, es importante que exista la línea 19. Si no configuráramos la variable indicando que no hay conexión, dudaríamos a la hora de realizar esta liberación en la línea 27.

Entonces quedamos en que se haría. Si existía una conexión, se cerrará. Si no existía, no hacemos nada. No obstante, en la línea 28 intentamos crear un socket. Esto, muy probablemente, tendrá éxito. Pero asignar un socket no nos indica necesariamente que se haya producido una conexión. Por lo tanto, si en la línea 29 no logramos conectarnos al servidor, se ejecutará la línea 32. Esta producirá una pequeña pausa para que podamos intentarlo de nuevo.

Sin embargo, y aquí está el quid de la cuestión del bucle infinito de la línea 24, si no logramos conectarnos al servidor, habremos asignado un socket. En ese caso, debemos devolverlo al sistema operativo. Entonces, volvemos a la comprobación de la línea 26. Pero esta vez la comprobación será exitosa y se ejecutará la línea 27, que libera el socket asignado. Y repetimos este proceso de asignación y liberación del socket hasta que logremos conectarnos o hasta que el usuario finalice el programa.

Ahora bien, si observas la animación de arriba, verás que en un momento dado comenzamos a transmitir y recibir datos. Pero, si este bucle de la línea 24 nunca se finaliza, ¿cómo pudo ocurrir esto? El motivo es precisamente la línea 29. Observa que, cuando tengamos éxito y logremos conectarnos al servidor, se ejecutará la línea 30 y saldremos del bucle iniciado en la línea 24.

Ahora mira qué cosa tan interesante. En la línea 34, solo tendremos éxito si el programa no ha sido finalizado por el usuario. Es decir, en este caso estamos conectados al servidor. Por tanto, necesitamos decirle al servidor quiénes somos. Así, el mensaje que se enviará al servidor se crea en la línea 36. Presta atención a este mensaje. El servidor debe reconocerlo. Si no es así, el servidor desconectará al cliente y volveremos al bucle de la línea 24. Por tanto, presta mucha atención si vas a realizar cualquier cambio en el sistema en el futuro. Pero si todo ha ido bien y el servidor nos ha reconocido como un cliente válido, tendremos que hacer algunas cosas y tomar ciertas precauciones. Por esta razón, en la línea 41 se realiza la limpieza de un buffer de memoria. Justo después, en la línea 42, apuntamos a la posición cero de ese buffer.

Si estás empezando en el mundo de la programación de sockets, seguro que no entiendes la razón de este trabajo en las líneas 41 y 42. Pero, si ya tienes experiencia, sabrás que, cuando se escribe en un socket, puede acumular mucha más información de la que esperamos ver al leerlo. Y, para ser más específico, esto ocurre mucho en conexiones de tipo TCP. Como no queremos perder ninguna solicitud o requerimiento de Excel a través del servidor, debemos tomar precauciones para evitar la pérdida de información. Por esta razón, es necesario hacer algunas cosas. Pero para entender mejor cómo se hace y por qué es necesario, necesitamos ver un poco más del código.

Entonces, entramos en un nuevo bucle, que es el principal, es decir, el responsable del intercambio de mensajes entre Excel y MetaTrader 5. Este bucle se inicia en la línea 43. Ahora, fíjate en la declaración de este bucle. Observa que estamos comprobando la finalización del programa y si el socket sigue conectado. Supongamos que todo está en orden y que podemos entrar y permanecer en este bucle durante mucho tiempo.

Así, las primeras cosas que hay que hacer son inicializar algunas variables. Esto se hace en las líneas 45 y 46, y justo después entramos en otro bucle que va desde la línea 47 hasta la 81. Presta mucha atención a lo que ocurre dentro de este nuevo bucle. Esto es importante porque es en él donde deberás realizar los cambios o mejoras si deseas o necesitas hacer otras cosas además de las que estoy mostrando y comentando. Esto probablemente ocurrirá cuando sea necesario pasar más información a Excel. O incluso para entender los comandos que llegarán a Excel.

En la línea 48, por ejemplo, vemos cuánta información hay en el socket. A continuación, en la línea 51, intentamos leer esa misma información. Sin embargo, hay un pequeño detalle que quizá quieras cambiar. En la línea 49, verificamos si la cantidad de información que se colocará en el búfer de memoria excede el tamaño del búfer asignado. En este caso, simplemente cambio la cantidad de datos que se van a leer para que no exceda el tamaño ya asignado. No obstante, si lo deseas, puedes cambiar el tamaño del área asignada. De todas formas, el resultado final será muy parecido.

Dada esta explicación sobre el motivo de la línea 50, podemos pasar a la línea 51. Observa que, si se lee cualquier dato, en la línea 52 se insertarán dichos datos en la memoria asignada. En este punto de la explicación, la línea 52 no tiene ningún sentido, es casi como si no existiera. Pero sigamos viendo cómo funciona el código; así, esta línea pasará a tener sentido. No obstante, es importante que entiendas que los datos leídos del socket se colocarán a partir de una posición determinada. Esa posición la indica la variable iMem. No olvides este detalle, ya que en la primera lectura realizada, la variable iMem contiene el valor cero. ero puede ser que en las siguientes lecturas tenga un valor diferente.

Así llegamos a la línea 53. Aquí iniciamos un bucle que constituye el núcleo de este código, ya que realizará gran parte del trabajo. Observa que en él verificamos algunas condiciones; si se satisfacen, se ejecutará una serie de pequeños pasos. Dichos pasos representan el protocolo de comunicación entre MetaTrader 5 y Excel. Por lo tanto, cualquier cambio que se realice aquí también deberá tenerse en cuenta en el código de VBA, ya que VBA se encargará de las respuestas de MetaTrader 5. Si el tratamiento se realiza en el código del servidor, también habrá que realizar los cambios correspondientes en el código de Python.

Este bucle de la línea 53 recorrerá el mensaje publicado carácter por carácter para entender qué está ocurriendo y, principalmente, saber cómo proceder. Sin embargo, debo hacer una salvedad: este código tiene como finalidad ser didáctico. Sin embargo, si logras entender cómo funcionan aquí las cosas, podrás adaptar este mismo código a tus necesidades particulares.

Seguramente se te ocurrirán otras formas de hacer lo mismo que se está haciendo aquí. Una de ellas sería usar la función StringSplit. No estarías equivocado al hacerlo, simplemente sería algo más complicado. Dependerá, por supuesto, del protocolo de mensajes que vayas a usar. En este caso, el protocolo es bastante simple. Antes del corchete, tenemos el símbolo que debe observarse. Dentro del corchete, tenemos el comando que debe ejecutarse. Así de simple. Pero, como en este caso no se trata de la parte de los comandos que representan compra y venta a mercado, no tendrás esta funcionalidad. Pero no te preocupes por eso.

Al final del artículo, proporcionaré las referencias necesarias para hacerlo, ya que esta función ya está implementada en el sistema de repetición/simulación. Pero quien no siga esta secuencia no sabrá cómo hacerlo. Sin embargo, no es difícil. Solo necesitarás crear el protocolo. Para crear dicho protocolo, necesitarás saber cómo ejecutar los comandos indicados. Si no sabes cómo hacerlo, no olvides revisar los artículos que dejaré como referencia.

Entonces, volviendo al código, encontramos algo que puede confundir a mucha gente, sobre todo a quienes estén empezando. Observa la línea 55. En este punto, tenemos un abre corchete. Este indica el final del nombre de un símbolo y el inicio de un comando de Excel. Para diferenciar las cosas, en la línea 56 cambiamos el valor de la variable id, que era cero, a uno. No olvides este detalle. Cuando el bucle se inició, el valor de la variable id era cero debido a la línea 46. Esto ocurrió la primera vez que el bucle de la línea 43 comenzó a ejecutarse. Presta mucha atención a estos detalles.

Como un abre corchete indica que el nombre del símbolo ya se ha capturado, necesitamos obtener los datos de este símbolo. En este caso, solo vamos a tomar el precio de cierre de la barra. Solo eso, pero puedes capturar la información que desees o necesites. Para ello, bastará con crear las reglas que indiquen qué valor debe obtenerse. Pero volvamos a la cuestión principal. Observa que la case de la línea 55 invade la case de la línea 57, sin que exista un comando break entre ellas. ¿Es esto posible? Sí, podemos hacer esto. Sin embargo, antes de explicar la case de la línea 57, observa que se trata de otro carácter. ¿Por qué?

Ahora viene la parte que realmente marca la diferencia. El carácter que aparece en la case de la línea 57 indica que es posible separar varios símbolos. Es decir, si Excel quiere buscar información de varios símbolos, puede hacerlo separándolos mediante este carácter. Sin embargo, si consultas el código VBA del artículo anterior, observarás que no se hace uso de dicha funcionalidad. Simplemente imprime el retorno en una única celda. De hecho, esto es un reto para ti, querido lector: separa estos datos y transfórmalos a la celda adecuada. Como no conozco la forma en que cada uno construye su hoja de cálculo, la manera de realizar esta separación cambiará de un caso a otro. Pero no es algo complicado de hacer. Solo dependerá de cómo hayas creado tu hoja de cálculo.

De cualquier forma, en la línea 58 probaremos si el símbolo buscado existe. Si es así, en la línea 59 crearemos una string de retorno. Pero atención a esto. A pesar de que estemos creando una string de retorno, en realidad no será esta la que devolveremos al servidor y, posiblemente, a Excel. Más adelante entenderás el motivo. Ahora, como acabamos de procesar un símbolo, en la línea 60 limpiamos la string para intentar capturar el siguiente y, en la línea 61, utilizamos el comando break para no invadir la siguiente case.

En la siguiente case, que está en la línea 62, tenemos un cierre de corchete. Esto indica que el comando dado por Excel fue capturado y entraremos en lo que rige el nombre del siguiente símbolo. Pero, aunque existan más informaciones leídas del socket, estas no se usarán ahora. Esto se debe a que, en la comprobación de la línea 58, se percibirá que la línea 63 indica que no se utilicen los datos. Muy bien, esta es la parte en la que separamos los símbolos del comando. Pero necesitamos saber qué es cada cosa. En caso de que ninguna case se ejecute, se ejecutará la opción predeterminada, que se encuentra en la línea 66.

Observa lo siguiente: el tipo de información y el tratamiento que se le dará a dicha información dependerán del valor de la variable id. Así, mientras sea cero, se capturará el nombre del símbolo. Esto se hace en la línea 70. Cuando id sea uno, se capturará el comando dado por Excel. Esto se hace en la línea 73. Si el valor es dos, moveremos los datos desde la posición actual hasta el inicio de la región de memoria.

Ahora, fíjate en lo que hace que el bucle iniciado en la línea 47 finalice en la 81. Una de las causas será precisamente el hecho de haber capturado el final del bloque de comandos. Con esto, entramos en la parte final del trabajo. Sin embargo, antes necesitamos realizar otra comprobación en la línea 82. Si tenemos éxito, obtendremos una nueva comprobación. Esta tiene como objetivo verificar si se está enviando algún comando. Si lo hay, dicho comando tendrá prioridad sobre cualquier otra cosa. Y es en este punto, en la línea 86, donde deberás hacer lo que se ha visto en otros artículos de esta misma secuencia. Así lograrás ejecutar una solicitud de compra o venta proveniente de Excel.

Para hacerlo de forma adecuada, estudia el material de apoyo que indicaré en el apartado de referencias. Como respuesta a la solicitud de ejecución de un comando, el valor de retorno o respuesta de MetaTrader 5 se modifica y deja de ser los datos capturados de los símbolos para pasar a ser una string de caracteres específica. Al final, en las líneas 89 y 90, se envía la respuesta de MetaTrader 5. Observa que esta respuesta dependerá de si estamos ejecutando un comando o capturando datos de algún símbolo.


Consideraciones finales

Aunque en este código no se ha incluido la implementación de cómo ejecutar un comando dado por Excel, podrás observar que la comunicación entre Excel y MetaTrader 5 se realiza de forma bastante fluida y sin muchos contratiempos. No obstante, es muy probable que sientas la necesidad de realizar algunas pequeñas mejoras y ajustes en esta implementación. No obstante, si esto ocurre, significará que, de hecho, logré alcanzar mi objetivo en esta fase, en la que expliqué cómo hacer uso de los sockets, ya que mucha gente desconocía que es posible operar en un mercado sin necesidad de estar mirando el gráfico de MetaTrader 5 y haciendo uso de algún tipo de análisis fundamental.

Aunque para implementar realmente la parte responsable del envío de órdenes sea necesario que implementes otras cuestiones en este sistema, no veo ningún problema en no mostrar cómo hacerlo aquí. Lo que quiero es que tengas claro lo que vas a hacer. Por esta razón, no mostraré la implementación final. Pero, si estudias los artículos de referencia, con toda seguridad lograrás implementar dicha funcionalidad. En el próximo artículo, abordaremos otro tema que, al igual que este sobre sockets, es necesario explorar antes de volver a dirigir nuestra atención al sistema de repetición/simulador.


Referencias:

Desarrollo de un sistema de repetición (Parte 74): Un nuevo Chart Trade (I)

Desarrollo de un sistema de repetición (Parte 75): Un nuevo Chart Trade (II)

Desarrollo de un sistema de repetición (Parte 76): Un nuevo Chart Trade (III)

Desarrollo de un sistema de repetición (Parte 77): Un nuevo Chart Trade (IV)

Desarrollo de un sistema de repetición (Parte 78): Un nuevo Chart Trade (V)

ArchivoDescripción
Experts\Expert Advisor.mq5
Demuestra la interacción entre Chart Trade y el Asesor Experto (es necesario el Mouse Study para la interacción)
Indicators\Chart Trade.mq5Crea la ventana para configurar la orden a ser enviada (es necesario el Mouse Study para la interacción)
Indicators\Market Replay.mq5Crea los controles para la interacción con el servicio de reproducción/simulador (es necesario el Mouse Study para la interacción)
Indicators\Mouse Study.mq5Permite la interacción entre los controles gráficos y el usuario (necesario tanto para operar el sistema de repetición como en el mercado real)
Servicios\Market Replay.mq5Crea y mantiene el servicio de reproducción y simulación de mercado (archivo principal de todo el sistema)
Código VS C++\Server.cppCrea y mantiene un socket servidor desarrollado en C++ (versión MiniChat).
Code in Python\Server.pyCrea y mantiene un socket en Python para la comunicación entre MetaTrader 5 e o Excel
Scripts\CheckSocket.mq5Permite realizar una prueba de conexión con un socket externo
Indicators\Mini Chat.mq5Permite implementar un minichat mediante un indicador (requiere el uso de un servidor para funcionar)
Experts\Mini Chat.mq5Permite implementar un mini chat mediante un Asesor Experto (requiere el uso de un servidor para funcionar)

Traducción del portugués realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/pt/articles/12829

Archivos adjuntos |
Anexo.zip (560.03 KB)
William da Paz
William da Paz | 27 abr 2025 en 03:07
Excelente trabajo mi amigo!

¿Hay alguna manera de que podamos sacar los datos del libro y / o tiempos y operaciones en Excel o incluso Python?

Gracias por su atención!
Redes neuronales en el trading: Optimización LSTM para la previsión de series temporales multivariantes (DA-CG-LSTM) Redes neuronales en el trading: Optimización LSTM para la previsión de series temporales multivariantes (DA-CG-LSTM)
En este artículo presentamos el algoritmo DA-CG-LSTM, que ofrece nuevos enfoques para el análisis y la previsión de series temporales. En él aprenderemos cómo los innovadores mecanismos de atención y la flexibilidad de los modelos mejoran la precisión de las predicciones.
Websockets para MetaTrader 5: conexiones de cliente asíncronas con la API de Windows Websockets para MetaTrader 5: conexiones de cliente asíncronas con la API de Windows
Este artículo detalla el desarrollo de una biblioteca personalizada vinculada dinámicamente y diseñada para facilitar las conexiones asíncronas de clientes WebSocket para las aplicaciones MetaTrader 5.
Del básico al intermedio: Estructuras (VII) Del básico al intermedio: Estructuras (VII)
En este artículo se mostrará cómo podemos abordar los problemas para estructurar las cosas y crear una solución más sencilla y atractiva. Aunque el contenido está orientado a la didáctica y, por lo tanto, no se trata de un código real, es necesario asimilar muy bien los conceptos y conocimientos que se verán aquí. Así, en el futuro, podrás seguir los códigos que iremos mostrando.
Desarrollamos un asesor experto multidivisas (Parte 26): Informador para instrumentos comerciales Desarrollamos un asesor experto multidivisas (Parte 26): Informador para instrumentos comerciales
Antes de continuar con el desarrollo de asesores expertos multidivisas, vamos a intentar crear un nuevo proyecto utilizando la biblioteca desarrollada. Usando este ejemplo, descubriremos cómo organizar mejor el almacenamiento del código fuente y cómo puede ayudarnos el uso del nuevo repositorio de código de MetaQuotes.