English
preview
Erstellen einer interaktiven grafischen Nutzeroberfläche in MQL5 (Teil 1): Erstellen des Panels

Erstellen einer interaktiven grafischen Nutzeroberfläche in MQL5 (Teil 1): Erstellen des Panels

MetaTrader 5Handel | 23 August 2024, 12:18
33 0
Allan Munene Mutiiria
Allan Munene Mutiiria

Einführung

Willkommen zum ersten Teil unseres umfassenden Leitfadens zur Erstellung von nutzerdefinierten grafischen Nutzeroberflächen (GUI) in MetaQuotes Language 5 (MQL5)! Als Händler und Entwickler wissen wir, wie wichtig effiziente und nutzerfreundliche Schnittstellen für unsere Handelsinstrumente sind. In dieser Serie werden wir in die Welt von MQL5 eintauchen und erkunden, wie Sie leistungsstarke GUI-Panels erstellen können, die Ihr Handelserlebnis verbessern.

In diesem ersten Teil werden die Grundlagen behandelt: Einrichten des Projekts, Entwerfen des Layouts des Bedienfelds und Hinzufügen wichtiger Steuerelemente. Im nächsten Teil werden wir das Panel live, interaktiv und responsiv gestalten. Egal, ob Sie ein erfahrener MQL5-Programmierer sind oder gerade erst anfangen, dieser Artikel enthält eine Schritt-für-Schritt-Anleitung, mit der Sie ein funktionales und optisch ansprechendes GUI-Panel erstellen können. Wir werden die oben genannten Ziele mit Hilfe der folgenden Themen erreichen:

  1. Elemente Illustration
  2. GUI-Panel-Montage in MQL5
  3. Schlussfolgerung

Auf dieser Reise werden wir ausgiebig MetaQuotes Language 5 (MQL5) als Basisumgebung für die integrierte Entwicklungsumgebung (IDE) verwenden und die Dateien auf dem MetaTrader 5 (MT5) Trading Terminal ausführen. Daher ist es von größter Bedeutung, dass die oben genannten Versionen vorhanden sind. Fangen wir an.


Illustration der Elemente

Wir werden ein GUI-Panel erstellen, das die gebräuchlichsten Dienstprogramme enthält, die jeder Händler benötigen könnte, und daher wollen wir in dieser Serie alles umreißen und abdecken. Die Anzahl der Elemente, die behandelt werden müssen, ist daher sehr umfangreich, aber wir werden sie zum besseren Verständnis zusammenfassen. Wir werden 4 Elemente für unsere GUI-Entwicklung verwenden, und damit werden wir sie erstellen. Das Panel wird die Erstellung von Handelsschaltflächen, scharfen Rechtecken, Live-Updates, die Verwendung von Emojis, verschiedenen Schriftarten, Etiketten, beweglichen Panelteilen und Hover-Effekten ermöglichen. Um das Ganze zu veranschaulichen, haben wir ein Beispiel angeführt.

BEISPIEL GUI


GUI-Panel-Montage in MQL5

Um das Panel zu erstellen, werden wir es auf einen Expertenberater stützen. Um einen Expert Advisor (EA) zu erstellen, klicken Sie auf Ihrem MetaTrader 5-Terminal auf die Registerkarte Tools und aktivieren Sie MetaQuotes Language Editor oder drücken Sie einfach F4 auf Ihrer Tastatur. Alternativ können Sie auch auf das IDE-Symbol (Integrated Development Environment) in der Symbolleiste klicken. Dadurch wird die MetaQuotes-Spracheditor-Umgebung geöffnet, die das Schreiben von Handelsrobotern, technischen Indikatoren, Skripten und Funktionsbibliotheken ermöglicht.

IDE

Sobald der MetaEditor geöffnet ist, navigieren Sie in der Symbolleiste zur Registerkarte „Datei“ und wählen Sie „Neue Datei“, oder drücken Sie einfach die Tastenkombination STRG + N, um ein neues Dokument zu erstellen. Alternativ können Sie auch auf das Symbol New auf der Registerkarte Werkzeuge klicken. Daraufhin erscheint ein Popup-Fenster des MQL-Assistenten.

NEUER EA

Markieren Sie in dem sich öffnenden Assistenten die Option Expert Advisor (Vorlage) und klicken Sie auf Weiter.

WIZARD

Geben Sie in den allgemeinen Eigenschaften des Expertenberaters unter dem Abschnitt Name den Dateinamen Ihres Experten an. Beachten Sie, dass Sie den Backslash vor dem Namen des EA verwenden, um einen Ordner anzugeben oder zu erstellen, wenn er nicht existiert. Hier haben wir zum Beispiel standardmäßig „Experts\“. Das bedeutet, dass unser EA im Ordner Experts erstellt wird und wir ihn dort finden können. Die anderen Abschnitte sind ziemlich einfach, aber Sie können dem Link am Ende des Assistenten folgen, um zu erfahren, wie der Prozess genau abläuft.

EA-NAME

Nachdem Sie den gewünschten Namen des Expert Advisors eingegeben haben, klicken Sie auf Weiter, dann auf Weiter und schließlich auf Fertig stellen. Nachdem wir all das getan haben, sind wir nun bereit, unser GUI-Panel zu codieren und zu programmieren.

Zunächst müssen wir Funktionen für die 4 Elemente erstellen, die wir benötigen, d. h. für die rechteckige Beschriftung, die Schaltfläche, das Bearbeitungsfeld und die Textbeschriftungen. Dies ist von großem Nutzen, da es uns ermöglicht, dieselbe Funktion bei der Erstellung ähnlicher Merkmale wiederzuverwenden, anstatt den gesamten Prozess bei der Erstellung ähnlicher Objekte wiederholen zu müssen. Außerdem sparen wir dadurch eine Menge Zeit und Platz, da der Prozess schnell und unkompliziert ist und die Codeschnipsel kurz.

Um die rechteckige Beschriftung zu erstellen, werden wir eine Funktion erstellen, die 10 Argumente oder Parameter benötigt.

//+------------------------------------------------------------------+
//|     Function to create rectangle label                           |
//+------------------------------------------------------------------+

bool createRecLabel(string objName, int xD, int yD, int xS, int yS,
                    color clrBg, int widthBorder, color clrBorder = clrNONE,
                    ENUM_BORDER_TYPE borderType = BORDER_FLAT, ENUM_LINE_STYLE borderStyle = STYLE_SOLID) {

...
}

Die Funktionssignatur veranschaulicht alles. Es handelt sich um eine boolesche Funktion mit dem Namen „createRecLabel“, was bedeutet, dass sie bei Erfolg bzw. Misserfolg zwei boolesche Flags, true bzw. false, zurückgibt. Zum besseren Verständnis der Parameter werden diese im Folgenden einzeln erläutert.

  • objName: Dieser Parameter steht für den eindeutigen Label-Namen des Rechteckobjekts. Er dient als Bezeichner für das zu erstellende grafische Element.
  • xD und yD: Diese Parameter bestimmen die X- und Y-Abstände von der Ecke, in der die Rechteckbeschriftung positioniert werden soll. Betrachten Sie sie als die Koordinaten, die die obere linke Ecke des Rechtecks relativ zum Chart definieren.
  • xS und yS: Diese Parameter geben die Breite und Höhe des Rechtecks an. Der Wert xS bestimmt, wie breit das Rechteck horizontal ist, während yS die vertikale Höhe bestimmt.

ENTFERNUNG UND GRÖSSE

  • clrBg: Der Parameter clrBg gibt die Hintergrundfarbe der Rechteckbeschriftung an. Wählen Sie eine Farbe, die einen guten Kontrast zum Hintergrund des Charts bildet oder die andere Elemente ergänzt.
  • widthBorder: Dieser Parameter bestimmt die Breite des Rahmens um das Rechteck. Wenn Sie einen Rand wünschen, geben Sie einen positiven Wert ein; andernfalls verwenden Sie Null, um keinen Rand zu erhalten.
  • clrBorder: Optionaler Parameter für die Farbe des Rahmens. Wenn Sie einen Rahmen wünschen, geben Sie eine Farbe an (z. B. clrNONE für keine Rahmenfarbe).
  • borderType: Gibt die Art des Rahmens für das Rechteck an. Zur Auswahl stehen flache, erhabene oder andere Formen. Für einen einfachen flachen Rahmen verwenden Sie BORDER_FLAT.
  • borderStyle: Wenn Sie einen flachen Rahmen wählen, bestimmt dieser Parameter den Linienstil (z. B. durchgezogen, gestrichelt). Verwenden Sie STYLE_SOLID für eine durchgehende Linie.

In der Funktionssignatur sollten Sie bemerkt haben, dass einige der Argumente bereits auf einen Wert initialisiert sind. Der Initialisierungswert stellt den Standardwert dar, der diesem Parameter zugewiesen wird, falls er während des Funktionsaufrufs ignoriert wird. Unsere Standard-Rahmenfarbe ist beispielsweise „none“, d. h., wenn der Farbwert während des Funktionsaufrufs nicht angegeben wird, wird für den Rand unseres Rechtecks keine Farbe verwendet. 

Innerhalb des Funktionskörpers, der von geschweiften Klammern ({}) eingerahmt wird, definieren wir unsere Prozeduren zur Erstellung von Objekten. 

    // Create a rectangle label object
    if (!ObjectCreate(0, objName, OBJ_RECTANGLE_LABEL, 0, 0, 0)) {
        Print(__FUNCTION__, ": failed to create rec label! Error code = ", _LastError);
        return (false); // Return false if object creation fails
    }

Wir beginnen mit einer if-Anweisung, um zu prüfen, ob das Objekt nicht erstellt wurde. Wir verwenden die Funktion ObjectCreate, die einen boolescher Wert zurückgibt und 6 Argumenten hat. Diese Funktion erstellt ein Objekt mit dem angegebenen Namen, Typ und den Anfangskoordinaten im angegebenen Teilfenster des Charts. Zunächst geben wir das Chartfenster an, 0 bedeutet, dass das Objekt im Hauptfenster erstellt werden soll. Dann geben wir den Objektnamen an. Dies ist der Name, der einem bestimmten Objekt eindeutig zugewiesen wird. Das zu erstellende Objekt ist vom Typ „OBJ_RECTANGLE_LABEL“, d.h. es handelt sich um ein Objekt zur Erstellung und Gestaltung der nutzerdefinierten grafischen Oberfläche. Anschließend wird das Fenster angegeben, 0 für das aktuelle Chartfenster. Schließlich geben wir die Zeit- und Preiswerte als Null (0) an, da wir sie nicht mit dem Chart, sondern mit den Koordinaten des Chartfensters verbinden werden. Die Zuordnung wird mit Hilfe von Pixeln festgelegt.

Wenn die Erstellung des Objekts fehlschlägt, also die Funktion „ObjectCreate“ false zurückgibt, hat es keinen Sinn, weiterzumachen, wir kehren mit einem Fehler zurück. In diesem Fall informieren wir über den Fehler, indem wir ihn neben dem Fehlercode in das Journal drucken und false zurückgeben. Es könnte ein vorheriger Fehler vorliegen, und um den neuesten Fehler zu erhalten, müssen wir den vorherigen Fehler löschen. Dies geschieht durch den Aufruf der Funktion „ResetLastError“, einer intgrierten MQL5-Funktion, unmittelbar vor der Logik der Objekterstellung. 

    ResetLastError(); // Reset any previous error codes

Der Zweck der Funktion besteht darin, den Wert der vordefinierten Variablen „_LastError“, in der der Fehlercode der letzten fehlerhaften Operation gespeichert ist, auf Null zu setzen. Durch den Aufruf dieser Funktion wird sichergestellt, dass alle vorherigen Fehlercodes gelöscht werden, bevor mit den nächsten Operationen fortgefahren wird. Dieser Schritt ist wichtig, weil er es uns ermöglicht, neue Fehler unabhängig von früheren Fehlerzuständen zu behandeln.

Wenn wir bis zu diesem Punkt nicht zurückkehren, bedeutet dies, dass wir das Objekt erstellt haben, und wir können mit der Aktualisierung der Eigenschaften des Objekts fortfahren. Eine eingebaute Funktion „ObjectSet...“ setzt den Wert der entsprechenden Objekteigenschaft. Die Objekteigenschaft muss vom Typ datetime, integer, color, boolean oder character sein.

    // Set properties for the rectangle label
    ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_XSIZE, xS); // Width of the rectangle
    ObjectSetInteger(0, objName, OBJPROP_YSIZE, yS); // Height of the rectangle
    ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner
    ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, clrBg); // Rectangle background color
    ObjectSetInteger(0, objName, OBJPROP_BORDER_TYPE, borderType); // Border type
    ObjectSetInteger(0, objName, OBJPROP_STYLE, borderStyle); // Border style (only if borderType is flat)
    ObjectSetInteger(0, objName, OBJPROP_WIDTH, widthBorder); // Border width (only if borderType is flat)
    ObjectSetInteger(0, objName, OBJPROP_COLOR, clrBorder); // Border color (only if borderType is flat)
    ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Not a background object
    ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Not selectable
    ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable
    ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected

Wir wollen uns auf die erste Eigenschaftslogik konzentrieren.

    ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner

Hier verwenden wir die eingebaute Funktion „ObjectSetInteger“ und übergeben die entsprechenden Parameter. Die Parameter sind wie unten beschrieben.

  • Chart id: Dies ist die ID des Charts. „0“ bezieht sich auf das aktuelle Chart (Chart-ID). Wir passen die Eigenschaften eines Objekts in diesem Chart an.
  • Name: Dies ist der Name des Objekts: „objName“ steht für den eindeutigen Namen, der dem Rechteckbeschriftungsobjekt zugewiesen wurde.
  • Property id: Dies ist die ID der Objekteigenschaft und ihr Wert kann einer der Werte der Aufzählung „ENUM_OBJECT_PROPERTY_INTEGER“ sein. „OBJPROP_XDISTANCE“ gibt an, dass wir die Eigenschaft X-Distanz ändern.
  • Property Wert: Dies ist der Eigenschaftswert. Der Wert, der „xD“ zugewiesen wird, bestimmt, wie weit rechts (oder links, falls negativ) die obere linke Ecke unserer Rechteckbeschriftung horizontal vom linken Rand des Charts positioniert wird.

Auch die anderen Eigenschaften werden nach demselben Schema festgelegt. „OBJPROP_YDISTANCE“ konfiguriert die Y-Abstandseigenschaft der Rechteckbeschriftung. Der Wert „yD“ legt fest, wie weit die linke obere Ecke der Rechteckbeschriftung vertikal vom oberen Rand des Charts entfernt sein soll. Mit anderen Worten, sie steuert die vertikale Platzierung der Beschriftung innerhalb des Chartbereichs. Damit wird der Y-Abstand von der Ecke festgelegt. Mit „OBJPROP_XSIZE“ und „OBJPROP_YSIZE“ wird die Breite bzw. Höhe des Rechtecks festgelegt. 

Um unser Objekt zu positionieren, verwenden wir die Eigenschaft „OBJPROP_CORNER“, um die Ecke zu bestimmen, in der sich unser Objekt im Chartfenster befinden soll.

    ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner

Es kann nur 4 Eigenschaftsarten geben:

  • CORNER_LEFT_UPPER: Der Mittelpunkt der Koordinaten befindet sich in der oberen linken Ecke des Charts.
  • CORNER_LEFT_LOWER: Der Mittelpunkt der Koordinaten befindet sich in der unteren linken Ecke des Charts.
  • CORNER_RIGHT_LOWER: Der Mittelpunkt der Koordinaten befindet sich in der unteren rechten Ecke des Charts.
  • CORNER_RIGHT_UPPER: Der Mittelpunkt der Koordinaten befindet sich in der oberen rechten Ecke des Charts.

In einer fotografischen Darstellung haben wir das hier.

Ecken

Der Rest der Eigenschaften ist einfach zu handhaben. Zum besseren Verständnis haben wir sie mit Kommentaren versehen. Dann wird das Chart einfach neu gezeichnet, damit die Änderungen automatisch wirksam werden, ohne dass auf eine Änderung der Kursnotierungen oder der Chartereignisse gewartet werden muss. 

    ChartRedraw(0); // Redraw the chart

Schließlich geben wir true zurück, was bedeutet, dass die Erstellung und Aktualisierung der Objekteigenschaften erfolgreich war.

    return (true); // Return true if object creation and property settings are successful

Der vollständige Funktionscode, der für die Erstellung eines Rechteckobjekts im Chartfenster verantwortlich ist, lautet wie folgt.

bool createRecLabel(string objName, int xD, int yD, int xS, int yS,
                    color clrBg, int widthBorder, color clrBorder = clrNONE,
                    ENUM_BORDER_TYPE borderType = BORDER_FLAT, ENUM_LINE_STYLE borderStyle = STYLE_SOLID) {
    ResetLastError(); // Reset any previous error codes
    
    // Create a rectangle label object
    if (!ObjectCreate(0, objName, OBJ_RECTANGLE_LABEL, 0, 0, 0)) {
        Print(__FUNCTION__, ": failed to create rec label! Error code = ", _LastError);
        return (false); // Return false if object creation fails
    }
    
    // Set properties for the rectangle label
    ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_XSIZE, xS); // Width of the rectangle
    ObjectSetInteger(0, objName, OBJPROP_YSIZE, yS); // Height of the rectangle
    ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner
    ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, clrBg); // Rectangle background color
    ObjectSetInteger(0, objName, OBJPROP_BORDER_TYPE, borderType); // Border type
    ObjectSetInteger(0, objName, OBJPROP_STYLE, borderStyle); // Border style (only if borderType is flat)
    ObjectSetInteger(0, objName, OBJPROP_WIDTH, widthBorder); // Border width (only if borderType is flat)
    ObjectSetInteger(0, objName, OBJPROP_COLOR, clrBorder); // Border color (only if borderType is flat)
    ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Not a background object
    ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Not selectable
    ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable
    ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected
    
    ChartRedraw(0); // Redraw the chart
    
    return (true); // Return true if object creation and property settings are successful
}

Um ein Schaltflächenobjekt zu erstellen, wird derselbe Funktionsansatz verwendet. Der Code zum Erstellen einer nutzerdefinierten Schaltflächenfunktion lautet wie folgt.

//+------------------------------------------------------------------+
//|     Function to create button                                    |
//+------------------------------------------------------------------+

bool createButton(string objName, int xD, int yD, int xS, int yS,
                  string txt = "", color clrTxt = clrBlack, int fontSize = 12,
                  color clrBg = clrNONE, color clrBorder = clrNONE,
                  string font = "Arial Rounded MT Bold") {
    // Reset any previous errors
    ResetLastError();

    // Attempt to create the button object
    if (!ObjectCreate(0, objName, OBJ_BUTTON, 0, 0, 0)) {
        // Print an error message if creation fails
        Print(__FUNCTION__, ": failed to create the button! Error code = ", _LastError);
        return (false);
    }

    // Set properties for the button
    ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_XSIZE, xS); // Width of the button
    ObjectSetInteger(0, objName, OBJPROP_YSIZE, yS); // Height of the button
    ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner
    ObjectSetString(0, objName, OBJPROP_TEXT, txt); // Text displayed on the button
    ObjectSetInteger(0, objName, OBJPROP_COLOR, clrTxt); // Text color
    ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, fontSize); // Font size
    ObjectSetString(0, objName, OBJPROP_FONT, font); // Font name
    ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, clrBg); // Background color
    ObjectSetInteger(0, objName, OBJPROP_BORDER_COLOR, clrBorder); // Border color
    ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Transparent background
    ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Button state (not pressed)
    ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable
    ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected

    // Redraw the chart to display the button
    ChartRedraw(0);

    return (true); // Button creation successful
}

Die Unterschiede im Code bestehen darin, dass ein Rechteck-Objekt keinen Text enthalten kann, eine Schaltfläche jedoch einen beschreibenden Text über die Funktionalität der Schaltfläche enthält, falls dies erforderlich ist. Daher berücksichtigen wir bei den Eingabeparametern Texteigenschaften, in unserem Fall den Textwert, die Farbe, die Schriftgröße und den Schriftnamen. Der Rahmentyp für unsere Schaltfläche ist statisch, sodass wir seine Eigenschaften loswerden und nur die Rahmenfarbe behalten. 

Der Objekttyp, den wir erstellen, ist „OBJ_BUTTON“, was bedeutet, dass wir ein grafisches Schaltflächenobjekt erstellen. Die Ankerpunkte werden in Pixel angegeben. Die Rahmeneigenschaft, die wir beibehalten, ist die Rahmenfarbe und der Rest wird durch die Texteingabeeigenschaften ersetzt.

Zur Erstellung der Schaltfläche für das Bearbeitungsfeld wird die gleiche Logik verwendet. 

//+------------------------------------------------------------------+
//|     Function to create edit field                                |
//+------------------------------------------------------------------+

bool createEdit(string objName, int xD, int yD, int xS, int yS,
                string txt = "", color clrTxt = clrBlack, int fontSize = 12,
                color clrBg = clrNONE, color clrBorder = clrNONE,
                string font = "Arial Rounded MT Bold") {
    // Reset any previous errors
    ResetLastError();

    // Attempt to create the edit object
    if (!ObjectCreate(0, objName, OBJ_EDIT, 0, 0, 0)) {
        // Print an error message if creation fails
        Print(__FUNCTION__, ": failed to create the edit! Error code = ", _LastError);
        return (false);
    }

    // Set properties for the edit field
    ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_XSIZE, xS); // Width of the edit field
    ObjectSetInteger(0, objName, OBJPROP_YSIZE, yS); // Height of the edit field
    ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner
    ObjectSetString(0, objName, OBJPROP_TEXT, txt); // Default text in the edit field
    ObjectSetInteger(0, objName, OBJPROP_COLOR, clrTxt); // Text color
    ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, fontSize); // Font size
    ObjectSetString(0, objName, OBJPROP_FONT, font); // Font name
    ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, clrBg); // Background color
    ObjectSetInteger(0, objName, OBJPROP_BORDER_COLOR, clrBorder); // Border color
    ObjectSetInteger(0, objName, OBJPROP_ALIGN, ALIGN_LEFT); // Text alignment (left-aligned)
    ObjectSetInteger(0, objName, OBJPROP_READONLY, false); // Edit field is not read-only
    ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Transparent background
    ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Edit field state (not active)
    ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable
    ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected

    // Redraw the chart to display the edit field
    ChartRedraw(0);

    return (true); // Edit field creation successful
}

Der Hauptunterschied im Code im Vergleich zur Erstellung einer Schaltflächenfunktion ist erstens der Objekttyp. Wir verwenden „OBJ_EDIT“, um zu signalisieren, dass wir eine editierbare Schaltfläche erstellen wollen. Dann fügen wir zu den Feldeigenschaften die Eigenschaft der horizontalen Textausrichtung hinzu, die entweder rechts, links oder mittig sein kann. In unserem Fall entscheiden wir uns für eine horizontale Ausrichtung des Textes nach links. 

    ObjectSetInteger(0, objName, OBJPROP_ALIGN, ALIGN_LEFT); // Text alignment (left-aligned)

Der letzte Unterschied ist die Eigenschaft, die die Möglichkeit bietet, den Text im Objekt zu bearbeiten. Um die Bearbeitung zu ermöglichen, setzen wir die Eigenschaft „OBJPROP_READONLY“ auf den Wert false.

    ObjectSetInteger(0, objName, OBJPROP_READONLY, false); // Edit field is not read-only

Der Rest der Argumente bleibt bestehen. 

Schließlich brauchen wir noch die Funktion des letzten Elements, das die Textbeschriftung ist. Die Kennzeichnung des Textes macht ein Hintergrundobjekt überflüssig und ist daher wesentlich einfacher zu implementieren als die übrigen Funktionen. Wir brauchen nur den Text und konzentrieren uns daher auf die Texteigenschaften. Sein Code lautet wie folgt.

//+------------------------------------------------------------------+
//|     Function to create text label                                |
//+------------------------------------------------------------------+

bool createLabel(string objName, int xD, int yD,
                 string txt, color clrTxt = clrBlack, int fontSize = 12,
                 string font = "Arial Rounded MT Bold") {
    // Reset any previous errors
    ResetLastError();

    // Attempt to create the label object
    if (!ObjectCreate(0, objName, OBJ_LABEL, 0, 0, 0)) {
        // Print an error message if creation fails
        Print(__FUNCTION__, ": failed to create the label! Error code = ", _LastError);
        return (false);
    }

    // Set properties for the label
    ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner
    ObjectSetString(0, objName, OBJPROP_TEXT, txt); // Text displayed on the label
    ObjectSetInteger(0, objName, OBJPROP_COLOR, clrTxt); // Text color
    ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, fontSize); // Font size
    ObjectSetString(0, objName, OBJPROP_FONT, font); // Font name
    ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Transparent background
    ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Label state (not active)
    ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable
    ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected

    // Redraw the chart to display the label
    ChartRedraw(0);

    return (true); // Label creation successful
}

Die wichtigsten Unterschiede in dieser Codestruktur gegenüber der Funktion der Schaltfläche sind die Objektgröße und die Rahmeneigenschaften. In der Funktionssignatur werden sowohl die Objektgrößen als auch die Randeigenschaften entfernt. Wir definieren unseren Objekttyp als „OBJ_LABEL“, um zu signalisieren, dass wir es gemäß seinen angegebenen Koordinaten in das Chartfenster zeichnen. Schließlich werden wir die Parameter Größe und Rahmen entfernen, und das ist alles. So einfach ist das. 

Da wir nun die Funktionen haben, die wir für die Erstellung einer grafischen Nutzeroberfläche benötigen, wollen wir sie für die Erstellung des Panels verwenden. Wir brauchen Namen für die Objekte und um die Interaktion der Objektnamen einfach zu verwalten, ist es viel einfacher, Makros zu definieren. 

#define MAIN_REC "MAIN_REC"

Wir verwenden das #define-Schlüsselwort, um ein Makro mit dem Namen „MAIN_REC“ und dem Wert "MAIN_REC" zu definieren, um unseren Basisnamen für das Hauptrechteck einfach zu speichern, anstatt den Namen bei jeder Erstellung der Ebene erneut eingeben zu müssen, was uns viel Zeit spart und die Gefahr einer falschen Namensgebung verringert. Grundsätzlich werden Makros also zur Textersetzung während der Kompilierung verwendet.

Unser Code wird sich hauptsächlich auf den Initialisierungsabschnitt des Experten stützen, da wir das Panel in der Initialisierungsinstanz erstellen wollen. OnInit wird also den größten Teil der Codestruktur enthalten. 

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+

int OnInit(){

   ...
   
   return(INIT_SUCCEEDED);
}

Die Funktion OnInit ist eine Ereignisbehandlung, die bei der Initialisierungsinstanz des Experten aufgerufen wird, um gegebenenfalls notwendige Initialisierungen vorzunehmen. 

Anschließend rufen wir die Funktion auf, um eine rechteckige Kennzeichnung zu erstellen, indem wir ihren Namen eingeben und ihre Parameter angeben.

   createRecLabel(MAIN_REC,10,30,250,400,clrWhite,1,clrBlack);

Hier lautet der Name des Rechtecks „MAIN_REC“, wie in der Makrodefinition angegeben. Unser Abstand entlang der x-Achse, der Zeit- und Datumsskala, von der linken oberen Ecke des Chartfensters beträgt 10 Pixel, und der Abstand entlang der y-Achse, der Preisskala, beträgt 30 Pixel. Die Breite beträgt 250 Pixel und die Höhe 400 Pixel. Wir wählen eine weiße Hintergrundfarbe, eine Rahmenbreite von 1 und eine schwarze Rahmenfarbe. Um die Pixel annähernd zu erfassen, können Sie das Chart auf 0 verkleinern, und die Anzahl der Balken zwischen zwei Fadenkreuzkoordinaten ist gleich der Anzahl der Pixel auf der horizontalen Skala. Ein Beispiel, das ist gemeint:

Fadenkreuz

Die anderen Parameter wurden weggelassen, was bedeutet, dass die Standardwerte automatisch angewendet werden, d. h. der Rahmentyp ist flach und der Linienstil ist eine durchgehende, durchgezogene Linie. Nach der Zusammenstellung ergibt sich das folgende Bild.

PANEEL1

Selbst wenn wir alle Parameter mit den Standardwerten wie unten angeben würden, wären die Ergebnisse immer die gleichen.

   createRecLabel(MAIN_REC,10,30,250,400,clrWhite,1,clrBlack,BORDER_FLAT,STYLE_SOLID);

Um einen Unterrahmen zu erstellen, deklarieren wir wieder explizit ein Makro für denselben.

#define MAIN_SUB_REC "MAIN_SUB_REC"

Dann rufen wir die gleiche Funktion auf, um den Unterrahmen zu erstellen. Wir wollen, dass unser Rahmen innerhalb des Rahmens des Basisrahmens des Panels liegt und müssen daher eine etwas andere Farbe verwenden. Um dies zu erreichen, haben wir eine hellblaue Farbe und einen Rand von 5 Pixeln verwendet.

   createRecLabel(MAIN_SUB_REC,15,35,240,390,clrLightBlue,1,clrNONE);

Da wir einen Rand von 5 Pixeln wollen, schieben wir von links um 5 Pixel und von oben um 5 Pixel. Der Abstand auf der x-Achse beträgt also die ursprünglichen 10 Pixel plus eine Marge von 5, was 15 Pixel ergibt. Das Gleiche gilt für die Skala der y-Achse. Das bedeutet, dass auch die Größe um 5 Pixel reduziert werden muss, aber Moment mal, wir brauchen auch einen Rand von 5 Pixeln rechts vom Panel. Daher ist eine Verkleinerung um 5 Pixel auf jeder Seite für zwei Seiten erforderlich. Die Gesamtzahl der benötigten Pixel ist also 5 multipliziert mit 2, was 10 Pixel ergibt. Eine Verringerung der Größe des Unterrechtecks um 10 Pixel ergibt 250 - 10 = 240 Pixel als Breite und 400 - 10 = 390 Pixel als Höhe des Unterrechtecks. Hier sind die Ergebnisse, die wir erhalten.

PANEEL2

Die hellblaue Farbe ist nicht so ansprechend für die Augen, also wählen wir eine dunklere Farbe. Um mehr Kontrolle über die verwendete Farbe zu erhalten, stellen wir die Hintergrundfarbe in Literalen dar. Dies geschieht im Format "C'000,000,000'", wobei die dreifachen Nullen eine beliebige Zahl zwischen 0 und 255 sein können. Das verwendete Format ist RGB (Rot, Grün, Blau). Die drei Werte stehen für die Rot-, Grün- bzw. Blaukomponente auf einer Skala von 0 bis 255. Die Zahl 245.245.245 entspricht also einem fast weißen Farbton. 

   createRecLabel(MAIN_SUB_REC,15,35,240,390,C'245,245,245',1,clrNONE);

Wir setzen die Rahmenfarbe auf „keine“, um eine ansprechendere Farbmischung zu erzielen. Es wird immer empfohlen, das Programm zu kompilieren und das Ergebnis jedes Mal zu überprüfen, wenn Sie ein neues GUI-Element hinzufügen. Nachfolgend sind die Ergebnisse aufgeführt.

PANEEL3

Um vertikale und horizontale Begrenzungslinien zu erstellen, definieren wir zwei weitere Makros.

#define MAIN_LINE_UP "MAIN_LINE_UP"
#define MAIN_LINE_DN "MAIN_LINE_DN"

Es wird die gleiche Struktur verwendet, aber dieses Mal wird ein erhöhter Rand verwendet. Dadurch wird die Verwendung der Rahmenfarbe ignoriert und es entsteht eine Illusion der Begrenzung.

   createRecLabel(MAIN_LINE_UP,15,35,240,1,C'245,245,245',1,clrNONE,BORDER_RAISED);
   createRecLabel(MAIN_LINE_DN,15,35-1,1,390+1,C'245,245,245',1,clrNONE,BORDER_RAISED);

Das ist das Ergebnis.

PANEEL4

Bis zu diesem Punkt ist die Einrichtung unserer Rahmen, Ränder und Grenzen für unser GUI-Panel abgeschlossen. Anschließend fügen wir die anderen Hilfsmittel des Panels hinzu, wie z. B. Schaltflächen, Titel, Bearbeitungsfelder und Beschriftungen sowie deren Eigenschaften und Effekte. 

Lassen Sie uns zunächst dem Panel einen Titel geben. 

#define LABEL_NAME "LABEL_NAME"
...
   createLabel(LABEL_NAME,25,35,"DashBoard v1.0",clrBlue,14,"Cooper Black");

Zunächst definieren wir ein Makro für den Titelnamen und rufen die Funktion auf, die für die Erstellung der Etiketten zuständig ist, indem wir ihren Namen eingeben. Die Abstände zur x-Achse und zur y-Achse geben wir mit 25 bzw. 35 Pixeln an. Die Texteingabe, die wir wählen, ist „DashBoard v1.0“, was den Paneltyp und die Version als erstes angibt. Gleichzeitig geben wir als Textfarbe blau mit einer Schriftgröße von 14 und als Schriftart „Cooper Black“ an. Bei der Angabe der Schriftart wird nicht zwischen Groß- und Kleinschreibung unterschieden. Groß- oder Kleinschreibung oder eine Mischung aus beidem hat keine Auswirkungen. Es könnte auch „Cooper Black“ oder „COOPER BLACK“ lauten. Wichtig ist nur, dass Sie den richtigen Schriftnamen angeben. Öffnen Sie die Kompilierung, erhalten wir die folgenden Ergebnisse.

PANEL5 TITEL

Sie haben bemerkt, dass sich die Schriftart ändern kann. Wir wollen der Musik Zucker geben und sehen, wie sie sich entwickelt. Einige Schriftarten enthalten Icons und Emojis. Jetzt akzeptiert und integriert MQL5 einige von ihnen. Beispiele für Schriftarten sind „Webdings“, „Wingdings“, „Wingdings 2“ und „Wingdings 3“. Es gibt noch viele weitere, aber wir haben uns für die oben genannten entschieden. Das bedeutet, dass wir das Panel mit diesen Symbolen und Emoji-Schriftarten aufpeppen können. Diese sind im Folgenden aufgeführt.

FONTS

Wir fügen drei Symbole vor dem Namen des Panels hinzu: ein Herz, ein Werkzeug und ein Krankenwagen-Symbol. Natürlich können Sie diese nach Ihren Wünschen auswählen. Das erfordert wiederum die Definition von drei Makros, die unsere Symbolnamen aufnehmen und später bei der Erstellung der Symbole verwenden. Hier ist die Logik.

#define ICON_HEART "ICON_HEART"
#define ICON_TOOL "ICON_TOOL"
#define ICON_CAR "ICON_CAR"

...
   createLabel(ICON_HEART,190,35,"Y",clrRed,15,"Webdings");

Es wird die gleiche Funktion verwendet, mit den Achsenabständen, der Farbe und der Schriftgröße. Sie können jedoch feststellen, dass der Name der Schriftart nun in „Webdings“ geändert wurde und der Textwert in Großbuchstaben „Y“ lautet. Das bedeutet nicht, dass wir „Y“ als Ausgabe anzeigen werden. Wir zeigen das entsprechende Symbol an, das dem jeweiligen Zeichen entspricht. Was die Schriftart anbelangt, so ist das Symbol unter dem Zeichen wie unten, das Herzsymbol.

HERZ-SYMBOL

Der Wert des Textes hängt von der Groß- und Kleinschreibung ab, denn wie Sie sehen können, unterscheidet sich das Symbol unter dem Kleinbuchstaben „y“ von dem des Großbuchstaben „Y“. Nach der Zusammenstellung ergibt sich folgendes Bild. 

PANEEL6

Die beiden anderen Symbole können nun auf die gleiche Weise wie das vorherige Symbol hinzugefügt werden.

   createLabel(ICON_TOOL,210,35,"@",clrBlue,15,"Webdings");
   createLabel(ICON_CAR,230,35,"h",clrBlack,15,"Webdings");

Dieselbe Implementierung wird dann verwendet, um dem Chart die anderen Hilfsobjekte hinzuzufügen. Die Logik ist wie folgt.

#define LINE1 "LINE1"
#define BTN_CLOSE "BTN_CLOSE"
#define BTN_MARKET "BTN_MARKET"
#define BTN_PROFIT "BTN_PROFIT"
#define BTN_LOSS "BTN_LOSS"
#define BTN_PENDING "BTN_PENDING"
#define LINE2 "LINE2"

...

   createRecLabel(LINE1,15+10,60,240-10,1,C'245,245,245',1,clrNONE,BORDER_RAISED);
   createLabel(BTN_CLOSE,25,65,"Close",clrBlack,13,"Impact");
   createLabel(BTN_MARKET,70,65,"Market",clrDarkRed,13,"Impact");
   createLabel(BTN_PROFIT,125,65,"Profit",clrGreen,13,"Impact");
   createLabel(BTN_LOSS,170,65,"Loss",clrRed,13,"Impact");
   createLabel(BTN_PENDING,205,65,"Pend'n",clrDarkGray,13,"Impact");
   createRecLabel(LINE2,15+10,87,240-10,1,C'245,245,245',1,clrNONE,BORDER_RAISED);
  

Wir definieren die Namen der Objektmakros und rufen die entsprechenden nutzerdefinierten Funktionen auf, um die Objekte zu erstellen. Es wird eine Instanz von zwei vertikalen Begrenzungslinien erstellt, die die Schaltflächen des Beschriftungsprogramms einschließen. Die Bezeichnungen lauten Close, Market, Profit, Loss und Pending, angepasst an „Pend'n“, um den Wortlaut innerhalb der Rahmengrenzen unterzubringen. Diese dienen dazu, alle Markt- und Pending-Aufträge zu schließen, nur die Markt-Aufträge zu schließen, nur die Positionen mit Gewinn zu schließen, nur die Positionen mit Verlust zu schließen bzw. Pending-Aufträge zu löschen. Beim Kompilieren erhalten wir dieses Ergebnis.

PANEEL7

Bis zu diesem Punkt haben wir den Kopfbereich unseres Panels erfolgreich erstellt. Wir fahren nun fort, die Schaltflächen-Dienstprogramme zu erstellen. Konzentrieren wir uns zunächst auf die Schaltfläche für das Handelsvolumen. Unsere Schaltfläche wird eine Beschriftung und ein Dropdown-Feld haben.

#define BTN_LOTS "BTN_LOTS"
#define LABEL_LOTS "LABEL_LOTS"
#define ICON_DROP_DN1 "ICON_DROP_DN1"

Die Definition der Makros ist abgeschlossen. Anschließend erstellen wir eine Schaltfläche, indem wir die Schaltfläche-Funktion aufrufen.

   createButton(BTN_LOTS,25,95,130,25,"",clrBlack,12,C'210,210,210',C'150,150,150');

Auch hier geben wir die x- und y-Abstände der Schaltflächen mit einer Größe von 130 Pixeln in der Breite bzw. 25 Pixeln in der Höhe an. Für den Text konnten wir einen Wert angeben, haben uns aber dagegen entschieden, da wir die Kontrolle über die Positionierung des Textes haben wollten. Schließlich werden buchstäbliche Farbdarstellungen verwendet, um sowohl den Hintergrund als auch den Rand der Schaltfläche festzulegen. Da wir uns entschieden haben, die Standardbeschriftung der Schaltflächen wegzulassen, haben wir eine neue Textbeschriftung erstellt, die mit Hilfe der folgenden Funktion in der Nähe der Schaltflächen erscheinen soll.

   createLabel(LABEL_LOTS,25+10,95+5,"LotSize",clrBlack,9);

Die Funktion ist Ihnen nun vertraut und Sie kennen die Parameter, die übergeben werden. Für das Dropdown-Symbol wird eine Schriftart verwendet, die das Symbol darstellt.

   createLabel(ICON_DROP_DN1,130,95+5,CharToString(240),C'070,070,070',20,"Wingdings 3");

Sie können feststellen, dass wir beim Text-Argument ein Zeichen in eine Zeichenkette umwandeln, was eine andere Möglichkeit ist, den entsprechenden Zeichencode anstelle der Zeichenkette zu liefern. Dies ist hilfreich, wenn Sie den Symbolcode bereits kennen. Zur Erstellung der Schaltfläche für das Bearbeitungsfeld wird das gleiche Verfahren angewandt. 

#define EDIT_LOTS "EDIT_LOTS"
#define BTN_P1 "BTN_P1"
#define BTN_M1 "BTN_M1"

...

   createEdit(EDIT_LOTS,165,95,60,25,"0.01",clrBlack,14,clrWhite,C'100,100,100',"Callibri");
   createButton(BTN_P1,225,95,20,12,"5",clrBlack,12,clrLightGray,C'100,100,100',"Webdings");
   createButton(BTN_M1,225,95+12,20,12,"6",clrBlack,12,clrLightGray,C'100,100,100',"Webdings");


Wir definieren die Makronamen wie üblich und rufen Funktionen auf. Für die Erstellung der Schaltfläche „Bearbeiten“ wird die Größe von 60 und 25 Pixel als Breite bzw. Höhe verwendet. Der Standardtext ist auf 0,01 mit einer schwarzen Textfarbe, einer Schriftgröße von 14 und einer Schriftart „Callibri“ eingestellt. Der Schaltflächenhintergrund ist auf Weiß mit einem fast dunklen Farbton als Rahmenfarbe eingestellt. Für die Erhöhung und Verringerung des Handelsvolumens verwenden wir die Schriftart „Webdings“ und die Textwerte „5“ bzw. „6“. Hier ist der Meilenstein, den wir bei der Zusammenstellung erreicht haben.

PANEEL8

Dies ist ein guter Fortschritt. Um die anderen Stop-Loss- und Take-Profit-Schaltflächen zu erstellen, gilt dieselbe Logik wie im folgenden Code. 

#define BTN_SL "BTN_SL"
#define LABEL_SL "LABEL_SL"
#define ICON_DROP_DN2 "ICON_DROP_DN2"
#define EDIT_SL "EDIT_SL"
#define BTN_P2 "BTN_P2"
#define BTN_M2 "BTN_M2"

#define BTN_TP "BTN_TP"
#define LABEL_TP "LABEL_TP"
#define ICON_DROP_DN3 "ICON_DROP_DN3"
#define EDIT_TP "EDIT_TP"
#define BTN_P3 "BTN_P3"
#define BTN_M3 "BTN_M3"

...

   createButton(BTN_SL,25,95+30,130,25,"",clrBlack,12,C'210,210,210',C'150,150,150');
   createLabel(LABEL_SL,35,95+30,"SL Pips",clrBlack,14);
   createLabel(ICON_DROP_DN2,130,100+30,CharToString(240),C'070,070,070',20,"Wingdings 3");
   createEdit(EDIT_SL,165,95+30,60,25,"100.0",clrBlack,13,clrWhite,C'100,100,100',"Callibri");
   createButton(BTN_P2,225,95+30,20,12,"5",clrBlack,12,clrLightGray,C'100,100,100',"Webdings");
   createButton(BTN_M2,225,107+30,20,12,"6",clrBlack,12,clrLightGray,C'100,100,100',"Webdings");

   createButton(BTN_TP,25,95+30+30,130,25,"",clrBlack,12,C'210,210,210',C'150,150,150');
   createLabel(LABEL_TP,35,95+30+30,"TP Pips",clrBlack,14);
   createLabel(ICON_DROP_DN3,130,100+30+30,CharToString(240),C'070,070,070',20,"Wingdings 3");
   createEdit(EDIT_TP,165,95+30+30,60,25,"100.0",clrBlack,13,clrWhite,C'100,100,100',"Callibri");
   createButton(BTN_P3,225,95+30+30,20,12,"5",clrBlack,12,clrLightGray,C'100,100,100',"Webdings");
   createButton(BTN_M3,225,107+30+30,20,12,"6",clrBlack,12,clrLightGray,C'100,100,100',"Webdings");
   

Utility-Makros werden definiert und die entsprechenden Funktionen zu ihrer Erstellung aufgerufen. Dieser Code unterscheidet sich in seiner Logik nicht von dem ursprünglichen Code, den wir zur Erstellung der Schaltflächen für das Handelsvolumen verwendet haben. Wenn Sie kompilieren, sollten Sie dieses Ergebnis erhalten.

PANEEL 9

#define BTN_BUY "BTN_BUY"
#define LABEL_BUY "LABEL_BUY"
#define LABEL_BUY_PRICE "LABEL_BUY_PRICE"
#define BTN_OVERLAY "BTN_OVERLAY"
#define BTN_SPREAD "BTN_SPREAD"

#define BTN_SELL "BTN_SELL"
#define LABEL_SELL "LABEL_SELL"
#define LABEL_SELL_PRICE "LABEL_SELL_PRICE"

#define BTN_CONTACT "BTN_CONTACT"

...

   
   createRecLabel(BTN_SELL,25,335,105,60,clrRed,1,clrNONE);
   createLabel(LABEL_SELL,35,335,"Sell",clrWhite,15,"ARIAL black");
   createLabel(LABEL_SELL_PRICE,35,335+30,DoubleToString(Bid(),_Digits),clrWhite,13,"ARIAL black");
   createRecLabel(BTN_BUY,140,335,105,60,clrGreen,1,clrNONE);
   createLabel(LABEL_BUY,150+35,335,"Buy",clrWhite,15,"ARIAL black");
   createLabel(LABEL_BUY_PRICE,150,335+30,DoubleToString(Ask(),_Digits),clrWhite,13,"ARIAL black");
   createRecLabel(BTN_OVERLAY,90,335,90,25,C'245,245,245',0,clrNONE);
   createButton(BTN_SPREAD,95,335,80,20,(string)Spread(),clrBlack,13,clrWhite,clrBlack);
   createButton(BTN_CONTACT,25,335+62,230-10,25,"https://t.me/Forex_Algo_Trader",clrBlack,10,clrNONE,clrBlack);
   

Um die Schaltflächen zum Kaufen, Verkaufen, Überlagern, eine Schaltfläche für Zusatzinformationen und eine Schaltfläche für den Spread zu erstellen, wird der obige Code implementiert. Das Einzige, was sich zusätzlich ändert, ist der Text für die Verkaufs- und Ankaufspreise sowie der Spread-Wert. Zusätzliche nutzerdefinierte Funktionen, Bid, Ask und Spread, werden aufgerufen, um die Werte zu füllen. Die Bid- und Ask-Funktionen geben einen Wert vom Datentyp „double“ zurück. Um den Double-Wert in eine Zeichenkette umzuwandeln, wird die eingebaute Funktion „DoubleToString“ aufgerufen. Für die Spanne wird der Integer-Wert direkt in die Zeichenkette eingegeben. Die nutzerdefinierten Funktionen sind wie folgt.

double Ask(){return(NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits));}
double Bid(){return(NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits));}
int Spread(){return((int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD));}

Die Funktionen geben die jeweiligen Datentypen der Symbolinformationen zurück. Nach der Kompilierung erhalten wir das folgende Ergebnis.

PANEEL10

Nun erstellen wir einige zusätzliche Schaltflächen, die wir zur Veranschaulichung verwenden, wie eine scharfkantige Schaltfläche erstellt werden kann, und ein Duplikat davon, das wir zur Automatisierung des Hover-Effekts verwenden werden.

#define BTN_SHARP "BTN_SHARP"
#define LABEL_SHARP "LABEL_SHARP"
#define BTN_HOVER "BTN_HOVER"
#define LABEL_HOVER "LABEL_HOVER"

...

   createRecLabel(BTN_SHARP,25,190,220,35,C'220,220,220',2,C'100,100,100');
   createLabel(LABEL_SHARP,25+20,190+5,"Sharp Edged Button",clrBlack,12,"ARIAL black");
   //createRecLabel(BTN_HOVER,25,230,220,35,C'220,220,220',3,C'050,050,255');
   createRecLabel(BTN_HOVER,25,230,220,35,C'220,220,220',3,C'100,100,100');
   createLabel(LABEL_HOVER,25+50,230+5,"Hover Effect",clrBlack,12,"ARIAL black");

Nachstehend finden Sie den Meilenstein.

PANEEL11

Es gibt etwas zusätzlichen Platz, der für andere Dienstprogramme verwendet werden kann, aber wir wollen ihn mit einigen Emoji- und Symbolzeichen füllen.

#define LABEL_EXTRA1 "LABEL_EXTRA1"
#define LABEL_EXTRA2 "LABEL_EXTRA2"
#define LABEL_EXTRA3 "LABEL_EXTRA3"
#define LABEL_EXTRA4 "LABEL_EXTRA4"

...

   createLabel(LABEL_EXTRA1,25,290,"_",clrBlack,25,"WEBDINGS");
   createLabel(LABEL_EXTRA2,25+40,290,"J",clrBlack,25,"WINGDINGS");
   createLabel(LABEL_EXTRA3,25+40+40,290,"{",clrBlack,25,"WINGDINGS 2");
   createLabel(LABEL_EXTRA4,25+40+40+40,290,"G",clrBlack,25,"WINGDINGS 3");

Sobald die Schaltfläche für das Handelsvolumen angeklickt wird, möchten wir einige Instanzen für die Erstellung einer Dropdown-Liste haben, aus der wir verschiedene Optionen auswählen können. Wir brauchen 3 Optionen sowie ein Symbol, um die Liste an eine andere Stelle als den ursprünglichen Erstellungspunkt zu ziehen. Es gilt die gleiche Logik.

#define BTN_DROP_DN "BTN_DROP_DN"
#define LABEL_OPT1 "LABEL_OPT1"
#define LABEL_OPT2 "LABEL_OPT2"
#define LABEL_OPT3 "LABEL_OPT3"
#define ICON_DRAG "ICON_DRAG"

...

void createDropDown(){
   createRecLabel(BTN_DROP_DN,25,95+25,130,70,clrWhite,2,clrBlack);
   createLabel(LABEL_OPT1,25+10,95+25,"LotSize",clrBlack,12,"stencil");
   createLabel(LABEL_OPT2,25+10,95+25+20,"Risk Percent %",clrBlack,12,"calibri Italic");
   createLabel(LABEL_OPT3,25+10,95+25+20+20,"Money Balance",clrBlack,12,"Arial bold");
   createLabel(ICON_DRAG,25+10+95,95+25,"d",clrRoyalBlue,15,"webdings");
}

Hier erstellen wir die Schaltflächen und Beschriftungen in einer nutzerdefinierten Funktion, sodass wir die Funktion aufrufen, sobald das Handelsvolumen angeklickt wird. Um jedoch die Positionen der Hilfsmittel anzuzeigen, rufen wir die Funktion auf, werden aber später die aufgerufene Funktion auskommentieren.

   createDropDown();

Der letzte Meilenstein ist wie folgt.

PANEL12. ABSCHLUSS TEIL1

Schließlich müssen wir die erstellten Objekte zerstören und löschen, sobald der Expert Advisor aus dem Chart entfernt wurde. Um dies zu erreichen, wird eine weitere Funktion zum Löschen der erstellten Objekte erstellt.

void destroyPanel(){
   ObjectDelete(0,MAIN_REC);
   ObjectDelete(0,MAIN_SUB_REC);
   ObjectDelete(0,MAIN_LINE_UP);
   
   //... other objects
   
   ChartRedraw(0);
}

Eine ungültige nutzerdefinierte Funktion bedeutet, dass sie nichts zurückgibt. Die eingebaute Funktion „ObjectDelete“ wird verwendet, um die entsprechenden Objekte wie übergeben zu löschen. Sie benötigt zwei Argumente, die Chart-ID, 0 für das aktuelle Chart, und den Namen des zu löschenden Objekts. Diese Funktion wird während der Deinitialisierungsfunktion des Experten aufgerufen.

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){
//---
   destroyPanel();
}

Im Folgenden finden Sie den vollständigen Quellcode, der für die Erstellung des GUI-Panels verantwortlich ist, wie in MQL5 für MetaTrader 5 (MT5). dargestellt.

//+------------------------------------------------------------------+
//|                                             DASHBOARD PART 1.mq5 |
//|                                  Copyright 2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"

//--- DEFINE MACRO PROPERTIES

#define MAIN_REC "MAIN_REC"
#define MAIN_SUB_REC "MAIN_SUB_REC"
#define MAIN_LINE_UP "MAIN_LINE_UP"
#define MAIN_LINE_DN "MAIN_LINE_DN"
#define LABEL_NAME "LABEL_NAME"
#define ICON_HEART "ICON_HEART"
#define ICON_TOOL "ICON_TOOL"
#define ICON_CAR "ICON_CAR"
#define LINE1 "LINE1"
#define BTN_CLOSE "BTN_CLOSE"
#define BTN_MARKET "BTN_MARKET"
#define BTN_PROFIT "BTN_PROFIT"
#define BTN_LOSS "BTN_LOSS"
#define BTN_PENDING "BTN_PENDING"
#define LINE2 "LINE2"

#define BTN_LOTS "BTN_LOTS"
#define LABEL_LOTS "LABEL_LOTS"
#define ICON_DROP_DN1 "ICON_DROP_DN1"
#define EDIT_LOTS "EDIT_LOTS"
#define BTN_P1 "BTN_P1"
#define BTN_M1 "BTN_M1"

#define BTN_SL "BTN_SL"
#define LABEL_SL "LABEL_SL"
#define ICON_DROP_DN2 "ICON_DROP_DN2"
#define EDIT_SL "EDIT_SL"
#define BTN_P2 "BTN_P2"
#define BTN_M2 "BTN_M2"

#define BTN_TP "BTN_TP"
#define LABEL_TP "LABEL_TP"
#define ICON_DROP_DN3 "ICON_DROP_DN3"
#define EDIT_TP "EDIT_TP"
#define BTN_P3 "BTN_P3"
#define BTN_M3 "BTN_M3"

#define BTN_BUY "BTN_BUY"
#define LABEL_BUY "LABEL_BUY"
#define LABEL_BUY_PRICE "LABEL_BUY_PRICE"
#define BTN_OVERLAY "BTN_OVERLAY"
#define BTN_SPREAD "BTN_SPREAD"

#define BTN_SELL "BTN_SELL"
#define LABEL_SELL "LABEL_SELL"
#define LABEL_SELL_PRICE "LABEL_SELL_PRICE"

#define BTN_CONTACT "BTN_CONTACT"

#define BTN_SHARP "BTN_SHARP"
#define LABEL_SHARP "LABEL_SHARP"
#define BTN_HOVER "BTN_HOVER"
#define LABEL_HOVER "LABEL_HOVER"

#define LABEL_EXTRA1 "LABEL_EXTRA1"
#define LABEL_EXTRA2 "LABEL_EXTRA2"
#define LABEL_EXTRA3 "LABEL_EXTRA3"
#define LABEL_EXTRA4 "LABEL_EXTRA4"

#define BTN_DROP_DN "BTN_DROP_DN"
#define LABEL_OPT1 "LABEL_OPT1"
#define LABEL_OPT2 "LABEL_OPT2"
#define LABEL_OPT3 "LABEL_OPT3"
#define ICON_DRAG "ICON_DRAG"

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+

int OnInit(){

   createRecLabel(MAIN_REC,10,30,250,400,clrWhite,1,clrBlack);
   createRecLabel(MAIN_SUB_REC,15,35,240,390,C'245,245,245',1,clrNONE);
   createRecLabel(MAIN_LINE_UP,15,35,240,1,C'245,245,245',1,clrNONE,BORDER_RAISED);
   createRecLabel(MAIN_LINE_DN,15,35-1,1,390+1,C'245,245,245',1,clrNONE,BORDER_RAISED);

   createLabel(LABEL_NAME,25,35,"DashBoard v1.0",clrBlue,14,"Cooper Black");
   
   createLabel(ICON_HEART,190,35,"Y",clrRed,15,"Webdings");
   createLabel(ICON_TOOL,210,35,"@",clrBlue,15,"Webdings");
   createLabel(ICON_CAR,230,35,"h",clrBlack,15,"Webdings");
   createRecLabel(LINE1,15+10,60,240-10,1,C'245,245,245',1,clrNONE,BORDER_RAISED);
   createLabel(BTN_CLOSE,25,65,"Close",clrBlack,13,"Impact");
   createLabel(BTN_MARKET,70,65,"Market",clrDarkRed,13,"Impact");
   createLabel(BTN_PROFIT,125,65,"Profit",clrGreen,13,"Impact");
   createLabel(BTN_LOSS,170,65,"Loss",clrRed,13,"Impact");
   createLabel(BTN_PENDING,205,65,"Pend'n",clrDarkGray,13,"Impact");
   createRecLabel(LINE2,15+10,87,240-10,1,C'245,245,245',1,clrNONE,BORDER_RAISED);
   
   createButton(BTN_LOTS,25,95,130,25,"",clrBlack,12,C'210,210,210',C'150,150,150');
   createLabel(LABEL_LOTS,25+10,95+5,"LotSize",clrBlack,9);
   //createLabel(ICON_DROP_DN1,150,75,CharToString(100),clrBlack,12,"Wingdings");
   createLabel(ICON_DROP_DN1,130,95+5,CharToString(240),C'070,070,070',20,"Wingdings 3");
   createEdit(EDIT_LOTS,165,95,60,25,"0.01",clrBlack,14,clrWhite,C'100,100,100',"Callibri");
   createButton(BTN_P1,225,95,20,12,"5",clrBlack,12,clrLightGray,C'100,100,100',"Webdings");
   createButton(BTN_M1,225,95+12,20,12,"6",clrBlack,12,clrLightGray,C'100,100,100',"Webdings");

   createButton(BTN_SL,25,95+30,130,25,"",clrBlack,12,C'210,210,210',C'150,150,150');
   createLabel(LABEL_SL,35,95+30,"SL Pips",clrBlack,14);
   createLabel(ICON_DROP_DN2,130,100+30,CharToString(240),C'070,070,070',20,"Wingdings 3");
   createEdit(EDIT_SL,165,95+30,60,25,"100.0",clrBlack,13,clrWhite,C'100,100,100',"Callibri");
   createButton(BTN_P2,225,95+30,20,12,"5",clrBlack,12,clrLightGray,C'100,100,100',"Webdings");
   createButton(BTN_M2,225,107+30,20,12,"6",clrBlack,12,clrLightGray,C'100,100,100',"Webdings");

   createButton(BTN_TP,25,95+30+30,130,25,"",clrBlack,12,C'210,210,210',C'150,150,150');
   createLabel(LABEL_TP,35,95+30+30,"TP Pips",clrBlack,14);
   createLabel(ICON_DROP_DN3,130,100+30+30,CharToString(240),C'070,070,070',20,"Wingdings 3");
   createEdit(EDIT_TP,165,95+30+30,60,25,"100.0",clrBlack,13,clrWhite,C'100,100,100',"Callibri");
   createButton(BTN_P3,225,95+30+30,20,12,"5",clrBlack,12,clrLightGray,C'100,100,100',"Webdings");
   createButton(BTN_M3,225,107+30+30,20,12,"6",clrBlack,12,clrLightGray,C'100,100,100',"Webdings");
   
   createRecLabel(BTN_SELL,25,335,105,60,clrRed,1,clrNONE);
   createLabel(LABEL_SELL,35,335,"Sell",clrWhite,15,"ARIAL black");
   createLabel(LABEL_SELL_PRICE,35,335+30,DoubleToString(Bid(),_Digits),clrWhite,13,"ARIAL black");
   createRecLabel(BTN_BUY,140,335,105,60,clrGreen,1,clrNONE);
   createLabel(LABEL_BUY,150+35,335,"Buy",clrWhite,15,"ARIAL black");
   createLabel(LABEL_BUY_PRICE,150,335+30,DoubleToString(Ask(),_Digits),clrWhite,13,"ARIAL black");
   createRecLabel(BTN_OVERLAY,90,335,90,25,C'245,245,245',0,clrNONE);
   createButton(BTN_SPREAD,95,335,80,20,(string)Spread(),clrBlack,13,clrWhite,clrBlack);
   createButton(BTN_CONTACT,25,335+62,230-10,25,"https://t.me/Forex_Algo_Trader",clrBlack,10,clrNONE,clrBlack);
   
   createRecLabel(BTN_SHARP,25,190,220,35,C'220,220,220',2,C'100,100,100');
   createLabel(LABEL_SHARP,25+20,190+5,"Sharp Edged Button",clrBlack,12,"ARIAL black");
   //createRecLabel(BTN_HOVER,25,230,220,35,C'220,220,220',3,C'050,050,255');
   createRecLabel(BTN_HOVER,25,230,220,35,C'220,220,220',3,C'100,100,100');
   createLabel(LABEL_HOVER,25+50,230+5,"Hover Effect",clrBlack,12,"ARIAL black");

   createLabel(LABEL_EXTRA1,25,290,"_",clrBlack,25,"WEBDINGS");
   createLabel(LABEL_EXTRA2,25+40,290,"J",clrBlack,25,"WINGDINGS");
   createLabel(LABEL_EXTRA3,25+40+40,290,"{",clrBlack,25,"WINGDINGS 2");
   createLabel(LABEL_EXTRA4,25+40+40+40,290,"G",clrBlack,25,"WINGDINGS 3");
   
   // createDropDown();
   
   return(INIT_SUCCEEDED);
}

double Ask(){return(NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits));}
double Bid(){return(NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits));}
int Spread(){return((int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD));}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){
//---
   destroyPanel();
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(){

}
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//|     Function to create rectangle label                           |
//+------------------------------------------------------------------+

bool createRecLabel(string objName, int xD, int yD, int xS, int yS,
                    color clrBg, int widthBorder, color clrBorder = clrNONE,
                    ENUM_BORDER_TYPE borderType = BORDER_FLAT, ENUM_LINE_STYLE borderStyle = STYLE_SOLID) {
    ResetLastError(); // Reset any previous error codes
    
    // Create a rectangle label object
    if (!ObjectCreate(0, objName, OBJ_RECTANGLE_LABEL, 0, 0, 0)) {
        Print(__FUNCTION__, ": failed to create rec label! Error code = ", _LastError);
        return (false); // Return false if object creation fails
    }
    
    // Set properties for the rectangle label
    ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_XSIZE, xS); // Width of the rectangle
    ObjectSetInteger(0, objName, OBJPROP_YSIZE, yS); // Height of the rectangle
    ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner
    ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, clrBg); // Rectangle background color
    ObjectSetInteger(0, objName, OBJPROP_BORDER_TYPE, borderType); // Border type
    ObjectSetInteger(0, objName, OBJPROP_STYLE, borderStyle); // Border style (only if borderType is flat)
    ObjectSetInteger(0, objName, OBJPROP_WIDTH, widthBorder); // Border width (only if borderType is flat)
    ObjectSetInteger(0, objName, OBJPROP_COLOR, clrBorder); // Border color (only if borderType is flat)
    ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Not a background object
    ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Not selectable
    ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable
    ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected
    
    ChartRedraw(0); // Redraw the chart
    
    return (true); // Return true if object creation and property settings are successful
}

//+------------------------------------------------------------------+
//|     Function to create button                                    |
//+------------------------------------------------------------------+

bool createButton(string objName, int xD, int yD, int xS, int yS,
                  string txt = "", color clrTxt = clrBlack, int fontSize = 12,
                  color clrBg = clrNONE, color clrBorder = clrNONE,
                  string font = "Arial Rounded MT Bold") {
    // Reset any previous errors
    ResetLastError();

    // Attempt to create the button object
    if (!ObjectCreate(0, objName, OBJ_BUTTON, 0, 0, 0)) {
        // Print an error message if creation fails
        Print(__FUNCTION__, ": failed to create the button! Error code = ", _LastError);
        return (false);
    }

    // Set properties for the button
    ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_XSIZE, xS); // Width of the button
    ObjectSetInteger(0, objName, OBJPROP_YSIZE, yS); // Height of the button
    ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner
    ObjectSetString(0, objName, OBJPROP_TEXT, txt); // Text displayed on the button
    ObjectSetInteger(0, objName, OBJPROP_COLOR, clrTxt); // Text color
    ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, fontSize); // Font size
    ObjectSetString(0, objName, OBJPROP_FONT, font); // Font name
    ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, clrBg); // Background color
    ObjectSetInteger(0, objName, OBJPROP_BORDER_COLOR, clrBorder); // Border color
    ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Transparent background
    ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Button state (not pressed)
    ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable
    ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected

    // Redraw the chart to display the button
    ChartRedraw(0);

    return (true); // Button creation successful
}

//+------------------------------------------------------------------+
//|     Function to create edit field                                |
//+------------------------------------------------------------------+

bool createEdit(string objName, int xD, int yD, int xS, int yS,
                string txt = "", color clrTxt = clrBlack, int fontSize = 12,
                color clrBg = clrNONE, color clrBorder = clrNONE,
                string font = "Arial Rounded MT Bold") {
    // Reset any previous errors
    ResetLastError();

    // Attempt to create the edit object
    if (!ObjectCreate(0, objName, OBJ_EDIT, 0, 0, 0)) {
        // Print an error message if creation fails
        Print(__FUNCTION__, ": failed to create the edit! Error code = ", _LastError);
        return (false);
    }

    // Set properties for the edit field
    ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_XSIZE, xS); // Width of the edit field
    ObjectSetInteger(0, objName, OBJPROP_YSIZE, yS); // Height of the edit field
    ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner
    ObjectSetString(0, objName, OBJPROP_TEXT, txt); // Default text in the edit field
    ObjectSetInteger(0, objName, OBJPROP_COLOR, clrTxt); // Text color
    ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, fontSize); // Font size
    ObjectSetString(0, objName, OBJPROP_FONT, font); // Font name
    ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, clrBg); // Background color
    ObjectSetInteger(0, objName, OBJPROP_BORDER_COLOR, clrBorder); // Border color
    ObjectSetInteger(0, objName, OBJPROP_ALIGN, ALIGN_LEFT); // Text alignment (left-aligned)
    ObjectSetInteger(0, objName, OBJPROP_READONLY, false); // Edit field is not read-only
    ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Transparent background
    ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Edit field state (not active)
    ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable
    ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected

    // Redraw the chart to display the edit field
    ChartRedraw(0);

    return (true); // Edit field creation successful
}

//+------------------------------------------------------------------+
//|     Function to create text label                                |
//+------------------------------------------------------------------+

bool createLabel(string objName, int xD, int yD,
                 string txt, color clrTxt = clrBlack, int fontSize = 12,
                 string font = "Arial Rounded MT Bold") {
    // Reset any previous errors
    ResetLastError();

    // Attempt to create the label object
    if (!ObjectCreate(0, objName, OBJ_LABEL, 0, 0, 0)) {
        // Print an error message if creation fails
        Print(__FUNCTION__, ": failed to create the label! Error code = ", _LastError);
        return (false);
    }

    // Set properties for the label
    ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner
    ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner
    ObjectSetString(0, objName, OBJPROP_TEXT, txt); // Text displayed on the label
    ObjectSetInteger(0, objName, OBJPROP_COLOR, clrTxt); // Text color
    ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, fontSize); // Font size
    ObjectSetString(0, objName, OBJPROP_FONT, font); // Font name
    ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Transparent background
    ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Label state (not active)
    ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable
    ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected

    // Redraw the chart to display the label
    ChartRedraw(0);

    return (true); // Label creation successful
}

//+------------------------------------------------------------------+
//|     Function to create the drop down utilities                   |
//+------------------------------------------------------------------+

void createDropDown(){
   createRecLabel(BTN_DROP_DN,25,95+25,130,70,clrWhite,2,clrBlack);
   createLabel(LABEL_OPT1,25+10,95+25,"LotSize",clrBlack,12,"stencil");
   createLabel(LABEL_OPT2,25+10,95+25+20,"Risk Percent %",clrBlack,12,"calibri Italic");
   createLabel(LABEL_OPT3,25+10,95+25+20+20,"Money Balance",clrBlack,12,"Arial bold");
   createLabel(ICON_DRAG,25+10+95,95+25,"d",clrRoyalBlue,15,"webdings");
}

//+------------------------------------------------------------------+
//|    Function to destroy the entire GUI Panel                      |
//+------------------------------------------------------------------+

void destroyPanel(){
   ObjectDelete(0,MAIN_REC);
   ObjectDelete(0,MAIN_SUB_REC);
   ObjectDelete(0,MAIN_LINE_UP);
   ObjectDelete(0,MAIN_LINE_DN);
   ObjectDelete(0,BTN_LOTS);
   ObjectDelete(0,LABEL_NAME);
   ObjectDelete(0,LABEL_LOTS);
   ObjectDelete(0,ICON_HEART);
   ObjectDelete(0,ICON_TOOL);
   ObjectDelete(0,ICON_CAR);
   ObjectDelete(0,ICON_DROP_DN1);
   ObjectDelete(0,LINE1);
   ObjectDelete(0,BTN_CLOSE);
   ObjectDelete(0,BTN_MARKET);
   ObjectDelete(0,BTN_PROFIT);
   ObjectDelete(0,BTN_LOSS);
   ObjectDelete(0,BTN_PENDING);
   ObjectDelete(0,LINE2);
   ObjectDelete(0,EDIT_LOTS);
   ObjectDelete(0,BTN_P1);
   ObjectDelete(0,BTN_M1);
   
   ObjectDelete(0,BTN_SL);
   ObjectDelete(0,LABEL_SL);
   ObjectDelete(0,ICON_DROP_DN2);
   ObjectDelete(0,EDIT_SL);
   ObjectDelete(0,BTN_P2);
   ObjectDelete(0,BTN_M2);
   
   ObjectDelete(0,BTN_TP);
   ObjectDelete(0,LABEL_TP);
   ObjectDelete(0,ICON_DROP_DN3);
   ObjectDelete(0,EDIT_TP);
   ObjectDelete(0,BTN_P3);
   ObjectDelete(0,BTN_M3);
   
   ObjectDelete(0,BTN_BUY);
   ObjectDelete(0,LABEL_BUY);
   ObjectDelete(0,LABEL_BUY_PRICE);
   ObjectDelete(0,BTN_OVERLAY);
   ObjectDelete(0,BTN_SPREAD);
   
   ObjectDelete(0,BTN_SELL);
   ObjectDelete(0,LABEL_SELL);
   ObjectDelete(0,LABEL_SELL_PRICE);
   
   ObjectDelete(0,BTN_CONTACT);
   
   ObjectDelete(0,BTN_SHARP);
   ObjectDelete(0,LABEL_SHARP);
   ObjectDelete(0,BTN_HOVER);
   ObjectDelete(0,LABEL_HOVER);
   
   ObjectDelete(0,LABEL_EXTRA1);
   ObjectDelete(0,LABEL_EXTRA2);
   ObjectDelete(0,LABEL_EXTRA3);
   ObjectDelete(0,LABEL_EXTRA4);
   
   ObjectDelete(0,BTN_DROP_DN);
   ObjectDelete(0,LABEL_OPT1);
   ObjectDelete(0,LABEL_OPT2);
   ObjectDelete(0,LABEL_OPT3);
   ObjectDelete(0,ICON_DRAG);
   
   ChartRedraw(0);
}


Schlussfolgerung

Abschließend können Sie feststellen, dass die Erstellung von GUI-Panels nicht so komplex ist, wie man denkt. Der Prozess umfasst eine Reihe von Schritten, die von der Definition der Abmessungen des Panels, d. h. der Festlegung der Position, der Größe und des Aussehens des Panels, das absolute oder auf das Chart bezogene Koordinaten verwenden kann, über die Erstellung verschiedener grafischer Objekte wie Schaltflächen, Beschriftungen, Bearbeitungsfelder und Rechteckbeschriftungen unter Angabe ihrer Eigenschaften (Farbe, Text, Schriftart usw.) bis hin zur Implementierung in Ereignisbehandlungsroutinen für die Erstellung der Panels und Nutzerinteraktionen reichen.

Dieser erste Teil hat die erfolgreiche Erstellung des Panels erfolgreich dargestellt. Der zweite Teil wird das Panel zum Leben erwecken, indem er es reaktionsfähig macht. Zum Beispiel werden wir die Schaltflächen so gestalten, dass sie bei Klicks reagieren, die Preisangaben bei jedem Tick aktualisieren, die Dropdown-Liste verschiebbar machen, Hover-Effekte zu den Schaltflächen hinzufügen und vieles mehr. Wir hoffen, dass Ihnen dieser Artikel bei der Erstellung von GUI-Panels nützlich war und dass Sie das hier vermittelte Wissen nutzen können, um noch komplexere und ausgefallenere GUI-Panels zu erstellen.


Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/15205

Beigefügte Dateien |
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.
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 25): Multi-Timeframe-Tests und -Handel MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 25): Multi-Timeframe-Tests und -Handel
Strategien, die auf mehreren Zeitrahmen (Multi-Timeframe) basieren, können aufgrund der in den Assembly-Klassen verwendeten MQL5-Code-Architektur standardmäßig nicht in den vom Assistenten zusammengestellten Expert Advisors getestet werden. In einer Fallstudie mit dem quadratischen gleitenden Durchschnitt untersuchen wir, wie sich diese Einschränkung bei Strategien, die mehrere Zeitrahmen nutzen wollen, umgehen lässt.
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.
Verwendung des Algorithmus PatchTST für maschinelles Lernen zur Vorhersage der Kursentwicklung in den nächsten 24 Stunden Verwendung des Algorithmus PatchTST für maschinelles Lernen zur Vorhersage der Kursentwicklung in den nächsten 24 Stunden
In diesem Artikel wenden wir einen relativ komplexen Algorithmus eines neuronalen Netzes aus dem Jahr 2023 namens PatchTST zur Vorhersage der Kursentwicklung der nächsten 24 Stunden an. Wir werden das offizielle Repository verwenden, geringfügige Änderungen vornehmen, ein Modell für EURUSD trainieren und es zur Erstellung von Zukunftsprognosen sowohl in Python als auch in MQL5 anwenden.