Desarrollamos un asesor experto multidivisas (Parte 27): Componente para mostrar textos de varias líneas
Contenido
- Introducción
- Trazando el camino
- Clase CConsoleDialog
- Constructor y destructor
- Creando un cuadro de diálogo
- Gestión de eventos
- Minimización
- Trabajando con texto
- Configuración de la fuente y el color
- Trabajando con el lienzo
- Conectando el componente
- Simulación
- Conclusión
Introducción
En la sección anterior, creamos una versión básica de un asesor-informador auxiliar que muestra información sobre los tamaños promedio de las velas en puntos y las longitudes de series de velas en la misma dirección. Esto no se relaciona directamente con nuestro proyecto principal: un sistema para la optimización automática y el inicio de asesores multidivisa que implementan una variedad de estrategias simples. Sin embargo, el desarrollo futuro del asesor-informador permanecerá por ahora en el marco de esta serie, ya que hemos comenzado a experimentar y mejorar la implementación de varios componentes que esperamos integrar posteriormente con éxito en el proyecto principal.
Hemos pasado a una estructura de código más optimizada que abre la posibilidad de paralelizar el trabajo en múltiples áreas del desarrollo de la biblioteca Adwizard. Una de estas áreas es la creación de una interfaz visual para gestionar el trabajo de los asesores finales. El proyecto de asesor-informador analizado en este artículo nos ayudará a explorar más a fondo diferentes enfoques para implementar la interfaz sin complejidad innecesaria. Tras estudiar sus ventajas y desventajas, podremos elegir el más adecuado y desarrollar con criterio el proyecto principal.
La última vez escribimos una posible implementación de la parte de cálculo, que no tenía requisitos estrictos de eficiencia. Para mostrar los resultados del cálculo, usamos dos métodos simples disponibles "listos para usar". La primera consiste en usar la función estándar Comment(), que muestra el texto pasado directamente en el gráfico. La segunda consiste en utilizar otra función estándar Print(), para enviar texto al registro del asesor. Esto resulta bastante cómodo para tareas sencillas.
No obstante, estos métodos tienen una serie de limitaciones. El principal problema del primero es la falta de control sobre el tamaño, estilo y color de la fuente, así como la imposibilidad de desplazarse por el texto cuando existe una gran cantidad de información. Esto crea inconvenientes, especialmente cuando se generan datos estructurados o de varias líneas. El segundo método tiene los mismos problemas, salvo el desplazamiento, más el inconveniente añadido de tener que agregar constantemente entradas al diario.
Por ello, en este artículo, crearemos nuestro propio componente: un cuadro de diálogo de pantalla completa capaz de mostrar texto de varias líneas con configuraciones de fuente flexibles y soporte de desplazamiento. Esta herramienta hará que la visualización de la información resulte más cómoda y clara. Una vez que hayamos probado este componente, probablemente pasará a formar parte de la biblioteca Adwizard como un recurso para mostrar una amplia variedad de información sobre el funcionamiento de los asesores multidivisa.
Trazando el camino
Vamos a enumerar los deseos que querríamos implementar:
-
Muestra de texto de varias líneas: al componente se le transmite un texto completamente formado como variable de línea, que puede contener caracteres de avance de línea. Cada parte, separada por caracteres de avance de línea, se mostrará en la ventana del gráfico en una nueva línea.
-
Desplazamiento de texto: si el texto completo no cabe en el área de muestra disponible, podemos usar la rueda del ratón para desplazarnos vertical y horizontalmente (mientras mantenemos presionada la tecla Shift). Por ahora, no mostraremos barras de desplazamiento, pero podríamos agregarlas más adelante.
-
Cambio del tamaño de la fuente: utilizando la tecla Ctrl + la rueda del ratón, podemos disminuir o aumentar el tamaño de la fuente utilizada para mostrar el texto.
-
Soporte para cambiar parámetros de fuente: estilo, color de texto y color de fondo. Por ahora, el cambio de estos parámetros solo se realizará mediante programación. En el futuro, podemos agregar una interfaz para cambiar estos parámetros cuando el programa se esté ejecutando.
-
Adaptación automática al cambio de tamaño del gráfico: si realizamos alguna acción que resulte en un cambio en el tamaño de la ventana del gráfico en el que se ejecuta el asesor experto que utiliza este componente para la muestra, el tamaño del área de muestra de texto también cambiará, ocupando el área completa disponible para la muestra.
-
Minimización: es la capacidad de minimizar y maximizar el área de muestra.
Posiblemente necesitemos mejorar aún más algunos de los requisitos durante el proceso de implementación, pero en general, la lista anterior resulta suficiente.
Clase CConsoleDialog
Vamos a crear una nueva clase y a llamarla CConsoleDialog. La haremos descendiente de la clase de biblioteca estándar existente CAppDialog, ya que esta clase padre ya contiene bastante de lo que planeamos implementar. Por ejemplo, la visualización de la ventana con los botones para minimizar/maximizar y cerrar la aplicación del asesor ya está lista. Todo lo que debemos hacer es ocuparnos del contenido interno del área de cliente de la ventana: aquí es donde se mostrará el texto.
Al mostrar el texto, usaremos un objeto de clase CCanvas para dibujar el mismo, e implementaremos el soporte para desplazarse y cambiar el tamaño de fuente mediante el manejo de eventos gráficos.
Así es como se verá la descripción de la nueva clase:
//+------------------------------------------------------------------+ //| Fullscreen dialog window class | //| to display multi-line text | //+------------------------------------------------------------------+ class CConsoleDialog : public CAppDialog { protected: CCanvas m_canvas; // Canvas object for displaying text string m_lines[]; // Array of text lines string m_text; // Text to display in the dialog window int m_startRow; // Initial line of visible text int m_startCol; // Starting column (symbol) of visible text int m_totalRows; // Total number of text lines int m_totalCols; // Total number of symbols in the longest line of text int m_visibleRows; // Maximum number of visible lines int m_visibleCols; // Maximum number of visible symbols in a line string m_fontName; // Text font name int m_fontSize; // Font size uint m_fontColor; // Font color int m_fontSymbolWidth; // Width of one symbol in pixels int m_fontSymbolHeight; // Text line height in pixels uint m_backgroundColor; // Background color bool m_mouseWheel; // Previous state of mouse scroll event tracking bool CreateCanvas(); // Create a canvas void UpdateCanvas(); // Output text on canvas void UpdateCanvasFont(); // Change the canvas font public: CConsoleDialog(); // Constructor ~CConsoleDialog(void); // Destructor // Methods for creating a dialog window bool Create(string name); virtual bool Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2); // Event handling virtual void ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam); virtual void Minimize(); // Minimize the dialog window virtual void Maximize(); // Maximize the dialog window virtual void Text(string text); // Set the new text virtual void FontName(string p_fontName); // Set the font name virtual bool FontSize(int p_fontSize); // Set the font size virtual void FontColor(uint p_fontColor); // Set the font color // Set the background color virtual void BackgroundColor(uint p_backgroundColor); };
De todos los métodos públicos enumerados, por ahora usaremos principalmente el método para configurar texto nuevo Text() y la primera versión del método Create(), que permite crear un cuadro de diálogo especificando solo su nombre. También la usaremos como título en la ventana.
Constructor y destructor
Al crear un objeto de la clase CConsoleDialog, el constructor inicializa la fuente predeterminada: se trata de una fuente monoespaciada "Consolas" de tamaño 13, con el color del texto establecido en negro con una ligera transparencia. Hemos elegido esta fuente para que los datos tabulares puedan mostrarse como texto y se vean exactamente como tablas con columnas pares. Si la fuente no es monoespaciada, ni siquiera serán posibles las tablas.
Un tamaño de fuente de 13 píxeles es, por una parte, lo suficientemente pequeño para mostrar una gran cantidad de texto, pero por otra, no tan pequeño como para resultar ilegible. Dada la posibilidad prevista de cambiar fácilmente el tamaño, la elección de un valor inicial concreto no juega un papel especial. El color de fondo se hace transparente, por lo que veremos a través del lienzo el color de fondo gris estándar usado en la clase CDialog.
Para una visualización correcta, se llama inmediatamente al método FontSize() para establecer el tamaño de la fuente, que determina los parámetros básicos para dibujar texto en el lienzo. A su vez, el destructor es responsable de eliminar correctamente el recurso canvas y restaurar la configuración original para procesar eventos de desplazamiento de la rueda del ratón en el gráfico.
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CConsoleDialog::CConsoleDialog() : m_fontName("Consolas"), m_fontSize(13), m_fontColor(ColorToARGB(clrBlack, 240)), m_backgroundColor(ColorToARGB(clrBlack, 0)) { FontSize(m_fontSize); } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CConsoleDialog::~CConsoleDialog() { // Delete the canvas m_canvas.Destroy(); // Return the previous mouse scroll event handling settings ChartSetInteger(m_chart_id, CHART_EVENT_MOUSE_WHEEL, (long)m_mouseWheel); }
Creando un cuadro de diálogo
Hay dos opciones para que el método Create() cree una ventana. La primera admite solo el nombre de la ventana y establece automáticamente la posición y el tamaño de la ventana en toda la pantalla del gráfico con un pequeño margen superior. Este método calcula las dimensiones del gráfico y llama al segundo método Create() con las coordenadas indicadas.
El segundo método permite crear un cuadro de diálogo con parámetros específicos: número de gráfico, nombre, número de subventana y coordenadas. Este método primero llama a la implementación principal para crear la ventana, luego establece las dimensiones para el estado minimizado, crea el lienzo, habilita el seguimiento de eventos de desplazamiento del ratón e inicializa las posiciones del área de texto visible para que la visualización empiece desde cero.
//+------------------------------------------------------------------+ //| Method to create a dialog window by name only | //+------------------------------------------------------------------+ bool CConsoleDialog::Create(string name) { // Set the corner position and window size int x1 = 0; int y1 = DIALOG_VERTICAL_MARGIN; int y2 = (int) ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS, 0); int x2 = (int) ChartGetInteger(0, CHART_WIDTH_IN_PIXELS, 0); // Call the method for creating according to the given dimensions return Create(0, name, 0, x1, y1, x2, y2); } //+------------------------------------------------------------------+ //| Dialog window creation method | //+------------------------------------------------------------------+ bool CConsoleDialog::Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2) { // Call the parent method to create the dialog if(!CAppDialog::Create(chart, name, subwin, x1, y1, x2, y2)) { return false; } // Set the size of the minimized dialog window m_min_rect.SetBound(0, DIALOG_VERTICAL_MARGIN, 250, DIALOG_VERTICAL_MARGIN + CONTROLS_DIALOG_MINIMIZE_HEIGHT); // Create a canvas if(!CreateCanvas()) { return false; } // Save the previous mouse scroll event handling settings m_mouseWheel = ChartGetInteger(0, CHART_EVENT_MOUSE_WHEEL); // Set up tracking mouse scroll events ChartSetInteger(chart, CHART_EVENT_MOUSE_WHEEL, 1); // Set the initial text position in the window m_startRow = 0; m_startCol = 0; return true; }
El valor del margen superior desde el borde de la ventana del gráfico se indica mediante la constante DIALOG_VERTICAL_MARGIN. Esta separación permite ver el nombre del símbolo y el periodo de tiempo en la parte superior del gráfico, así como el nombre del asesor en ejecución. Haciendo clic en el nombre del asesor podrás acceder rápidamente a sus parámetros. Si el cuadro de diálogo comenzara desde la parte superior del gráfico, esta opción no existiría. Sin embargo, si por algún motivo resulta innecesario, simplemente podemos establecer el valor de la constante mencionada anteriormente en 0, y luego el cuadro de diálogo ocupará toda el área disponible del gráfico.
Gestión de eventos
El método ChartEvent() es responsable de manejar varios eventos de gráficos. Básicamente, procesaremos los eventos de desplazamiento de la rueda del ratón (CHARTEVENT_MOUSE_WHEEL). Si la ventana no está minimizada, se verificarán las teclas presionadas: manteniendo presionada la tecla Shift desplazamos el texto horizontalmente si la anchura excede el rango visible; si no hay teclas adicionales, el texto se desplazará verticalmente cuando su altura supere el área visible; y manteniendo presionada la tecla Ctrl podremos cambiar el tamaño de fuente escalando el texto. Si el tamaño del gráfico cambia, el método adaptará automáticamente el tamaño de la ventana, expandiéndola para llenar toda el área disponible si es necesario. Todos los demás eventos se procesarán en la clase básica CAppDialog.
//+------------------------------------------------------------------+ //| Event handling | //+------------------------------------------------------------------+ void CConsoleDialog::ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { // Handle the mouse wheel scroll event if(id == CHARTEVENT_MOUSE_WHEEL) { // If the dialog window is minimized, then we do not handle this event if(m_minimized) { return; } // Parse the state of the buttons and the mouse wheel for this event int flg_keys = (int)(lparam >> 32); // Flag of the states of the Ctrl, Shift keys and mouse buttons int delta = (int)dparam; // total value of the wheel scroll, // triggered when +120 or -120 is reached // If the SHIFT key is pressed, if((flg_keys & 0x0004) != 0) { // If the number of symbols in the string is greater than the number of visible // symbols in the dialog, then we perform a horizontal shift if(m_totalCols > m_visibleCols) { // For one scroll event we will move by 2 symbols (120 / 60 = 2) delta /= 60; // If the new start position is within the allowed range, if(m_startCol - delta >= 0 && m_startCol - delta <= m_totalCols - m_visibleCols + 2) { // Save the new starting position m_startCol -= delta; // Update the canvas UpdateCanvas(); } } } else if (flg_keys == 0) { // Otherwise, if the number of lines of text is greater than the number of visible // lines in the dialog, then we perform a vertical shift if(m_totalRows > m_visibleRows) { // For each scroll event we will move by 1 line (120 / 120 = 1) delta /= 120; // If the new start position is within the allowed range, if(m_startRow - delta >= 0 && m_startRow - delta <= m_totalRows - m_visibleRows + 1) { // Save the new starting position m_startRow -= delta; // Update the canvas UpdateCanvas(); } } } else if((flg_keys & 0x0008) != 0) { // Otherwise, if the CTRL key is pressed, we try to set a new font size if(FontSize(m_fontSize + delta / 120)) { // Update the canvas UpdateCanvas(); } } return; } // Handle chart changing event if(id == CHARTEVENT_CHART_CHANGE) { // If the display size changed if(m_chart.HeightInPixels(m_subwin) != Height() + DIALOG_VERTICAL_MARGIN || m_chart.WidthInPixels() != Width()) { // Set new size for the dialog window m_norm_rect.SetBound(0, DIALOG_VERTICAL_MARGIN, m_chart.WidthInPixels(), m_chart.HeightInPixels(m_subwin)); // If the dialog window is not minimized, if(!m_minimized) { // maximize it to fill the chart area with new dimensions Maximize(); } return; } } // Handle other events in the parent class CAppDialog::ChartEvent(id, lparam, dparam, sparam); }
Como no utilizamos componentes que sean descendientes de la clase CWndObj en este cuadro de diálogo, no podemos usar macros estándar para crear la función OnEvent(), que vincula los eventos de los componentes del cuadro de diálogo y sus funciones de controlador. El componente CCanvas que estamos usando nos obliga a usar el manejador de eventos de gráfico general ChartEvent().
Minimización
Al minimizar una ventana utilizando el método Minimize(), se eliminar el lienzo, lo cual liberará los recursos que este utiliza. Después de ello, se llamará a la implementación básica para cambiar el estado de la ventana. De forma similar, al maximizar con el método Maximize(),, primero se llama al método padre para maximizar la ventana, después de lo cual se crea el lienzo y se actualiza la visualización del texto para garantizar una muestra correcta dadas las nuevas dimensiones del área del cliente.
//+------------------------------------------------------------------+ //| Minimize the dialog window | //+------------------------------------------------------------------+ void CConsoleDialog::Minimize() { // Delete the canvas m_canvas.Destroy(); // Call the parent Minimize method CAppDialog::Minimize(); } //+------------------------------------------------------------------+ //| Maximize the dialog window | //+------------------------------------------------------------------+ void CConsoleDialog::Maximize() { // Call the parent Maximize method CAppDialog::Maximize(); // Create a canvas CreateCanvas(); // Display text on the canvas UpdateCanvas(); }
Tal vez nos resulte más cómodo en el futuro escribir una clase contenedora para el lienzo, convirtiéndolo en un descendiente de la clase CWndObj. Pero por ahora este enfoque nos bastará.
Trabajando con texto
Para establecer o cambiar el texto mostrado, utilizaremos el método Text(). Este comprueba si el nuevo texto es diferente del actual. De ser así, la línea original se dividirá en un array de líneas en el carácter de avance de línea '\n'. Después de esto, se guarda el número de líneas y se determina la longitud máxima de la línea más larga. Estos datos son necesarios para organizar correctamente el desplazamiento y la visualización. Luego, se actualiza el lienzo para mostrar el nuevo texto.
//+------------------------------------------------------------------+ //| Set a text | //+------------------------------------------------------------------+ void CConsoleDialog::Text(string text) { // If the text changes, if(text != m_text) { // Save the new text m_text = text; // Divide the text into lines StringSplit(m_text, '\n', m_lines); // Remember the number of lines m_totalRows = ArraySize(m_lines); // Define the maximum length of lines m_totalCols = 0; FOREACH(m_lines) { m_totalCols = MathMax(m_totalCols, StringLen(m_lines[i])); } // Display text on the canvas UpdateCanvas(); } }
Configuración de la fuente y el color
El método FontName() permite establecer el nombre de la fuente utilizada para mostrar texto y actualiza la configuración del lienzo en consecuencia.
El cambio del tamaño de fuente se implementa en el método FontSize(), que toma un nuevo valor y comprueba que esté dentro de límites razonables (de 8 a 72). Si el cambio se realiza con éxito, la posición de desplazamiento se restablecerá al inicio del texto y las propiedades de fuente del lienzo se actualizarán para reflejar el nuevo valor de tamaño. Además, para el nuevo tamaño, se calcularán y guardarán los valores de anchura y altura del carácter para calcular correctamente la parte visible del texto.
El método FontColor() permite establecer el color de la fuente.
//+------------------------------------------------------------------+ //| Set the font name | //+------------------------------------------------------------------+ void CConsoleDialog::FontName(string p_fontName) { // Save the new font name m_fontName = p_fontName; // Update the canvas font UpdateCanvasFont(); } //+------------------------------------------------------------------+ //| Set the font size | //+------------------------------------------------------------------+ bool CConsoleDialog::FontSize(int p_fontSize) { // If the size is within reasonable limits, if (p_fontSize >= 8 && p_fontSize <= 72) { // Save the new font size m_fontSize = p_fontSize; // Reset the starting row and column m_startRow = 0; m_startCol = 0; // Update the canvas font UpdateCanvasFont(); return true; } return false; } //+------------------------------------------------------------------+ //| Set the font color | //+------------------------------------------------------------------+ void CConsoleDialog::FontColor(uint p_fontColor) { m_fontColor = p_fontColor; }
Trabajando con el lienzo
El método CreateCanvas() se encarga de crear el lienzo que inicializa el objeto CCanvas con las dimensiones del área de cliente del cuadro de diálogo y especificar un formato de color con un canal alfa. Cuando el lienzo se crea correctamente, los parámetros de fuente y carácter se establecen de inmediato. El método UpdateCanvas() se encarga de dibujar el texto en el lienzo: borra el fondo y luego muestra las líneas visibles, considerando las posiciones de desplazamiento actuales por líneas y caracteres. Para cada línea visible, el comienzo de la línea se recorta si es necesario y el texto se muestra con pequeñas separaciones desde los bordes. Una vez se completa la representación, se realiza una actualización del lienzo para que los cambios sean visibles para el usuario.
Finalmente, el método UpdateCanvasFont() actualiza la configuración de la fuente en el lienzo, calcula las dimensiones de un carácter según la letra "M" y calcula cuántas líneas y caracteres pueden caber en las dimensiones de la ventana actual, lo cual es necesario para desplazarse.
//+------------------------------------------------------------------+ //| Create a canvas | //+------------------------------------------------------------------+ bool CConsoleDialog::CreateCanvas() { // Get the dimensions of the dialog window client area int height = ClientAreaHeight(); int width = ClientAreaWidth(); // If the size is non-zero if(height > 0 && width > 0) { // If an error occurred while creating the canvas, then exit if(!m_canvas.CreateBitmapLabel("display", ClientAreaLeft(), ClientAreaTop(), ClientAreaWidth(), ClientAreaHeight(), COLOR_FORMAT_ARGB_NORMALIZE)) { PrintFormat(__FUNCTION__" | ERROR: Creating canvas %d", GetLastError()); return false; } UpdateCanvasFont(); } return true; } //+------------------------------------------------------------------+ //| Display text on canvas | //+------------------------------------------------------------------+ void CConsoleDialog::UpdateCanvas() { // Erase the canvas with the background color m_canvas.Erase(m_backgroundColor); // For each line that falls within the visible range for (int i = m_startRow; i < MathMin(m_totalRows, m_startRow + m_visibleRows); i++) { // Take the next line of text string line = m_lines[i]; // If it should be shown not from the first symbol, then if (m_startCol > 0) { // Cut out the initial symbols line = StringSubstr(line, m_startCol); } // Display the string on the canvas m_canvas.TextOut(5, 5 + (i - m_startRow) * m_fontSymbolHeight, line, m_fontColor, TA_LEFT | TA_TOP); } // Call the method to draw the canvas on the screen m_canvas.Update(true); } //+------------------------------------------------------------------+ //| Change the canvas font | //+------------------------------------------------------------------+ void CConsoleDialog::UpdateCanvasFont() { // Set font parameters for text output on canvas m_canvas.FontSet(m_fontName, m_fontSize); // Set new sizes of one symbol m_canvas.TextSize("M", m_fontSymbolWidth, m_fontSymbolHeight); // Determine the number of visible lines and symbols per line (columns) m_visibleRows = ClientAreaHeight() / m_fontSymbolHeight; m_visibleCols = ClientAreaWidth() / m_fontSymbolWidth; }
Vamos a guardar el código resultante en el archivo ConsoleDialog.mqh en la carpeta del proyecto y veamos qué cambios deben realizarse en el archivo del asesor-informador para conectar el componente desarrollado.
Conectando el componente
Para mostrar texto en un gráfico utilizando el nuevo componente, abriremos el archivo asesor-informador. Primero, debemos incluir el archivo de biblioteca creado:
#include "ConsoleDialog.mqh"
A continuación, crearemos un objeto de creación e inicio del diálogo global:
CConsoleDialog *dialog;
En el método Init(), antes de iniciar el cálculo y la visualización, agregaremos los comandos para crear e iniciar el cuadro de diálogo:
//+------------------------------------------------------------------+ //| Initialize the EA | //+------------------------------------------------------------------+ int OnInit(void) { // ... // Create and launch a dialog to display the results dialog = new CConsoleDialog(); dialog.Create("Symbols Informer"); dialog.Run(); // Perform a forced recalculation Calculate(true); // Show the results Show(); return(INIT_SUCCEEDED); }
Y finalmente, en la función Show(), reemplazaremos la llamada a la función Comment() con la configuración del texto con los resultados de nuestro cuadro de diálogo:
//+------------------------------------------------------------------+ //| Show results | //+------------------------------------------------------------------+ void Show() { // Get the results as text string text = TextComment(); // Show it on the chart in the dialog window dialog.Text(text); }
Luego guardaremos los cambios realizados en el archivo SymbolsInformer.mq5 en la carpeta del proyecto.
Simulación
Iniciaremos el asesor-informador con los parámetros predeterminados. Como ahora funcionan tanto el desplazamiento como el cambio de tamaño del texto, podemos seleccionar fácilmente el tamaño más cómodo y el área de resultados visibles deseada.
Si nos interesan, por ejemplo, solo los datos sobre el tamaño medio de la vela del EURUSD M30, podemos crear la siguiente visualización aumentando el tamaño de la fuente:

Si queremos ver todos los valores de GBPUSD y EURGBP a la vez, podemos reducir nuevamente el tamaño de la fuente y desplazarnos hacia abajo por el texto:

Podemos adaptar fácilmente el componente desarrollado para su uso en asesores existentes, donde no se utiliza una interfaz gráfica y toda la información se muestra en el gráfico en forma de texto.
Por ejemplo, en el reciente artículo Trading de arbitraje en Forex: sistema comercial matricial para retornar al valor justo con limitación del riesgo, su autor ofrece un ejemplo de este tipo de asesor:

Realizando algunos cambios menores en su código fuente, como se describe en el apartado de conexión del componente, obtendremos la siguiente imagen:

De esta forma resulta mucho más cómodo y agradable percibir la información.
Conclusión
Hoy hemos mejorado ligeramente la primera versión del asesor-informador auxiliar, que muestra información sobre los tamaños promedio de las velas en puntos y las longitudes de las series de velas unidireccionales. De paso, hemos desarrollado un componente que podría ser útil en muchos otros asesores.
Pero por ahora tenemos un asesor responsable de la parte de los cálculos y de mostrar los resultados. La próxima vez intentaremos separar estas dos partes para ofrecer más flexibilidad. Planeamos transferir este enfoque a un asesor comercial multidivisa.
Gracias por su atención, ¡hasta pronto!
Advertencia importante
Todos los resultados expuestos en este artículo y en todos los artículos anteriores de la serie se basan únicamente en datos de pruebas históricas y no ofrecen ninguna garantía de lograr beneficios en el futuro. El trabajo de este proyecto es de carácter exploratorio. Todos los resultados publicados pueden ser usados por cualquiera bajo su propia responsabilidad.
Contenido del archivo
| # | Nombre | Versión | Descripción | Cambios recientes |
|---|---|---|---|---|
| SymbolsInformer | Carpeta de trabajo del proyecto | |||
| 1 | SymbolsInformer.mq5 | 1.01 | Asesor experto mostrar información sobre las longitudes de las series de velas unidireccionales | Parte 27 |
| 2 | CConsoleDialog.mqh | 1.00 | Parte 27 | |
| 3 | AbbyCross.mq5 | — | Ejemplo de un archivo de asesor de terceros con la clase CConsoleDialog incluida | |
| SymbolsInformer/Include/Adwizard/Utils | Utilidades auxiliares, macros para la reducción del código | |||
| 4 | Macros.mqh | 1.07 | Macros útiles para operaciones con arrays | Parte 26 |
| 5 | NewBarEvent.mqh | 1.00 | Clase de definición de una nueva barra para un símbolo específico | Parte 8 |
Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/17883
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.
Creación de un Panel de administración de operaciones en MQL5 (Parte X): Interfaz basada en recursos externos
Indicador del modelo CAPM en el mercado Forex
Minería de datos de los balances de los bancos centrales y obtención de un panorama de la liquidez global
Reimaginando las estrategias clásicas (Parte 14): Configuraciones de alta probabilidad
- 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