Creación de un Panel de administración de operaciones en MQL5 (Parte II): Mejorar la capacidad de respuesta y la rapidez de los mensajes
Contenido:
Introducción:
Imagine perderse una señal crucial del mercado por culpa de un mensaje retrasado, un obstáculo habitual que cuesta a los operadores valiosas oportunidades y beneficios en el vertiginoso entorno de la negociación. En este contexto, los conocimientos de los administradores son tan vitales como las propias señales del mercado. Aunque los sistemas algorítmicos son rápidos y emocionalmente inteligentes, no pueden sustituir la aguda supervisión de los operadores expertos, que supervisan continuamente el rendimiento del sistema y toman decisiones críticas. 
Comparación entre el mensaje al hacer clic y el tipo de mensaje.

En la imagen de arriba, hay un problema: al intentar arrastrar el panel, el gráfico se mueve y el botón de minimizar no responde.
A medida que el comercio algorítmico domina los mercados financieros, la comunicación eficiente entre los usuarios de los sistemas de comercio (comerciantes) y los administradores humanos (el hombre detrás del sistema de comercio) se ha vuelto imperativa. Anteriormente, creamos interfaces de mensajería del Panel de administración que tienen una capacidad de respuesta limitada requerida para tareas en tiempo real, como mensajería rápida y hacer clic y arrastrar el panel en sí, lo que crea un desafío importante para los administradores que necesitan reaccionar rápidamente.

Panel de administración: Mejoras dirigidas al Panel de administración anterior
Este artículo tiene como objetivo romper estas barreras de comunicación introduciendo capacidad de respuesta en la interfaz de mensajería del administrador mediante MQL5. Además, destaca la importancia de la mensajería rápida para respaldar decisiones comerciales ágiles y la eficiencia operativa.
En esta discusión, exploraremos cómo se puede utilizar MQL5 para mejorar la capacidad de respuesta de los mensajes dentro de las plataformas comerciales. Lo guiaremos a través de los pasos clave de implementación, ayudándolo a desarrollar una comprensión más profunda de las posibilidades que ofrece la programación MQL5. Juntos, crearemos una interfaz de mensajería más efectiva que satisfaga las demandas del comercio moderno.Para seguir esta discusión desde el principio hasta el final, abordaré las siguientes preguntas:
- ¿Qué es la capacidad de respuesta en la GUI?
- ¿Qué son los mensajes rápidos?
Sensibilidad:
En MQL5, la capacidad de respuesta en la GUI (interfaz gráfica de usuario) se refiere a qué tan rápida y fluidamente la interfaz reacciona a las interacciones del usuario, como hacer clic en botones, mover controles deslizantes o cambiar el tamaño de los paneles. Una GUI responsiva proporciona respuesta inmediata al usuario, garantizando que la interfaz se sienta intuitiva y fácil de usar. Esto es especialmente importante en las aplicaciones comerciales, donde las acciones oportunas pueden ser cruciales.
Para lograr capacidad de respuesta, a menudo es necesario optimizar el código para reducir el tiempo de ejecución de las funciones relacionadas con la GUI, minimizar la cantidad de objetos dibujados en el gráfico y utilizar el procesamiento asincrónico cuando sea posible. Esto garantiza que el hilo principal siga respondiendo a las entradas del usuario, lo que permite una experiencia de usuario fluida durante actividades comerciales críticas.
Permítame describir en detalle los aspectos clave de la capacidad de respuesta en una GUI MQL5:
- Retroalimentación inmediata: la interfaz debe responder instantáneamente a las acciones del usuario, como hacer clic en botones o ingresar texto. No debe haber ningún retraso perceptible entre la acción del usuario y la respuesta del sistema.
- Rendimiento fluido: incluso con múltiples elementos GUI y lógica compleja, la interfaz debería funcionar sin problemas, sin demoras ni congelamientos. Esto implica prácticas de codificación eficientes para minimizar la carga en la CPU y garantizar la ejecución rápida de los comandos del usuario.
- Actualizaciones dinámicas: la GUI debe poder actualizar elementos dinámicamente sin necesidad de volver a dibujar toda la interfaz. Por ejemplo, si se alcanza un nuevo nivel de precio, los elementos correspondientes (por ejemplo, etiquetas, líneas) deberían actualizarse sin problemas y sin parpadear.
- Escalabilidad: la interfaz debe manejar bien los cambios de tamaño o resolución. Por ejemplo, si el usuario cambia el tamaño de un panel, el contenido debería ajustarse automáticamente y mantener la usabilidad.
- Manejo de errores: la GUI debe gestionar los errores con elegancia, brindando una respuesta clara e inmediata al usuario si algo sale mal, sin bloquearse ni dejar de responder.
Mensajes rápidos:
Consulte mensajes predefinidos y de uso común que se pueden enviar con un solo clic o una interacción mínima. Estos mensajes generalmente se configuran con antelación para satisfacer necesidades de comunicación frecuentes, lo que permite a los usuarios responder rápidamente o enviar mensajes estándar sin necesidad de escribir manualmente.
Casos de uso para mensajes rápidos
- Respuestas estándar: Los mensajes rápidos se pueden usar para respuestas o comandos estándar, como reconocer una señal comercial, confirmar una acción o notificar a un equipo sobre un evento específico.
- Notificaciones de errores: si ocurre un error durante el trading, se puede enviar inmediatamente un mensaje breve como "Señal no válida" o "Error detectado".
- Comandos de rutina: Los mensajes rápidos pueden incluir comandos de rutina o instrucciones que se utilizan con frecuencia en operaciones comerciales, como "Cerrar todas las posiciones" o "Activar EA".
Ejemplo:
Supongamos que tiene un panel de administración en MQL5 con varios mensajes rápidos para un sistema de comercio automatizado. Estos podrían incluir:
- Iniciar monitoreo: Un breve mensaje para comenzar a monitorear las condiciones del mercado.
- Detener el monitoreo: un mensaje breve para detener el monitoreo.
- Señal no válida: un mensaje para notificar al usuario que se ha detectado una señal comercial no válida.
Cada uno de estos podría estar vinculado a un botón en el panel. Al hacer clic en el botón, el mensaje predefinido se envía instantáneamente, lo que ahorra tiempo y garantiza una comunicación constante.
Implementación en MQL5
En MQL5, los mensajes rápidos se pueden implementar en un panel de mensajería mediante la creación de botones o menús desplegables vinculados a cadenas de texto específicas previamente escritas. Cuando el usuario pulsa uno de estos botones, el mensaje correspondiente se envía automáticamente a través del canal de comunicación deseado, como Telegram, correo electrónico u otra API de mensajería. Algunos inconvenientes obvios que se pueden notar en la imagen animada de la introducción que muestra nuestro panel cubriendo alguna parte del gráfico pueden resultar molestos cuando queremos tener una imagen más grande para analizar el gráfico. Para conquistar este segmento, lo dividiré en dos:
- Colocación lógica de los botones de control del panel.
- Codificando nuestros botones de mensajes rápidos usando la función de repetición.
Supongo que habrán leído la Parte I y se habrán hecho una idea de dónde venimos y hacia dónde vamos.
1. Colocación lógica de los botones de control del Panel
Botón Minimizar, Maximizar y Cerrar
- Declaración del botón:
Aquí mostramos cómo declaramos los botones antes de continuar:
///Global variables
CButton minimizeButton;
CButton maximizeButton;
CButton closeButton; - Botón Minimizar:
Para el botón minimizar, lo creamos usando la clase CButton, posicionándolo en (375, -22) en el gráfico con un tamaño que abarca (30, 22) píxeles. El botón muestra un guión bajo _, un símbolo común para minimizar ventanas. Lo añadimos al Panel de Administración usando «adminPanel. Add(minimizeButton)". El propósito de este botón es permitir a los usuarios ocultar temporalmente el Panel de administración sin cerrarlo por completo. En la función «OnMinimizeButtonClick()», programamos el botón para que oculte el Panel de administración y sólo muestre los botones minimizar, maximizar y cerrar. Esto simula la minimización de la ventana mientras mantiene disponibles los controles esenciales.
// Create the minimize button if (!minimizeButton.Create(chart_id, "MinimizeButton", 0, 375, -22, 405, 0)) { Print("Failed to create minimize button"); return INIT_FAILED; } minimizeButton.Text("_"); adminPanel.Add(minimizeButton); // Function to handle minimize button click void OnMinimizeButtonClick() { minimized = true; // Hide the full admin panel adminPanel.Hide(); minimizeButton.Show(); maximizeButton.Show(); closeButton.Show(); }
- Botón Maximizar:
Para el botón de maximizar, usamos la misma clase «CButton» y lo posicionamos junto al botón de minimizar en (405, -22). El botón muestra [], un símbolo habitual para maximizar o restaurar ventanas, y lo añadimos al Panel de administración mediante"adminPanel. Add(maximizeButton)". Este botón permite a los usuarios restaurar el Panel de administración a su tamaño completo después de haberlo minimizado. En la función «OnMaximizeButtonClick()», al hacer clic en este botón se restablece el tamaño original del Panel de administración y se ocultan los botones de minimizar, maximizar y cerrar. Esto imita el comportamiento de maximizar una ventana minimizada.
// Create the maximize button if (!maximizeButton.Create(chart_id, "MaximizeButton", 0, 405, -22, 435, 0)) { Print("Failed to create maximize button"); return INIT_FAILED; } maximizeButton.Text("[ ]"); adminPanel.Add(maximizeButton); // Function to handle maximize button click void OnMaximizeButtonClick() { if (minimized) { minimizeButton.Hide(); maximizeButton.Hide(); closeButton.Hide(); adminPanel.Show(); } }
- Botón de Cerrar:
Para el botón de cerrar, lo creamos de la misma manera que los otros dos botones, posicionándolo en (435, -22) y mostrando una X, símbolo universal para cerrar ventanas. Añadimos este botón al Panel de administración usando «adminPanelAdd(closeButton)». Este botón permite a los usuarios eliminar completamente el Asesor Experto (EA) del gráfico llamando a «ExpertRemove()» en la función «OnCloseButtonClick()». Proporciona una forma sencilla de cerrar el Panel de administración y detener el EA cuando el usuario haya terminado de utilizar el panel.
// Create the close button if (!closeButton.Create(chart_id, "CloseButton", 0, 435, -22, 465, 0)) { Print("Failed to create close button"); return INIT_FAILED; } closeButton.Text("X"); adminPanel.Add(closeButton); // Function to handle close button click void OnCloseButtonClick() { ExpertRemove(); // Completely remove the EA Print("Admin Panel closed."); }2. Codificación de nuestros botones de mensajes rápidos mediante la función de bucle (repetición)
Interfaz de botones de mensajes rápidos múltiples
Entradas para mensajes rápidos:
- Hemos utilizado variables de entrada (QuickMessage1 a QuickMessage8) para personalizar los mensajes. Estas entradas permiten a los usuarios modificar el texto de cada mensaje rápido directamente desde la configuración del Asesor Experto, sin alterar el código central. Esta flexibilidad permite adaptar fácilmente los mensajes a diferentes escenarios comerciales o preferencias del usuario. Además, la colocación de los botones es dinámica, lo que significa que puede ajustar el número de botones, su tamaño o su posición modificando los parámetros del bucle o la matriz «quickMessages». Esta estructura garantiza que el Panel de Administración pueda adaptarse fácilmente a diferentes necesidades, proporcionando una interfaz robusta y fácil de usar.
//+------------------------------------------------------------------+ //| Inputs | //+------------------------------------------------------------------+ input string QuickMessage1 = "Updates"; input string QuickMessage2 = "Close all"; input string QuickMessage3 = "In deep profits"; input string QuickMessage4 = "Hold position"; input string QuickMessage5 = "Swing Entry"; input string QuickMessage6 = "Scalp Entry"; input string QuickMessage7 = "Book profit"; input string QuickMessage8 = "Invalid Signal"; input string InputChatId = "Enter Chat ID from Telegram bot API"; // User's Telegram chat ID input string InputBotToken = "Enter BOT TOKEN from your Telegram bot"; // User's Telegram bot token
Implementación de bucle:
- Establecimos múltiples botones de mensajes rápidos creando una matriz de objetos (CButton) (quickMessageButtons[8]) e inicializándolos en un bucle. El bucle itera a través de la matriz (quickMessages), que contiene mensajes predefinidos. Cada iteración crea un botón, le asigna una etiqueta de (quickMessages), y posiciona los botones dinámicamente en función de su índice. La esencia de la función de repetición queda capturada por la estructura de bucle, que replica el proceso de creación y configuración de cada botón, lo que garantiza la consistencia y la eficiencia. En MQL5, este enfoque minimiza la redundancia al utilizar un bucle para manejar tareas repetitivas como la creación de múltiples botones con características similares, simplificando así el código y reduciendo el potencial de errores.
// Array of predefined quick messages string quickMessages[8] = { QuickMessage1, QuickMessage2, QuickMessage3, QuickMessage4, QuickMessage5, QuickMessage6, QuickMessage7, QuickMessage8 }; // Coordinates and dimensions for the buttons int startX = 5, startY = 160, width = 222, height = 65, spacing = 5; // Loop to create and configure quick message buttons for (int i = 0; i < 8; i++) { if (!quickMessageButtons[i].Create(chart_id, "QuickMessageButton" + IntegerToString(i + 1), 0, startX + (i % 2) * (width + spacing), startY + (i / 2) * (height + spacing), startX + (i % 2) * (width + spacing) + width, startY + (i / 2) * (height + spacing) + height)) { Print("Failed to create quick message button ", i + 1); return INIT_FAILED; } quickMessageButtons[i].Text(quickMessages[i]); adminPanel.Add(quickMessageButtons[i]); }
Administrar la longitud del mensaje:
- La implementación de la longitud de caracteres implica un contador de caracteres que rastrea la cantidad de caracteres ingresados en el cuadro de entrada y actualiza una etiqueta para mostrar la longitud actual junto con la longitud máxima permitida del mensaje. La función (OnInputChange) se activa cada vez que cambia el texto de entrada, recuperando el texto, calculando su longitud mediante (StringLen) y actualizando después la etiqueta (charCounter) con el formato «longitud_actual/longitud_máxima_del_mensaje». Esto garantiza que los usuarios sepan cuántos caracteres les quedan mientras redactan su mensaje, evitando así que superen el límite permitido. Opcionalmente, utilicé 600 como longitud máxima de caracteres.
// Maximum number of characters allowed in a message int MAX_MESSAGE_LENGTH = 600; // Function to update the character counter void OnInputChange() { string text = inputBox.Text(); int currentLength = StringLen(text); charCounter.Text(IntegerToString(currentLength) + "/" + IntegerToString(MAX_MESSAGE_LENGTH)); }
Nuestro programa totalmente integrado está aquí:
//+------------------------------------------------------------------+ //| Admin Panel.mq5 | //| Copyright 2024, Clemence Benjamin | //| https://www.mql5.com/en/users/billionaire2024/seller | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property description "A responsive Admin Panel. Send messages to your telegram clients without leaving MT5" #property version "1.09" #include <Trade\Trade.mqh> #include <Controls\Dialog.mqh> #include <Controls\Button.mqh> #include <Controls\Edit.mqh> #include <Controls\Label.mqh> // Use CLabel for displaying text //+------------------------------------------------------------------+ //| Inputs | //+------------------------------------------------------------------+ input string QuickMessage1 = "Updates"; input string QuickMessage2 = "Close all"; input string QuickMessage3 = "In deep profits"; input string QuickMessage4 = "Hold position"; input string QuickMessage5 = "Swing Entry"; input string QuickMessage6 = "Scalp Entry"; input string QuickMessage7 = "Book profit"; input string QuickMessage8 = "Invalid Signal"; input string InputChatId = "Enter Chat ID from Telegram bot API"; // User's Telegram chat ID input string InputBotToken = "Enter BOT TOKEN from your Telegram bot"; // User's Telegram bot token //+------------------------------------------------------------------+ //| Global variables | //+------------------------------------------------------------------+ CDialog adminPanel; CButton sendButton; CButton clearButton; CButton minimizeButton; CButton maximizeButton; CButton closeButton; CButton quickMessageButtons[8]; CEdit inputBox; CLabel charCounter; // Use CLabel for the character counter bool minimized = false; int MAX_MESSAGE_LENGTH = 600; // Maximum number of characters //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { long chart_id = ChartID(); // Create the dialog if (!adminPanel.Create(chart_id, "Admin Panel", 0, 30, 30, 500, 500)) { Print("Failed to create dialog"); return INIT_FAILED; } // Create the input box if (!inputBox.Create(chart_id, "InputBox", 0, 5, 5, 460, 75)) { Print("Failed to create input box"); return INIT_FAILED; } adminPanel.Add(inputBox); // Create the clear button for the input box if (!clearButton.Create(chart_id, "ClearButton", 0, 180, 75, 270, 105)) { Print("Failed to create clear button"); return INIT_FAILED; } clearButton.Text("Clear"); adminPanel.Add(clearButton); // Create the send button for custom messages if (!sendButton.Create(chart_id, "SendButton", 0, 270, 75, 460, 105)) { Print("Failed to create send button"); return INIT_FAILED; } sendButton.Text("Send Message"); adminPanel.Add(sendButton); // Create the character counter label if (!charCounter.Create(chart_id, "CharCounter", 0, 380, 110, 460, 130)) { Print("Failed to create character counter label"); return INIT_FAILED; } charCounter.Text("0/" + IntegerToString(MAX_MESSAGE_LENGTH)); adminPanel.Add(charCounter); // Create the quick message buttons string quickMessages[8] = { QuickMessage1, QuickMessage2, QuickMessage3, QuickMessage4, QuickMessage5, QuickMessage6, QuickMessage7, QuickMessage8 }; int startX = 5, startY = 160, width = 222, height = 65, spacing = 5; for (int i = 0; i < 8; i++) { if (!quickMessageButtons[i].Create(chart_id, "QuickMessageButton" + IntegerToString(i + 1), 0, startX + (i % 2) * (width + spacing), startY + (i / 2) * (height + spacing), startX + (i % 2) * (width + spacing) + width, startY + (i / 2) * (height + spacing) + height)) { Print("Failed to create quick message button ", i + 1); return INIT_FAILED; } quickMessageButtons[i].Text(quickMessages[i]); adminPanel.Add(quickMessageButtons[i]); } adminPanel.Show(); // Create the minimize button if (!minimizeButton.Create(chart_id, "MinimizeButton", 0, 375, -22, 405, 0)) { Print("Failed to create minimize button"); return INIT_FAILED; } minimizeButton.Text("_"); adminPanel.Add(minimizeButton); // Create the maximize button if (!maximizeButton.Create(chart_id, "MaximizeButton", 0, 405, -22, 435, 0)) { Print("Failed to create maximize button"); return INIT_FAILED; } maximizeButton.Text("[ ]"); adminPanel.Add(maximizeButton); // Create the close button if (!closeButton.Create(chart_id, "CloseButton", 0, 435, -22, 465, 0)) { Print("Failed to create close button"); return INIT_FAILED; } closeButton.Text("X"); adminPanel.Add(closeButton); adminPanel.Show(); // Enable chart events ChartSetInteger(ChartID(), CHART_EVENT_OBJECT_CREATE, true); ChartSetInteger(ChartID(), CHART_EVENT_OBJECT_DELETE, true); ChartSetInteger(ChartID(), CHART_EVENT_MOUSE_WHEEL, true); ChartRedraw(); Print("Initialization complete"); return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { adminPanel.Destroy(); Print("Deinitialization complete"); } //+------------------------------------------------------------------+ //| Expert event handling function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { // Handle different types of events switch (id) { case CHARTEVENT_OBJECT_CLICK: if (sparam == "SendButton") { OnSendButtonClick(); } else if (sparam == "ClearButton") { OnClearButtonClick(); } else if (sparam == "MinimizeButton") { OnMinimizeButtonClick(); } else if (sparam == "MaximizeButton") { OnMaximizeButtonClick(); } else if (sparam == "CloseButton") { OnCloseButtonClick(); } else if (StringFind(sparam, "QuickMessageButton") >= 0) { int index = StringToInteger(StringSubstr(sparam, StringLen("QuickMessageButton"))); OnQuickMessageButtonClick(index - 1); } break; case CHARTEVENT_OBJECT_CHANGE: if (sparam == "InputBox") { OnInputChange(); } break; default: break; } } //+------------------------------------------------------------------+ //| Function to handle custom message send button click | //+------------------------------------------------------------------+ void OnSendButtonClick() { string message = inputBox.Text(); if (message != "") { if (SendMessageToTelegram(message)) Print("Custom message sent: ", message); else Print("Failed to send custom message."); } else { Print("No message entered."); } } //+------------------------------------------------------------------+ //| Function to handle clear button click | //+------------------------------------------------------------------+ void OnClearButtonClick() { inputBox.Text(""); // Clear the text in the input box OnInputChange(); // Update the character counter Print("Input box cleared."); } //+------------------------------------------------------------------+ //| Function to handle quick message button click | //+------------------------------------------------------------------+ void OnQuickMessageButtonClick(int index) { string quickMessages[8] = { QuickMessage1, QuickMessage2, QuickMessage3, QuickMessage4, QuickMessage5, QuickMessage6, QuickMessage7, QuickMessage8 }; string message = quickMessages[index]; if (SendMessageToTelegram(message)) Print("Quick Message Button Clicked - Quick message sent: ", message); else Print("Failed to send quick message."); } //+------------------------------------------------------------------+ //| Function to update the character counter | //+------------------------------------------------------------------+ void OnInputChange() { string text = inputBox.Text(); int currentLength = StringLen(text); charCounter.Text(IntegerToString(currentLength) + "/" + IntegerToString(MAX_MESSAGE_LENGTH)); } //+------------------------------------------------------------------+ //| Function to handle minimize button click | //+------------------------------------------------------------------+ void OnMinimizeButtonClick() { minimized = true; // Hide the full admin panel adminPanel.Hide(); minimizeButton.Show(); maximizeButton.Show(); closeButton.Show(); } //+------------------------------------------------------------------+ //| Function to handle maximize button click | //+------------------------------------------------------------------+ void OnMaximizeButtonClick() { if (minimized) { minimizeButton.Hide(); maximizeButton.Hide(); closeButton.Hide(); adminPanel.Show(); } } //+------------------------------------------------------------------+ //| Function to handle close button click | //+------------------------------------------------------------------+ void OnCloseButtonClick() { ExpertRemove(); // Completely remove the EA Print("Admin Panel closed."); } //+------------------------------------------------------------------+ //| Function to send the message to Telegram | //+------------------------------------------------------------------+ bool SendMessageToTelegram(string message) { // Use the input values for bot token and chat ID string botToken = InputBotToken; string chatId = InputChatId; string url = "https://api.telegram.org/bot" + botToken + "/sendMessage"; char post_data[]; // Prepare the message data string jsonMessage = "{\"chat_id\":\"" + chatId + "\", \"text\":\"" + message + "\"}"; // Resize the character array to fit the JSON payload ArrayResize(post_data, StringToCharArray(jsonMessage, post_data)); int timeout = 5000; char result[]; string responseHeaders; // Make the WebRequest int res = WebRequest("POST", url, "Content-Type: application/json\r\n", timeout, post_data, result, responseHeaders); if (res == 200) // HTTP 200 OK { Print("Message sent successfully: ", message); return true; } else { Print("Failed to send message. HTTP code: ", res, " Error code: ", GetLastError()); Print("Response: ", CharArrayToString(result)); return false; } }
Prueba del panel de administración avanzado y con capacidad de respuesta:
Aquí inicié el Panel de administración y funcionó bien con pocos inconvenientes. Vea la imagen a continuación.

Índice Volatility 150s: Prueba del panel de administración
La integración de Telegram funcionó bien, ¡nuestros mensajes llegan con un clic!
Mensajes rápidos entrantes de Telegram
Conclusión
En conclusión, la integración de funciones de respuesta y mensajería rápida en el Asesor Experto (EA) del Panel de Administración representa una mejora significativa en su utilidad y experiencia del usuario. Los botones de minimizar, maximizar y cerrar recientemente agregados brindan una interfaz perfecta e intuitiva, que permite a los usuarios administrar la visibilidad y el funcionamiento del panel con facilidad. Estas características garantizan que el panel no solo sea funcional sino también adaptable a las necesidades del usuario, ya sea que requiera una vista completa o una pantalla compacta y discreta.La implementación de la mensajería rápida agiliza aún más la comunicación al permitir a los usuarios enviar mensajes predefinidos instantáneamente a sus clientes de Telegram sin salir del entorno de MetaTrader 5. Esta característica es particularmente valiosa en escenarios de trading de ritmo rápido donde el tiempo es crítico. La capacidad del panel para enviar mensajes personalizados, junto con la comodidad de los botones de mensajes rápidos, permite a los usuarios mantener una comunicación efectiva con una interrupción mínima de sus actividades comerciales.
En general, estas mejoras hacen del Panel de administración una herramienta más poderosa para comerciantes y administradores, mejorando tanto la eficiencia como la flexibilidad. Esta evolución refleja nuestro compromiso de brindar soluciones que aborden los desafíos del mundo real en el trading algorítmico, garantizando que los usuarios puedan gestionar sus operaciones comerciales con mayor control y conveniencia.
Se podría hacer más, pero hoy lo hemos logrado. Se adjunta un archivo fuente a continuación. ¡Feliz desarrollo y comercio, compañeros!
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/15418
Advertencia: todos los derechos de estos materiales pertenecen a MetaQuotes Ltd. Queda totalmente prohibido el copiado total o parcial.
Este artículo ha sido escrito por un usuario del sitio web y refleja su punto de vista personal. MetaQuotes Ltd. no se responsabiliza de la exactitud de la información ofrecida, ni de las posibles consecuencias del uso de las soluciones, estrategias o recomendaciones descritas.
Redes neuronales en el trading: Aprendizaje jerárquico de características en nubes de puntos
Ejemplo de optimización estocástica y control óptimo
Redes neuronales en el trading: Transformer para nubes de puntos (Pointformer)
Redes neuronales en el trading: Transformador contrastivo de patrones
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso
Este artículo es increíblemente útil y muy práctico. Muchas gracias
Gracias por sus valiosos comentarios, ¡se agradecen enormemente!