Русский Português
preview
Simulación de mercado (Parte 15): Sockets (IX)

Simulación de mercado (Parte 15): Sockets (IX)

MetaTrader 5Probador |
153 0
Daniel Jose
Daniel Jose

Introducción

En el artículo anterior, «Simulación de mercado (Parte 14): Sockets (VIII)», expliqué cómo puedes hacer ciertas cosas con Python sin depender de paquetes ni herramientas de terceros. No pretendo decirte que no uses paquetes que te ayuden a realizar tareas en Python, pero el objetivo de estas demostraciones es precisamente motivarte para que estudies los conceptos con más interés. No tiene sentido depender de paquetes o soluciones externas cuando puedes hacer las cosas basándote en lo que te permite tu lenguaje favorito.

Pues bien, creo que en ese artículo logré despertar tu curiosidad respecto a algunos temas de los que mucha gente no sabe cómo funcionan. Considero que la mayoría, si ha realizado algún curso o estudio basado en lo que comúnmente se enseña, jamás ha oído hablar de ciertas tecnologías. Un ejemplo es la tecnología COM, que mencioné brevemente y de forma bastante superficial en el artículo anterior. Sin embargo, conocer cómo hacer las cosas con estos métodos te será de gran ayuda en todas las etapas de la programación.

Entonces, en este artículo, comenzaré a explicar una de las posibles soluciones para lo que he estado intentando mostrar. Es decir, cómo permitir que un usuario de Excel realice una acción en MetaTrader 5 sin enviar órdenes ni abrir o cerrar una posición. La idea es que el usuario utilice Excel para realizar un análisis fundamental de algún símbolo. Y que, usando únicamente Excel, pueda indicar a un Asesor Experto que se esté ejecutando en MetaTrader 5 que debe abrir o cerrar una posición determinada.

Hasta ahora, todo lo que se ha mostrado y demostrado tiene como único objetivo transferir datos, como si estuviéramos usando un chat. Sin embargo, creo que ha sido más fácil para ti, estimado lector, que no tienes tanta experiencia con los sockets, comprender los conceptos básicos gracias a estos métodos. Recuerda que solo estoy rascando la superficie de un gran iceberg, que se llama sockets. Te aconsejo que estudies mucho más a fondo esta tecnología, pues si llegas a entender cómo funciona, te encantará y te entusiasmarán las posibilidades que se abrirán.

Pero vayamos a lo que realmente nos interesa en este artículo. Como las cosas que hay que hacer son, en su mayoría, relativamente complicadas y otras bastante simples, lo explicaré con calma. De esta manera, aunque no llegue a mostrarlo todo, entenderás cómo funciona. Si se alcanza este objetivo, podrás modificar y adaptar lo que muestre para tener tu propia solución, que muy probablemente podrá superar con creces lo que voy a presentar. El objetivo es ser lo más didáctico posible, así que empecemos.


Creación del servidor en Python

Como quedó claro en los artículos anteriores, no es posible crear y ejecutar un servidor directamente en Excel. Podríamos hacerlo, pero para ello tendríamos que hacer un verdadero malabarismo para evitar que el servidor comprometiera la experiencia de uso de Excel. Una forma de hacerlo es construir el servidor en un hilo. Sin embargo, construir y ejecutar un servidor en un hilo en Excel es una tarea bastante complicada. No es la tarea más complicada, pero sin duda es mucho más complicada que la propuesta que se hará aquí.

Entonces, lo primero que hay que hacer es construir un servidor aislado en Python. Este servidor accederá, en realidad, a la hoja de cálculo de Excel. Sin embargo, hay algunos detalles que deben tenerse en cuenta. De nuevo, la idea es ser didáctico. Lo que presentaré puede mejorarse enormemente. A continuación, podemos ver el código primario del servidor en Python. Lo llamo «primario» porque este código se puede perfeccionar y adaptar a tus necesidades, y solo es necesario ajustarlo en los puntos correctos. Pero, antes de hacer eso, ¿qué te parece si primero entendemos cómo funciona? Así tendrán mucho más sentido los cambios que podrás y necesitarás hacer.

001. import socket as sock
002. import select
003. import sys
004. from win32com import client as win32
005. 
006. class LinkMT5Excel:
007.     def __init__(self, host, port, sheet, cell) -> None:
008.         try:
009.             self.__CMD = ''
010.             self.__MT5 = None
011.             self.__server = sock.socket(sock.AF_INET, sock.SOCK_STREAM)
012.             self.__server.setblocking(False)
013.             self.__server.bind((host, int(port)))
014.             self.__server.listen()
015.             self.__CONN_LIST = [self.__server]
016.             EXCEL = win32.GetActiveObject('Excel.Application')
017.             self.__SHEET = EXCEL.Worksheets(sheet)
018.             self.__COLUNN, L = cell.split('$')
019.             self.__LINE = int(L)
020.         except:
021.             self.__CONN_LIST.clear()
022. 
023.     def __WriteInExcel(self, index, msg) -> None:
024.         try:
025.             if self.__SHEET:
026.                 self.__SHEET.Range(self.__COLUNN + str(self.__LINE + index)).Value = msg
027.         except:
028.             self.__SHEET = None
029.             self.__ShutdownServer()
030. 
031.     def __ReadInExcel(self, index) -> str:
032.         try:
033.             if self.__SHEET:
034.                 return self.__SHEET.Range(self.__COLUNN + str(self.__LINE + index)).Value
035.         except:
036.             self.__SHEET = None
037.             self.__ShutdownServer()    
038.         return ''
039. 
040.     def __MT5_Disconnect(self, conn) -> None:
041.         if conn == self.__MT5:
042.             self.__WriteInExcel(2, 'MetaTrader 5 is offline.')
043.             self.__MT5 = None
044.         if conn:
045.             conn.close()
046.             if self.__CONN_LIST:
047.                 self.__CONN_LIST.remove(conn)
048. 
049.     def __ShutdownServer(self) -> None:
050.         for conn in self.__CONN_LIST:
051.             conn.close()
052.         self.__CONN_LIST.clear()
053. 
054.     def __Command(self, cmd, conn) -> bool:
055.         if cmd.lower() == '/force server shutdown':
056.             self.__ShutdownServer()
057.             return True
058.         elif cmd.lower() == '/shutdown':
059.             self.__MT5_Disconnect(conn)
060.             return True
061.         self.__CMD = '' if cmd.lower() == 'n/d' else cmd
062.         return False
063.     
064.     def __Refused(self, conn) -> bool:
065.         conn.send('Connection Refused...\n\r'.encode())
066.         conn.close()
067.         return False
068. 
069.     def __Checking(self, conn) -> bool:
070.         try:
071.             info, cmd = conn.recv(512).decode().rstrip(None).split(':')
072.             if info.lower() != '<mt5 with excel>':
073.                 return self.__Refused(conn)
074.             if self.__Command(cmd, conn):
075.                 return True
076.             if (self.__MT5) or (cmd.lower() != 'mt5'):
077.                 return self.__Refused(conn)
078.             self.__MT5 = conn
079.             self.__WriteInExcel(2, 'MetaTrader 5 is online.')
080.         except:
081.             return self.__Refused(conn)
082.         return True
083.     
084.     def __SwapMsg(self, rec, conn) -> None:
085.         try:
086.             if rec:
087.                 data = conn.recv(1024).decode().rstrip(None)
088.                 if data:
089.                     if '/' in data:
090.                         if self.__Command(data, conn):
091.                             return
092.                     else:
093.                         self.__WriteInExcel(4, data)
094.                 else:
095.                     self.__MT5_Disconnect(conn)
096.                     return
097.             conn.send((self.__ReadInExcel(3) + f'[{self.__CMD}]').encode())
098.         except:
099.             self.__MT5_Disconnect(conn)
100. 
101.     def Run(self) -> None:
102.         self.__WriteInExcel(0, 'Server online.')
103.         self.__MT5_Disconnect(None)
104.         while self.__CONN_LIST:
105.             read, write, err = select.select(self.__CONN_LIST, [], [], 0.5)
106.             for slave in read:
107.                 if slave is self.__server:
108.                     conn, addr = slave.accept()
109.                     conn.setblocking(False)
110.                     if not self.__Checking(conn):
111.                         continue
112.                     self.__CONN_LIST.append(conn)
113.                     self.__SwapMsg(False, conn)
114.                 else:
115.                     self.__SwapMsg(True, slave)
116. 
117.     def __del__(self) -> None:
118.         for n in range(3):
119.             self.__WriteInExcel(n, '')
120.         self.__WriteInExcel(0, 'Server offline...')
121. 
122. if __name__ == '__main__':
123.     if len(sys.argv) == 5:
124.         Mt5_Excel = LinkMT5Excel(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
125.         Mt5_Excel.Run()
126.         del Mt5_Excel
127.     else:
128.         print(f'Usage: {sys.argv[0]} <HOST> <PORT> <SHEET> <CELL>')

Código en Python

Si has seguido esta fase del servicio de repetición/simulador, en la que me he centrado en explicar sockets, nada de este código te resultará realmente muy extraño. Y, si ya llevas algún tiempo estudiando Python, este código te resultará aún más sencillo de entender. Sin embargo, si no es tu caso, no te preocupes, porque vamos a entender qué está ocurriendo aquí. Así que, para quienes siguen la secuencia, tengamos paciencia con los demás, especialmente con quienes tienen menos experiencia en el área, ya que hay cosas en este código que necesitan ser bien entendidas.

Bien, entre las líneas uno y cuatro importamos algunos de los paquetes que necesitamos. Observa que no estamos utilizando ningún paquete fuera de la instalación estándar de Python y que tampoco estoy haciendo nada muy complicado en este punto. Podrías usar algún paquete como pandas, xlwings, openpyxl o cualquier otro para ejecutar algunos de los pasos que se mostrarán a lo largo de este artículo. Pero, para no dar la impresión de que se está discriminando a otros paquetes, haremos todo utilizando únicamente la instalación estándar de Python. De este modo, resulta más sencillo para ti elegir el paquete que prefieras y utilizar la opción que consideres mejor. La idea aquí es ser lo más simples posible, sin inclinar la balanza hacia ninguna dirección específica.

Muy bien, una vez realizadas dichas importaciones, comenzamos creando una clase en la línea seis. Podríamos hacerlo sin usar clases, pero, si las usamos, podemos beneficiarnos de otras ventajas. Así, en la línea siete, empezamos definiendo el inicializador de la clase. Aquí recibimos algunos argumentos que nos indican cosas importantes para que el servidor funcione correctamente. Observa dónde se utilizan esos parámetros para entender qué se espera y cómo mejorar este mismo código. 

En las líneas nueve y diez, declaramos e inicializamos dos variables que serán importantes más adelante. En la línea 13, empezamos a usar los argumentos pasados. Observa que le indicamos al servidor cuál es el host, es decir, desde dónde esperamos recibir una conexión. Si este valor de host es 0.0.0.0, indica que aceptaremos cualquier dirección de cliente, pero también puede ser un valor específico. Esto queda a tu criterio. Un detalle importante en esta línea es que, como la inicialización del servidor se realizará desde Excel, los argumentos pasados serán strings. Por esta razón, es necesario convertir el valor de la string en un valor adecuado, que en este caso es un entero, para indicar el puerto que se usará. Así, Python sabrá interpretar correctamente el valor que debe emplearse. Las demás líneas, es decir, las comprendidas entre las líneas 11 y 14, se encargan de inicializar el socket para que el servidor pueda quedarse observando el puerto y esperando una conexión. Si tienes alguna duda al respecto, consulta los artículos anteriores.

Ahora volvamos a la línea ocho, ya que, aunque los pasos anteriores no deberían generar fallos sin una buena razón, en esta línea ocho abrimos un punto para analizar posibles errores en el código. Dichas fallas ocurren en tiempo de ejecución (run-time). Por lo tanto, para que el usuario no vea cosas extrañas cuando se ejecute el script, hacemos que cualquier excepción sea tratada por el propio código.

Así, en la línea 16, intentamos capturar la sección activa de Excel. Como el servidor se inicializará por sí solo, tendremos éxito al hacerlo. Sin embargo, en la línea 17 hay algo que puede fallar. En este punto, intentamos acceder a una hoja de Excel. Esto puede fallar en cualquier momento, simplemente porque la hoja no exista en el libro, y necesitamos que exista. Si tenemos éxito, en la línea 18 capturaremos la celda específica que usará el servidor. Observa que hemos dividido este proceso en dos pasos. En la línea 18, capturamos la columna y un valor numérico. Este valor numérico se convierte en un entero en la línea 19 para poder realizar algunos cálculos sencillos en el servidor. Pero no te preocupes, esto se entenderá más adelante.

Ahora, lo que realmente necesitas comprender, estimado lector, es que si ocurre algún fallo durante esta inicialización, la línea 21 cerrará el servidor y evitará cualquier intento de enviar datos a Excel. Es importante hacerlo porque algo no se ha accedido o configurado correctamente y no queremos que el usuario vea mensajes que no entienda.

Bien, ahora comenzamos la ardua tarea de conseguir que las cosas funcionen. Comenzamos en la línea 23, donde tenemos un procedimiento que intentará escribir algo en Excel. Pero no escribiremos en cualquier sitio. Lo haremos de forma bastante controlada. Por lo tanto, necesitamos un índice para desplazarnos con respecto a la columna y la fila indicadas en la inicialización. Como el objetivo es únicamente didáctico, no usaremos la columna, solo la fila. Así, basándonos en el valor de la primera fila, intentaremos escribir en la hoja indicada durante la inicialización. Sin embargo, dado que este proceso puede fallar, en la línea 24 le indicamos a Python que espere un error.

En la línea 25, verificamos si la variable contiene algo válido. Esto es importante, pues puede suceder que, durante el apagado, la hoja no exista y no queremos entrar sin motivo en un bucle en el que el servidor intenta cerrarse, se genera una excepción que dispara un nuevo intento de salida y se vuelve a llamar al procedimiento, generándose otra excepción y así sucesivamente. Para evitar precisamente esto, realizamos una comprobación en la línea 25. A continuación, en la línea 26, intentamos escribir en la hoja de cálculo. En este punto puede ocurrir un error, ya que es posible que el usuario haya eliminado la hoja que el servidor necesita dentro del libro sin darse cuenta. En ese caso, se ejecutará la línea 27 y el código correspondiente, y el servidor se cerrará.

Ahora vamos a la línea 31. En esta línea se captura el contenido de una celda específica de la hoja de cálculo. Dicha celda tiene como referencia la indicada durante la inicialización. Por eso es tan importante hacer las cosas con calma y entender lo que está ocurriendo. Del mismo modo que al intentar escribir en una celda el proceso puede fallar, aquí puede suceder lo mismo. Sin embargo, si la lectura se produce como se espera, en la línea 34 devolveremos el valor de la celda para que el servidor pueda utilizarlo.

Tal vez hayas pensado en lo siguiente: si esta función de la línea 31 logra leer la hoja de cálculo de Excel, ¿por qué no indicar simplemente durante la inicialización cuál es la hoja y la celda, para que el servidor busque el resto de la información directamente en Excel? Si has pensado en eso, mis más sinceras felicitaciones. Esto indica que ya has percibido una posible mejora que se puede hacer aquí, en el script de Python. Pero continuemos, porque aún queda mucho por ver.

En la línea 40, tenemos un procedimiento que ayuda al usuario de Excel a saber cuándo MetaTrader 5 se ha vuelto inaccesible por cualquier motivo. Esto ocurre cuando se ha desconectado. Dicho procedimiento es bastante simple y no requiere mayores explicaciones. En la línea 49, tenemos otro procedimiento igualmente sencillo para desconectar el servidor por cualquier motivo. Muchos de estos motivos se deben a fallos durante la ejecución del script del servidor, aunque existen otros que explicaré más adelante. Por ahora, no te preocupes por eso. Además, en la línea 54 tenemos una función muy interesante. A partir de aquí, las cosas se ponen realmente interesantes. Pero primero veamos qué ocurre en esta función de la línea 54.

Es bastante simple y tiene como objetivo analizar algún comando que pueda haber sido enviado al socket. Dicho comando deberá ser ejecutado por el servidor. Por el momento, solo tenemos dos comandos. El primero se encuentra en la línea 55 y su objetivo es forzar el apagado del servidor, algo muy sencillo y directo. El segundo comando está en la línea 58 y forzará la desconexión del cliente, que en este caso es MetaTrader 5. Si no se ha realizado ninguna solicitud al servidor para ejecutar un comando, en la línea 62 se devolverá un valor falso. Es decir, lo que se envió no era un comando.

Pero, ¿por qué estamos devolviendo un valor falso? La razón está precisamente en la función de la línea 69. Su objetivo principal es verificar si el cliente que intenta conectarse al servidor debe ser aceptado. Aquí es donde la cosa se vuelve realmente interesante, ya que, en principio, cualquiera podría conectarse al servidor. Sin embargo, esta función tiene como propósito impedirlo. ¿Y cómo lo hace? Simplemente probando lo que el cliente enviará al socket tan pronto como el servidor acepte revisar la conexión. Así, en la línea 72, verificamos el encabezado inicial de la conexión. Solo durante el intento de conexión debe estar presente dicho encabezado, pero durante todo el resto del tiempo ya no será necesario. Más adelante entenderás cómo funciona realmente.

Lo que debe quedar claro aquí es que en la línea 71 se realiza una separación entre el encabezado y algún comando enviado. El motivo de esto es sencillo y se comprenderá en el próximo artículo, donde veremos la parte correspondiente del código en VBA de Excel. Si el encabezado proporcionado por el cliente no coincide con el que espera el servidor, se ejecutará la función de la línea 64. Dicha función informará al cliente de que el servidor lo está desconectando, ya que no ha sido reconocido.

Si el encabezado es el esperado, en la línea 74 intentaremos ejecutar algún comando enviado por el cliente. Si no se trata de un comando, en la línea 76 comprobaremos si ya existe alguna conexión con MetaTrader 5. Si existe, o si el comando es diferente al esperado, lo que indicaría que el cliente no es MetaTrader 5, se denegará la conexión. En el último caso, en las líneas 78 y 79 tendremos la información de que MetaTrader 5 está en línea. Si en cualquier momento se produce una excepción, la conexión será rechazada debido a la ejecución de la línea 80.

Ahora llegamos a un procedimiento crucial, que se encuentra en la línea 84. ¿Y qué hace este procedimiento? Se encarga del intercambio de mensajes entre MetaTrader 5 y Excel. Presta atención, porque aunque este procedimiento es relativamente simple, si no lo entiendes, no podrás adaptar el código a lo que deseas hacer. Es cierto que, después de ver los próximos artículos, todo esto tendrá pleno sentido. Pero, por ahora, intentemos entender lo que está ocurriendo aquí en el script de Python.

Como pueden producirse errores, iniciamos el código indicando a Python que esperamos que se produzcan. Esto se hace en la línea 85. Si el autor de llamada indica que este procedimiento debe leer el socket, la línea 86 tendrá éxito y entraremos en la parte de lectura del socket. Esto se realiza en la línea 87.

Ahora presta mucha atención a lo que voy a explicar, porque será de gran importancia más adelante. En la línea 88, verificamos si hemos recibido algo en el socket. Si no es así, desconectamos MetaTrader 5. Si hay algo en el socket, en la línea 89 verificamos la existencia de un carácter determinado en el mensaje recibido. Si dicho carácter existe en el mensaje, significa que se trata de un comando proveniente de MetaTrader 5, lo que hará que se ejecute la línea 90. Sin embargo, si dicha ejecución falla, no se publicará nada más. Observa el código de comandos para ver qué tipo de datos se esperan desde MetaTrader 5. Cuando hablemos sobre el código en MQL5, volveremos a este punto. Por ahora, basta con saber que MetaTrader 5 puede enviar comandos para que el servidor los ejecute.

Bien, pero ¿y si no se trataba de un comando? Esto ocurre porque falló la línea 89. Entonces, ¿qué sucederá? En ese caso, se ejecutará la línea 93. Escribirá la información enviada por MetaTrader 5 en respuesta a una solicitud de Excel en una celda específica. ¿Pero qué solicitud? Ahora llegamos al punto realmente interesante: la línea 97. Observa lo que estamos haciendo en esta línea. En ella, usamos el servidor para enviar una solicitud a MetaTrader 5 a través del socket. Dicha solicitud puede presentarse de dos formas:

  • La primera es el contenido leído de una celda o rango de celdas específico en Excel. Aunque, para simplificar, no estamos usando un rango, sino el contenido de una celda concreta.
  • La segunda es que, dentro de los corchetes, enviaremos, cuando Excel lo indique, algún comando para que MetaTrader 5 lo ejecute.

La forma en que dichos comandos o solicitudes de Excel se ejecutarán en MetaTrader 5 se verá más adelante. Por ahora, observa que tenemos un protocolo bastante simple para que se produzca la comunicación. Es decir, básicamente, lo que haya en la celda o como comando enviado por Excel se transmitirá a MetaTrader 5. El servidor no participará activamente en esta fase de intercambio de mensajes, sino que solo registrará los mensajes en los puntos indicados dentro de esta rutina para que luego el VBA y el MQL5 hagan su trabajo.

No obstante, si deseas aumentar o mejorar la cantidad y calidad de la información que se transferirá entre Excel y MetaTrader 5, puedes usar Python para simplificar el trabajo que se realizaría en VBA o MQL5. Pero, dado que el objetivo es ser lo más didáctico posible, utilizaremos un protocolo de mensajes muy sencillo, haciendo uso de una única celda en Excel. Si entiendes cómo se ha hecho esto, podrás hacer cualquier cosa que te interese.

Observa que todas las posiciones de las celdas utilizadas aquí tienen como origen precisamente la primera celda indicada durante la inicialización del servidor. Es importante que comprendas estos detalles, ya que todo lo demás se hará directamente dentro de VBA de Excel. Será bastante simple y fácil de hacer y ejecutar.

Muy bien, con esto llegamos al final. Así llegamos a la línea 101. Prácticamente todo lo que está en este procedimiento ya se ha visto en los artículos anteriores sobre sockets, pero hay algunos puntos que merecen destacarse o explicarse. Por ejemplo, en la línea 113 encontramos algo que puede parecer extraño a primera vista, aunque no lo es tanto si lo piensas bien y has seguido esta secuencia. Si se cumple la verificación que se realiza en la línea 110, se enviará algo al cliente que acaba de conectarse. Normalmente, sería un mensaje de bienvenida.

Pero aquí haremos algo completamente diferente. Como Excel no permanecerá mucho tiempo conectado, entiende que la información que se enviará está dirigida al MetaTrader 5, por lo que es importante comprender el procedimiento de la línea 84, que se explicó hace poco. Así, en esta primera llamada no leeremos el socket, sino que solo escribiremos en él. Cuando el servidor reciba una respuesta de MetaTrader 5, se ejecutará la línea 115 y, esta vez sí, leeremos el socket y también escribiremos en él. De este modo, permaneceremos dentro de un bucle, recibiendo constantemente información de MetaTrader 5 y reenviándola a Excel.

Para terminar, tenemos un procedimiento que resultará bastante extraño para muchos de ustedes. Se debe a que es un destructor de clase. Al igual que tuvimos un constructor, que es __init__, también tenemos un destructor, que en este caso es __del__. Normalmente, este destructor no se incluye en el código de un script en Python, ya que Python cuenta con un recolector de basura que, cuando el script termina, elimina los objetos y libera la memoria utilizada. Sin embargo, la función de este destructor es un poco más noble. En efecto, hace que Excel muestre un mensaje en la posición donde normalmente se indica que el servidor está en línea, informando de que el servidor está en modo fuera de línea. Así, podrás verlo directamente en Excel, sin necesidad de usar otros medios o recursos. El resto del código es tan sencillo que no requiere ninguna otra atención.


Consideraciones finales

Con las explicaciones dadas aquí, damos por finalizada la parte referente al servidor en Python. El objetivo de este servidor es ser lo más didáctico y sencillo posible de crear en Python, usando únicamente los paquetes incluidos en la instalación estándar del lenguaje. Sin embargo, el lector podría crear algo mucho más elaborado y práctico utilizando otros paquetes y componentes para manipular archivos de Excel. Incluso podrías generar toda la hoja de cálculo de Excel, así como otras muchas funciones, directamente dentro de este código de Python.

Pero no quiero complicar las cosas ni favorecer a un paquete concreto de Python. Sé que existen muchos paquetes de excelente calidad que nos permiten realizar diversas tareas e incluso reemplazar por completo la necesidad de crear algo usando Excel. Sin embargo, como se mencionó en otro artículo, la idea aquí es atender a algún cliente o usuario que se niega a usar cualquier herramienta que no sea Excel. El objetivo es crear una hoja de cálculo para el análisis fundamentalista de un símbolo determinado, con el fin de poder comprar o vender dentro de ciertos rangos de precio. Algunos de ustedes pueden preguntarse: ¿por qué no colocar directamente la orden en el libro del símbolo en las posiciones deseadas? Así no sería necesario trabajar todo el tiempo en Excel y podrían hacerlo directamente en MetaTrader 5.

Entiendo perfectamente a quien piensa así. Pero hay personas que no tienen paciencia ni disposición para quedarse mirando un gráfico, colocando y quitando órdenes, abriendo y cerrando posiciones. Simplemente prefieren hacerlo todo desde unos pocos programas, normalmente aquellos que dominan y en los que ya han desarrollado sus métodos de análisis, y no quieren renunciar a eso. Por lo tanto, esas personas quieren que tú, como programador, crees algún método o medio para enviar órdenes, cerrar posiciones o abrir posiciones dentro de un determinado rango de precios usando ese programa en particular, que en este caso es Excel.

No quieren preocuparse por entender cómo se hará. Simplemente te contratan y te pagan para que lo hagas de la mejor forma posible. Esa es precisamente la propuesta que estoy mostrando cómo realizar, al menos en parte. Ya que tú, como programador, puedes querer hacerlo de otra manera o con ligeras diferencias. Personalmente, eso no me importa demasiado. Lo que realmente me da satisfacción es saber que, al leer estos artículos, tú, que pensabas que ciertas cosas no eran posibles, veas que sí lo son. Que es perfectamente posible hacer cualquier cosa, siempre que estudies y dediques tiempo a conseguirlo. En el próximo artículo, veremos la parte de VBA en Excel, donde comprenderás cómo poner en funcionamiento este servidor junto con Excel. Así que, hasta el próximo artículo de esta misma serie.

Archivo Descripció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.mq5 Crea la ventana para configurar la orden a ser enviada (es necesario el Mouse Study para la interacción)
Indicators\Market Replay.mq5 Crea 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.mq5 Permite 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.mq5 Crea y mantiene el servicio de reproducción y simulación de mercado (archivo principal de todo el sistema)
Código VS C++\Server.cpp Crea y mantiene un socket servidor desarrollado en C++ (versión MiniChat).
Code in Python\Server.py Crea y mantiene un socket en Python para la comunicación entre MetaTrader 5 e o Excel
Scripts\CheckSocket.mq5 Permite realizar una prueba de conexión con un socket externo
Indicators\Mini Chat.mq5 Permite implementar un minichat mediante un indicador (requiere el uso de un servidor para funcionar)
Experts\Mini Chat.mq5 Permite 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/12827

Archivos adjuntos |
Anexo.zip (560.03 KB)
Añadimos un LLM personalizado a un robot comercial (Parte 5): Desarrollar y probar la estrategia de negociación con LLMs (IV) - Probar la estrategia de trading Añadimos un LLM personalizado a un robot comercial (Parte 5): Desarrollar y probar la estrategia de negociación con LLMs (IV) - Probar la estrategia de trading
Con el rápido desarrollo de la inteligencia artificial en la actualidad, los modelos de lenguaje (LLM) son una parte importante de la inteligencia artificial, por lo que debemos pensar en cómo integrar potentes LLM en nuestro trading algorítmico. Para la mayoría de las personas, resulta difícil ajustar estos potentes modelos según sus necesidades, implementarlos localmente y luego aplicarlos al comercio algorítmico. Esta serie de artículos adoptará un enfoque paso a paso para lograr este objetivo.
Simulación de mercado (Parte 14): Sockets (VIII) Simulación de mercado (Parte 14): Sockets (VIII)
Muchos podrían sugerir que deberíamos dejar de usar Excel y pasar a Python directamente, haciendo uso de algunos paquetes que permitirían a Python crear un archivo de Excel para poder analizar los resultados después. Pero, como se mencionó en el artículo anterior, aunque esta solución sea la más sencilla para muchos programadores, no será bien recibida por algunos usuarios. Y, en este asunto, el usuario siempre tiene la razón. Tú, como programador, debes encontrar la forma de hacer que las cosas funcionen.
Desarrollamos un asesor experto multidivisas (Parte 23): Ordenando la cadena de etapas de optimización automática de proyectos (II) Desarrollamos un asesor experto multidivisas (Parte 23): Ordenando la cadena de etapas de optimización automática de proyectos (II)
Hoy nuestro objetivo consiste en crear un sistema de optimización periódica automática de las estrategias comerciales utilizadas en un asesor experto final. El sistema se vuelve más complejo a medida que se desarrolla, por lo que de vez en cuando debemos examinarlo en su conjunto para detectar cuellos de botella y soluciones subóptimas.
Redes neuronales en el trading: Modelos híbridos de secuencias de grafos (GSM++) Redes neuronales en el trading: Modelos híbridos de secuencias de grafos (GSM++)
Los modelos híbridos de secuencias de grafos (GSM++) combinan los puntos fuertes de distintas arquitecturas para posibilitar un análisis de datos de gran precisión y optimizar los costes computacionales. Estos modelos se adaptan eficazmente a los datos dinámicos del mercado, mejorando la presentación y el procesamiento de la información financiera.