English Русский Español Português
preview
Entwicklung eines Expert Advisors für mehrere Währungen (Teil 27): Komponente zur Anzeige von mehrzeiligem Text

Entwicklung eines Expert Advisors für mehrere Währungen (Teil 27): Komponente zur Anzeige von mehrzeiligem Text

MetaTrader 5Beispiele |
17 0
Yuriy Bykov
Yuriy Bykov

Inhalt


Einführung

Im vorigen Abschnitt haben wir eine Basisversion eines Hilfs-EA-Informers erstellt, der Informationen über die durchschnittliche Kerzengröße in Punkten und die Länge von Kerzenfolgen in derselben Richtung anzeigt. Dies steht nicht in direktem Zusammenhang mit unserem Hauptprojekt – einem System zur automatischen Optimierung und zum Start von EAs für mehrere Währungen, die eine Vielzahl einfacher Strategien umsetzen. Die Weiterentwicklung des EA-Informers wird vorerst Teil dieser Artikelreihe bleiben, da wir bereits damit begonnen haben, die Umsetzung verschiedener Komponenten zu erproben und zu verfeinern, die wir anschließend hoffentlich erfolgreich in das Hauptprojekt integrieren können.

Wir haben auf eine besser optimierte Codestruktur umgestellt, was die Möglichkeit eröffnet, die Arbeit in verschiedenen Bereichen der Adwizard-Bibliotheksentwicklung parallel durchzuführen. Einer dieser Bereiche ist die Erstellung einer grafischen Benutzeroberfläche zur Verwaltung der erzeugten EAs. Das in diesem Artikel behandelte EA-Informer-Projekt wird uns dabei helfen, verschiedene Ansätze zur Implementierung der Schnittstelle ohne unnötige Komplexität weiter zu untersuchen. Nachdem wir ihre Vor- und Nachteile geprüft haben, werden wir in der Lage sein, die am besten geeignete Option auszuwählen und das Hauptprojekt zielgerichtet weiterzuentwickeln.

Letztes Mal haben wir eine Implementierung des Berechnungsteils geschrieben, an die keine strengen Anforderungen hinsichtlich der Effizienz gestellt wurden. Zur Darstellung der Berechnungsergebnisse haben wir zwei einfache Methoden verwendet, die standardmäßig zur Verfügung stehen. Die erste Möglichkeit besteht darin, die Standardfunktion „Comment()“ zu verwenden, die den übergebenen Text direkt im Chart anzeigt. Die zweite Möglichkeit besteht darin, eine weitere Standardfunktion namens Print() zu verwenden, um Text in den EA-Protokollen anzuzeigen. Das ist für einfache Aufgaben sehr praktisch.

Diese Methoden weisen jedoch eine Reihe von Einschränkungen auf. Das Hauptproblem bei der ersten Variante ist die fehlende Kontrolle über Schriftgröße, Schriftart und Farbe sowie die Unmöglichkeit, durch den Text zu scrollen, wenn es sich um eine große Informationsmenge handelt. Dies führt zu Unannehmlichkeiten, insbesondere bei der Ausgabe mehrzeiliger oder strukturierter Daten. Die zweite Methode hat dieselben Nachteile – mit Ausnahme der Scrollfunktion – und zusätzlich den Nachteil, dass fortlaufend neue Protokolleinträge geschrieben werden.  

Daher werden wir in diesem Artikel eine eigene Komponente erstellen – ein Dialogfenster über die gesamte Chartfläche, das mehrzeiligen Text mit flexiblen Schriftarteneinstellungen und Scroll-Unterstützung anzeigen kann. Dieses Tool macht die Visualisierung von Informationen einfacher und übersichtlicher. Nachdem wir diese Komponente in der Praxis getestet haben, wird sie wahrscheinlich als Tool zur Darstellung verschiedener Arten von Informationen über EAs mit mehreren Währungen in die Adwizard-Bibliothek aufgenommen.


Den weiteren Weg planen

Lassen Sie uns die Funktionen auflisten, die wir umsetzen möchten:

  • Anzeige von mehrzeiligem Text – der Komponente wird ein vollständig formatierter Text in Form einer String-Variablen übergeben, der Zeilenumbruchzeichen enthalten kann. Jeder durch Zeilenvorschubzeichen getrennte Abschnitt wird im Chartfenster in einer neuen Zeile angezeigt.

  • Scrollen des Textes – Wenn der Text nicht vollständig in den verfügbaren Anzeigebereich passt, können Sie mit dem Mausrad vertikal und (bei gedrückter Umschalttaste) horizontal scrollen. Wir werden vorerst keine Bildlaufleisten anzeigen, könnten sie aber später hinzufügen.

  • Ändern der Schriftgröße – Mit der Strg-Taste und dem Mausrad können wir die Schriftgröße, in der der Text angezeigt wird, vergrößern oder verkleinern. 

  • Unterstützung für die Änderung von Schriftartparametern – Schriftart, Textfarbe und Hintergrundfarbe. Vorerst werden diese Parameter nur programmgesteuert geändert. In Zukunft können Sie eine Schnittstelle hinzufügen, über die diese Parameter während der Programmausführung geändert werden können.

  • Automatische Anpassung an Änderungen der Chartgröße – Wenn der Benutzer Aktionen durchführt, die die Größe des Chartfensters verändern, in dem der EA läuft, der diese Komponente für die Ausgabe nutzt, ändert sich auch die Größe des Textbereichs, wobei dieser weiterhin den gesamten verfügbaren Bereich für die Ausgabe einnimmt.

  • Minimieren – Möglichkeit, den Ausgabe-Bereich zu minimieren und zu maximieren.

Möglicherweise müssen wir einige der Anforderungen im Laufe der Umsetzung noch weiter präzisieren, aber die obige Liste ist vollkommen ausreichend.


Die Klasse „CConsoleDialog“

Erstellen wir eine neue Klasse namens CConsoleDialog. Wir werden sie zu einer Unterklasse der bestehenden Standardbibliotheksklasse CAppDialog machen, da diese übergeordnete Klasse bereits einen Großteil dessen enthält, was wir implementieren wollten. So ist beispielsweise die Anzeige eines Fensters mit Schaltflächen zum Minimieren/Maximieren und Schließen der EA-Anwendung bereits fertiggestellt. Nun müssen wir uns nur noch um den Inhalt des Clientbereichs des Fensters kümmern – dort wird der Text angezeigt.

Zur Darstellung des Textes verwenden wir ein Objekt der Klasse CCanvas für die Textdarstellung, während die Unterstützung für das Scrollen und die Änderung der Schriftgröße durch die Verarbeitung von Chart-Ereignissen implementiert wird.

So wird die Beschreibung der neuen Klasse aussehen:

//+------------------------------------------------------------------+
//| 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);
};

Von allen aufgeführten öffentlichen Methoden werden wir vorerst hauptsächlich die Methode zum Festlegen eines neuen Text() sowie die erste Version der Create() -Methode verwenden, mit der wir ein Dialogfenster erstellen können, indem wir lediglich dessen Namen angeben. Sie wird außerdem als Beschriftung in der Fensterleiste verwendet. 


Konstruktor und Destruktor

Beim Erstellen eines Objekts der Klasse CConsoleDialog initialisiert der Konstruktor die Standardschriftart, bei der es sich um die Monospace-Schriftart „Consolas“ in der Schriftgröße 13 handelt, wobei die Textfarbe auf Schwarz mit leichter Transparenz eingestellt ist. Diese Schriftart wurde gewählt, damit tabellarische Daten als Text dargestellt werden können und dabei genau wie Tabellen mit gleichmäßigen Spalten aussehen. Ohne Monospace-Schrift sind gleichmäßig ausgerichtete Tabellen unmöglich.

Eine Schriftgröße von 13 Pixeln ist einerseits klein genug, um eine große Textmenge darzustellen, andererseits aber nicht so klein, dass sie unleserlich wird. Da die Größe künftig problemlos geändert werden kann, spielt die Wahl eines bestimmten Ausgangswerts keine besondere Rolle. Die Hintergrundfarbe wird transparent gemacht, sodass wir durch die Canvas hindurch die in der Klasse CDialog verwendete standardmäßige graue Hintergrundfarbe sehen können.

Um eine korrekte Darstellung zu gewährleisten, wird sofort die Methode FontSize() aufgerufen, um die grundlegenden Parameter für die Darstellung von Text auf der Canvas festzulegen. Der Destruktor wiederum ist dafür zuständig, die Canvas-Ressource ordnungsgemäß zu löschen und die ursprünglichen Einstellungen für die Verarbeitung von Mausrad-Scroll-Ereignissen im Chart wiederherzustellen.

//+------------------------------------------------------------------+
//| 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);
}


Ein Dialogfenster erstellen

Es gibt zwei Varianten der Methode Create(), mit denen ein Fenster erstellt werden kann. Die erste Option akzeptiert nur den Fensternamen und passt die Position und Größe des Fensters automatisch an den gesamten Chart an, wobei oben ein kleiner Rand verbleibt. Die Methode berechnet die Abmessungen des Charts und ruft die zweite Option Create() mit bestimmten Koordinaten auf.

Mit der zweiten Methode können wir ein Dialogfenster mit bestimmten Parametern erstellen – Chartnummer, Name, Nummer des Unterfensters und Koordinaten. Die Methode ruft zunächst die übergeordnete Implementierung auf, um das Fenster zu erstellen, legt dann die Abmessungen für den minimierten Zustand fest, erstellt die Canvas, aktiviert die Erfassung von Maus-Scroll-Ereignissen und initialisiert die Positionen des sichtbaren Textbereichs, sodass die Anzeige am Anfang beginnt.

//+------------------------------------------------------------------+
//| 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;
}

Der Wert des oberen Randes vom Rand des Chartfensters wird durch die Konstante DIALOG_VERTICAL_MARGIN festgelegt. Dank dieses Randes können wir oben im Chart den Symbolnamen und den Zeitrahmen sowie den Namen des laufenden EAs sehen. Durch einen Klick auf den Namen des EAs können wir schnell auf dessen Parameter zugreifen. Wenn das Dialogfenster ganz oben im Chart beginnen würde, gäbe es diese Option nicht. Sollte sich dies jedoch plötzlich als unnötig erweisen, können Sie den Wert der oben genannten Konstante einfach auf 0 setzen; dann nimmt das Dialogfenster tatsächlich den gesamten verfügbaren Bereich des Charts ein.


Die Ereignisbehandlung

Die Methode ChartEvent() ist für die Verarbeitung verschiedener Chartereignisse zuständig. Im Grunde genommen werden wir Scroll-Ereignisse des Mausrads (CHARTEVENT_MOUSE_WHEEL) verarbeiten. Wenn das Fenster nicht minimiert ist, werden die gedrückten Tasten berücksichtigt: Durch Gedrückthalten der Umschalttaste wird der Text horizontal gescrollt, wenn die Breite den sichtbaren Bereich überschreitet; wenn keine weiteren Tasten gedrückt sind, wird vertikal gescrollt, wenn die Texthöhe den sichtbaren Bereich überschreitet; und durch Gedrückthalten der Strg-Taste können Sie die Schriftgröße durch Skalieren des Textes ändern. Ändert sich die Größe des Charts, passt die Methode die Fenstergröße automatisch an und vergrößert sie gegebenenfalls so, dass sie den gesamten verfügbaren Bereich ausfüllt. Alle anderen Ereignisse werden in der Basisklasse CAppDialog behandelt.

//+------------------------------------------------------------------+
//| 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);
}

Da wir in diesem Dialogfeld keine Komponenten verwenden, die von der Klasse CWndObj erben, können wir keine Standardmakros verwenden, um die Funktion OnEvent() zu generieren, die die Ereignisse der Dialogfeldkomponenten mit ihren Handler-Funktionen verknüpft. Die verwendete Komponente CCanvas erzwingt die Verwendung des allgemeinen Chart-Ereignisbehandlers ChartEvent().


Minimieren

Wenn ein Fenster mit der Methode Minimize() minimiert wird, wird die Canvas zerstört, wodurch die belegten Ressourcen freigegeben werden. Anschließend wird die Basisimplementierung aufgerufen, um den Fensterzustand zu ändern. Ebenso wird bei der Maximierung mit der Methode Maximize() zunächst die übergeordnete Methode aufgerufen, um das Fenster zu maximieren. Anschließend wird die Canvas erstellt und die Textanzeige aktualisiert, um angesichts der neuen Abmessungen des Clientbereichs eine korrekte Darstellung zu gewährleisten.

//+------------------------------------------------------------------+
//| 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();
}

Es könnte für uns in Zukunft praktischer sein, eine Wrapper-Klasse für Canvas zu schreiben und diese zu einem Nachkommen der Klasse CWndObj zu machen. Aber vorerst reicht dieser Ansatz völlig aus.


Handhaben von Text

Um den angezeigten Text festzulegen oder zu ändern, wird die Methode Text() verwendet. Es wird geprüft, ob sich der neue Text vom aktuellen unterscheidet. Wenn ja, wird die ursprüngliche Zeichenkette am Zeilenumbruchzeichen „\n“ in ein Array von Zeichenketten aufgeteilt. Anschließend wird die Anzahl der Zeilen gespeichert und die maximale Länge der längsten Zeile ermittelt. Diese Daten sind für die korrekte Darstellung des Bildlaufs und der Anzeige erforderlich. Anschließend wird eine Bildschirmaktualisierung ausgelöst, um den neuen Text anzuzeigen.

//+------------------------------------------------------------------+
//| 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();
   }
}


Schriftart und Farbe festlegen

Mit der Methode FontName() kann der Name der zur Textanzeige verwendeten Schriftart festgelegt werden, woraufhin die Einstellungen der Canvas entsprechend angepasst werden.

Die Änderung der Schriftgröße wird in der Methode FontSize() umgesetzt, die einen neuen Wert entgegennimmt und prüft, ob dieser innerhalb eines angemessenen Bereichs liegt (von 8 bis 72). Wenn die Änderung erfolgreich ist, wird die Bildlaufposition auf den Anfang des Textes zurückgesetzt und die Schriftarteigenschaften der Canvas werden aktualisiert, um den neuen Größenwert widerzuspiegeln. Außerdem werden für die neue Größe die Breiten- und Höhenwerte eines Symbols berechnet und gespeichert, um den sichtbaren Teil des Textes korrekt zu berechnen.

Mit der Methode FontColor() lässt sich die Schriftfarbe festlegen.

//+------------------------------------------------------------------+
//| 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;
}


Arbeiten mit Canvas

Die Methode „CreateCanvas()“ ist für die Erstellung der Canvas zuständig, initialisiert ein CCanvas-Objekt mit der Größe des Clientbereichs des Dialogfensters und legt ein Farbformat mit Alphakanal fest. Sobald die Canvas erfolgreich erstellt wurde, werden die Schriftart- und Symbolparameter sofort festgelegt. Die Methode UpdateCanvas() ist für die eigentliche Darstellung des Textes auf der Canvas zuständig: Sie löscht den Hintergrund und zeigt dann die sichtbaren Zeilen an, wobei sie die aktuellen Scrollpositionen nach Zeilen und Zeichen berücksichtigt. Bei jeder sichtbaren Zeile wird der Zeilenanfang gegebenenfalls gekürzt, und der Text wird mit schmalen Rändern angezeigt. Sobald die Darstellung abgeschlossen ist, wird eine Aktualisierung der Canvas ausgelöst, damit die Änderungen für den Benutzer sichtbar werden.

Schließlich aktualisiert die Methode UpdateCanvasFont() die Schriftarteneinstellungen auf der Canvas, berechnet die Größe eines Symbols auf der Grundlage des Buchstabens „M“ und ermittelt, wie viele Zeilen und Symbole in die aktuellen Fensterabmessungen passen – was für das Scrollen erforderlich ist.

//+------------------------------------------------------------------+
//| 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;
}

Speichern Sie den resultierenden Code in der Datei ConsoleDialog.mqh im Projektordner und prüfen Sie, welche Änderungen an der EA-Informer-Datei vorgenommen werden müssen, um die entwickelte Komponente anzubinden.


Einbindung der Komponente

Um mit der neuen Komponente Text in einem Chart anzuzeigen, öffnen Sie die EA-Informer-Datei. Zunächst fügen wir die erstellte Bibliotheksdatei ein:

#include "ConsoleDialog.mqh"

Als Nächstes erstellen wir ein globales Dialogobjekt:

CConsoleDialog *dialog;

In der Methode „OnInit()“ fügen wir Befehle zum Erstellen und Starten des Dialogfelds ein, bevor die Berechnung und die Anzeige gestartet werden:

//+------------------------------------------------------------------+
//| 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);
}

Schließlich ersetzen wir in der Funktion Show() den Aufruf der Funktion Comment() durch die Einstellung des Textes mit den Ergebnissen in unserem Dialogfeld:

//+------------------------------------------------------------------+
//| Show results                                                     |
//+------------------------------------------------------------------+
void Show() {
// Get the results as text
   string text = TextComment();

// Show it on the chart in the dialog window
   dialog.Text(text);
}

Speichern Sie die Änderungen an der Datei SymbolsInformer.mq5 im Projektordner.


Test

Starten Sie den Informer-EA mit den Standardparametern. Da nun sowohl das Scrollen als auch die Textgrößenanpassung funktionieren, können Sie ganz einfach die für Sie angenehmste Größe und den gewünschten sichtbaren Bereich auswählen.

Wenn wir beispielsweise nur an Daten zur durchschnittlichen Kerzenlänge für EURUSD M30 interessiert sind, können wir durch Vergrößern der Schriftgröße folgende Darstellung erstellen:

Wenn wir alle Werte für GBPUSD und EURGBP auf einen Blick sehen möchten, können wir die Schriftgröße erneut verkleinern und im Text nach unten scrollen:

Die entwickelte Komponente lässt sich problemlos für den Einsatz in bestehenden EAs anpassen, in denen keine grafische Benutzeroberfläche verwendet wird und alle Informationen in Textform im Chart angezeigt werden.

Zum Beispiel stellt im kürzlich erschienenen Artikel „Forex-Arbitrage-Handel: Ein Matrix-Handelssystem der Rückkehr zum fairen Wert mit Risikokontrolle“ der Autor ein Beispiel für einen solchen EA vor:

Durch einige geringfügige Änderungen am Quellcode, wie im Abschnitt zum Verbinden der Komponente beschrieben, erhalten wir folgende Ergebnisse:

In dieser Form lassen sich Informationen deutlich komfortabler erfassen.


Schlussfolgerung

Wir haben die erste Version eines Hilfs-EA verbessert, der Informationen über die durchschnittliche Kerzengröße in Punkten sowie die Länge von Kerzenfolgen anzeigt, die sich in dieselbe Richtung bewegen. Dabei haben wir eine Komponente entwickelt, die in vielen anderen EAs nützlich sein könnte.

Derzeit haben wir jedoch einen EA, der sowohl für die Berechnung als auch für die Anzeige der Ergebnisse zuständig ist. Das nächste Mal werden wir versuchen, diese beiden Teile voneinander zu trennen, um mehr Flexibilität zu gewinnen. Wir planen, diesen Ansatz auf den EA für den Handel mit mehreren Währungen zu übertragen.

Vielen Dank für Ihre Aufmerksamkeit! Bis bald!


Wichtige Warnung

Alle in diesem Artikel und in allen vorangegangenen Artikeln dieser Reihe vorgestellten Ergebnisse beruhen lediglich auf historischen Testdaten und sind keine Garantie für zukünftige Gewinne. Die Arbeiten im Rahmen dieses Projekts haben Forschungscharakter. Alle veröffentlichten Ergebnisse können von jedermann auf eigenes Risiko verwendet werden.


Inhalt des Archivs

#
Name Version Beschreibung Jüngste Änderungen
  SymbolsInformer   Arbeitsordner des Projekts  
1 SymbolsInformer.mq5 1.01
Der EA für die Anzeige von Informationen über die Länge von unidirektionalen Kerzenserien
Teil 27
2 CConsoleDialog.mqh 1.00   Teil 27
3 AbbyCross.mq5 Ein Beispiel für eine EA-Datei eines Drittanbieters, die die Klasse „CConsoleDialog“ enthält
  SymbolsInformer/Include/Adwizard/Utils
  Hilfsprogramme, Makros zur Code-Reduzierung  
4 Macros.mqh
1.07 Nützliche Makros für Array-Operationen
Teil 26
5 NewBarEvent.mqh  1.00 Klasse zur Erkennung einer neuen Bar eines bestimmten Symbols Teil 8
Der Quellcode ist außerdem in den öffentlichen Repositorys SymbolsInformer und Adwizard verfügbar.

Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/17883

Beigefügte Dateien |
MQL5.zip (19 KB)
Die Übertragung der Trading-Signale in einem universalen Expert Advisor. Die Übertragung der Trading-Signale in einem universalen Expert Advisor.
In diesem Artikel wurden die verschiedenen Möglichkeiten beschrieben, um die Trading-Signale von einem Signalmodul des universalen EAs zum Steuermodul der Positionen und Orders zu übertragen. Es wurden die seriellen und parallelen Interfaces betrachtet.
CAPM-Indikator für den Forex-Markt CAPM-Indikator für den Forex-Markt
Anpassung des klassischen CAPM-Modells für den Forexmarkt in MQL5. Der Indikator berechnet die erwartete Rendite und die Risikoprämie auf der Grundlage der historischen Volatilität. Die Indikatoren steigen an Hochs und Tiefs an und spiegeln damit die grundlegenden Prinzipien der Preisbildung wider. Praktische Anwendung von Contra-Trend- und Trendfolgestrategien unter Berücksichtigung der Dynamik des Risiko-Ertrags-Verhältnisses in Echtzeit. Der Artikel behandelt mathematische Grundlagen und die technische Umsetzung.
Eine alternative Log-datei mit der Verwendung der HTML und CSS Eine alternative Log-datei mit der Verwendung der HTML und CSS
In diesem Artikel werden wir eine sehr einfache, aber leistungsfähige Bibliothek zur Erstellung der HTML-Dateien schreiben, dabei lernen wir auch, wie man eine ihre Darstellung einstellen kann (nach seinem Geschmack) und sehen wir, wie man es leicht in seinem Expert Advisor oder Skript hinzufügen oder verwenden kann.
Anwendung des Grey-Modells in der technischen Analyse von Finanzzeitreihen Anwendung des Grey-Modells in der technischen Analyse von Finanzzeitreihen
Dieser Artikel befasst sich mit dem Grey-Modell, einem vielversprechenden Instrument, das die Möglichkeiten von Händlern erweitern kann. Wir werden uns einige Möglichkeiten ansehen, wie dieses Modell auf die technische Analyse angewendet und zur Entwicklung von Handelsstrategien genutzt werden kann.