
Entwicklung eines Toolkit zur Analyse von Preisaktionen (Teil 8): Metrics Board
Inhalt
- Einführung
- System-Übersicht
- MQL5 Code
- Aufschlüsselung und Implementierung des Codes
- Einschließlich Bibliotheken
- Ergebnisse
- Schlussfolgerung
Einführung
In der Anfangsphase unserer Serie veröffentlichten wir einen Artikel mit dem Titel „Analytics Master“, in dem wir Methoden zum Abrufen und Visualisieren der Marktkennzahlen des Vortags untersuchten. Diese grundlegenden Arbeiten bildeten die Grundlage für die Entwicklung anspruchsvollerer Instrumente. Wir freuen uns, Ihnen den Metrics Board EA vorstellen zu können, eine innovative und qualitativ hochwertige Lösung, die die Marktanalyse im MetaTrader 5 revolutioniert. Dieses Tool funktioniert als nahtlos integrierte Anwendung und bietet eine optimierte und einfache Nutzeroberfläche mit speziellen Schaltflächen für fortgeschrittene Analysen, einschließlich:
- Hoch/Tief-Analyse: Erkennen Sie mühelos kritische Kursniveaus, um Markttrends zu bewerten und potenzielle Umschwünge zu identifizieren.
- Volumenanalyse: Analysieren Sie die Handelsvolumina, um das Marktengagement und die Liquiditätsbedingungen zu beurteilen.
- Trendanalyse: Bewertung der Richtungsstärke und Nachhaltigkeit anhand präziser Metriken.
- Volatilitätsanalyse: Quantifizierung von Marktschwankungen zur Formulierung von Strategien, die auf unterschiedliche Handelsumgebungen zugeschnitten sind.
- Analyse des gleitenden Durchschnitts: Überwachen der dynamische Preistrends, um ein besseres Verständnis des Marktverhaltens zu erlangen.
- Analyse von Unterstützung/Widerstand: Identifizieren der entscheidende Kursniveaus, um Ein- und Ausstiege sowie Risikomanagementstrategien zu optimieren.
Jede Schaltfläche ermöglicht die Bereitstellung von Live-Daten mit einem einfachen Klick und verwandelt komplexe Marktdaten in sofort umsetzbare Erkenntnisse. Der EA Metrics Board wird von fortschrittlichen Algorithmen angetrieben, die schnelle und genaue Berechnungen gewährleisten, die den Bedürfnissen professioneller Trader entsprechen. Mit diesem Tool können Händler komplizierte Marktdaten in einfache und umsetzbare Erkenntnisse umwandeln. Dieser EA dient als wichtige Ressource für diejenigen, die ihre Handelsstrategien verfeinern wollen.
System-Übersicht
In diesem Abschnitt werde ich einen kurzen Überblick über die Systemlogik geben. Eine ausführliche Erläuterung der Schritte finden Sie im Abschnitt Codeaufschlüsselung und Implementierung. Gehen wir die folgenden Schritte durch:
- Einrichtung der Klasse: Die Klasse erstellt einen Dialog mit Schaltflächen für verschiedene Analysen.
- Ereignisbehandlung: Schaltflächenklicks lösen entsprechende Analysemethoden aus.
- Analyse und Anzeige: Die Marktdaten werden verarbeitet und im Panel angezeigt.
- Schließen: Eine Schaltfläche „Close“ ermöglicht es dem Nutzer, die Metrik-Tafel zu schließen.
Abb. 1. Zusammenfassung der Logik des EAs
MQL5 Code
//+------------------------------------------------------------------+ //| Metrics Board.mql5| //| Copyright 2025, Christian Benjamin| //| https://www.mql5.com| //+------------------------------------------------------------------+ #property copyright "2025, MetaQuotes Software Corp." #property link "https://www.mql5.com/en/users/lynnchris" #property version "1.0" #property strict #include <Trade\Trade.mqh> #include <Controls\Dialog.mqh> #include <Controls\Button.mqh> #include <Controls\Label.mqh> #include <Controls\Panel.mqh> // Metrics Board Class class CMetricsBoard : public CAppDialog { private: CButton m_btnClose; // Close Button CButton m_btnHighLowAnalysis; CButton m_btnVolumeAnalysis; CButton m_btnTrendAnalysis; CButton m_btnVolatilityAnalysis; CButton m_btnMovingAverage; CButton m_btnSupportResistance; CPanel m_panelResults; CLabel m_lblResults; public: CMetricsBoard(void); ~CMetricsBoard(void); virtual bool Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2); virtual void Minimize(); virtual bool Run(); // Declaration of Run method virtual bool OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam); virtual bool ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam); virtual void Destroy(const int reason = REASON_PROGRAM); // Override Destroy method private: bool CreateButtons(void); bool CreateResultsPanel(void); void OnClickButtonClose(); // New close button handler void PerformHighLowAnalysis(void); void PerformVolumeAnalysis(void); void PerformTrendAnalysis(void); void PerformVolatilityAnalysis(void); void PerformMovingAverageAnalysis(void); void PerformSupportResistanceAnalysis(void); double CalculateMovingAverage(int period); }; CMetricsBoard::CMetricsBoard(void) {} CMetricsBoard::~CMetricsBoard(void) {} // Override Destroy method void CMetricsBoard::Destroy(const int reason) { // Call base class Destroy method to release resources CAppDialog::Destroy(reason); } //+------------------------------------------------------------------+ //| Create a control dialog | //+------------------------------------------------------------------+ bool CMetricsBoard::Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2) { if(!CAppDialog::Create(chart, name, subwin, x1, y1, x2, y2)) { Print("Failed to create CAppDialog instance."); return false; // Failed to create the dialog } if(!CreateResultsPanel()) { Print("Failed to create results panel."); return false; // Failed to create the results panel } if(!CreateButtons()) { Print("Failed to create buttons."); return false; // Failed to create buttons } Show(); // Show the dialog after creation return true; // Successfully created the dialog } //+------------------------------------------------------------------+ //| Minimize the control window | //+------------------------------------------------------------------+ void CMetricsBoard::Minimize() { CAppDialog::Minimize(); } //+------------------------------------------------------------------+ //| Run the control. | //+------------------------------------------------------------------+ bool CMetricsBoard::Run() { // Assuming Run makes the dialog functional if(!Show()) { Print("Failed to show the control."); return false; // Could not show the control } // Additional initialization or starting logic can be added here return true; // Successfully run the control } //+------------------------------------------------------------------+ //| Create the results panel | //+------------------------------------------------------------------+ bool CMetricsBoard::CreateResultsPanel(void) { if(!m_panelResults.Create(0, "ResultsPanel", 0, 10, 10, 330, 60)) return false; m_panelResults.Color(clrLightGray); Add(m_panelResults); if(!m_lblResults.Create(0, "ResultsLabel", 0, 15, 15, 315, 30)) return false; m_lblResults.Text("Results will be displayed here."); m_lblResults.Color(clrBlack); m_lblResults.FontSize(12); Add(m_lblResults); return true; } //+------------------------------------------------------------------+ //| Create buttons for the panel | //+------------------------------------------------------------------+ bool CMetricsBoard::CreateButtons(void) { int x = 20; int y = 80; int buttonWidth = 300; int buttonHeight = 30; int spacing = 15; // Create Close Button if(!m_btnClose.Create(0, "CloseButton", 0, x, y, x + buttonWidth, y + buttonHeight)) return false; m_btnClose.Text("Close Panel"); Add(m_btnClose); y += buttonHeight + spacing; struct ButtonData { CButton *button; string name; string text; }; ButtonData buttons[] = { {&m_btnHighLowAnalysis, "HighLowButton", "High/Low Analysis"}, {&m_btnVolumeAnalysis, "VolumeButton", "Volume Analysis"}, {&m_btnTrendAnalysis, "TrendButton", "Trend Analysis"}, {&m_btnVolatilityAnalysis, "VolatilityButton", "Volatility Analysis"}, {&m_btnMovingAverage, "MovingAverageButton", "Moving Average"}, {&m_btnSupportResistance, "SupportResistanceButton", "Support/Resistance"} }; for(int i = 0; i < ArraySize(buttons); i++) { if(!buttons[i].button.Create(0, buttons[i].name, 0, x, y, x + buttonWidth, y + buttonHeight)) return false; buttons[i].button.Text(buttons[i].text); Add(buttons[i].button); y += buttonHeight + spacing; } return true; } //+------------------------------------------------------------------+ //| Handle events for button clicks | //+------------------------------------------------------------------+ bool CMetricsBoard::OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_OBJECT_CLICK) { Print("Event ID: ", id, ", Event parameter (sparam): ", sparam); if(sparam == "CloseButton") // Handle close button click { OnClickButtonClose(); // Call to new close button handler return true; // Event processed } else if(sparam == "HighLowButton") { Print("High/Low Analysis Button Clicked"); m_lblResults.Text("Performing High/Low Analysis..."); PerformHighLowAnalysis(); return true; // Event processed } else if(sparam == "VolumeButton") { Print("Volume Analysis Button Clicked"); m_lblResults.Text("Performing Volume Analysis..."); PerformVolumeAnalysis(); return true; // Event processed } else if(sparam == "TrendButton") { Print("Trend Analysis Button Clicked"); m_lblResults.Text("Performing Trend Analysis..."); PerformTrendAnalysis(); return true; // Event processed } else if(sparam == "VolatilityButton") { Print("Volatility Analysis Button Clicked"); m_lblResults.Text("Performing Volatility Analysis..."); PerformVolatilityAnalysis(); return true; // Event processed } else if(sparam == "MovingAverageButton") { Print("Moving Average Analysis Button Clicked"); m_lblResults.Text("Calculating Moving Average..."); PerformMovingAverageAnalysis(); return true; // Event processed } else if(sparam == "SupportResistanceButton") { Print("Support/Resistance Analysis Button Clicked"); m_lblResults.Text("Calculating Support/Resistance..."); PerformSupportResistanceAnalysis(); return true; // Event processed } } return false; // If we reach here, the event was not processed } //+------------------------------------------------------------------+ //| Handle chart events | //+------------------------------------------------------------------+ bool CMetricsBoard::ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { Print("ChartEvent ID: ", id, ", lparam: ", lparam, ", dparam: ", dparam, ", sparam: ", sparam); if(id == CHARTEVENT_OBJECT_CLICK) { return OnEvent(id, lparam, dparam, sparam); } return false; } //+------------------------------------------------------------------+ //| Analysis operations | //+------------------------------------------------------------------+ void CMetricsBoard::PerformHighLowAnalysis(void) { double high = iHigh(Symbol(), PERIOD_H1, 0); double low = iLow(Symbol(), PERIOD_H1, 0); Print("Retrieved High: ", high, ", Low: ", low); if(high == 0 || low == 0) { m_lblResults.Text("Failed to retrieve high/low values."); return; } string result = StringFormat("High: %.5f, Low: %.5f", high, low); m_lblResults.Text(result); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMetricsBoard::PerformVolumeAnalysis(void) { double volume = iVolume(Symbol(), PERIOD_H1, 0); Print("Retrieved Volume: ", volume); if(volume < 0) { m_lblResults.Text("Failed to retrieve volume."); return; } string result = StringFormat("Volume (Last Hour): %.1f", volume); m_lblResults.Text(result); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMetricsBoard::PerformTrendAnalysis(void) { double ma = CalculateMovingAverage(14); Print("Calculated 14-period MA: ", ma); if(ma <= 0) { m_lblResults.Text("Not enough data for moving average calculation."); return; } string result = StringFormat("14-period MA: %.5f", ma); m_lblResults.Text(result); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMetricsBoard::PerformVolatilityAnalysis(void) { int atr_period = 14; int atr_handle = iATR(Symbol(), PERIOD_H1, atr_period); if(atr_handle == INVALID_HANDLE) { m_lblResults.Text("Failed to get ATR handle."); return; } double atr_value[]; if(CopyBuffer(atr_handle, 0, 0, 1, atr_value) < 0) { m_lblResults.Text("Failed to copy ATR value."); IndicatorRelease(atr_handle); return; } string result = StringFormat("ATR (14): %.5f", atr_value[0]); m_lblResults.Text(result); IndicatorRelease(atr_handle); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMetricsBoard::PerformMovingAverageAnalysis(void) { double ma = CalculateMovingAverage(50); Print("Calculated 50-period MA: ", ma); if(ma <= 0) { m_lblResults.Text("Not enough data for moving average calculation."); return; } string result = StringFormat("50-period MA: %.5f", ma); m_lblResults.Text(result); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMetricsBoard::PerformSupportResistanceAnalysis(void) { double support = iLow(Symbol(), PERIOD_H1, 1); double resistance = iHigh(Symbol(), PERIOD_H1, 1); Print("Retrieved Support: ", support, ", Resistance: ", resistance); if(support == 0 || resistance == 0) { m_lblResults.Text("Failed to retrieve support/resistance levels."); return; } string result = StringFormat("Support: %.5f, Resistance: %.5f", support, resistance); m_lblResults.Text(result); } //+------------------------------------------------------------------+ //| Calculate moving average | //+------------------------------------------------------------------+ double CMetricsBoard::CalculateMovingAverage(int period) { if(period <= 0) return 0; double sum = 0.0; int bars = Bars(Symbol(), PERIOD_H1); if(bars < period) { return 0; } for(int i = 0; i < period; i++) { sum += iClose(Symbol(), PERIOD_H1, i); } return sum / period; } // Implementation of OnClickButtonClose void CMetricsBoard::OnClickButtonClose() { Print("Close button clicked. Closing the Metrics Board..."); Destroy(); // This method destroys the panel } CMetricsBoard ExtDialog; //+------------------------------------------------------------------+ //| Initialize the application | //+------------------------------------------------------------------+ int OnInit() { if(!ExtDialog.Create(0, "Metrics Board", 0, 10, 10, 350, 500)) { Print("Failed to create Metrics Board."); return INIT_FAILED; } if(!ExtDialog.Run()) // Call Run to make the dialog functional { Print("Failed to run Metrics Board."); return INIT_FAILED; // Call to Run failed } return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ //| Deinitialize the application | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { ExtDialog.Destroy(reason); // Properly call Destroy method } //+------------------------------------------------------------------+ //| Handle chart events | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { ExtDialog.ChartEvent(id, lparam, dparam, sparam); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+
Aufschlüsselung und Implementierung des Codes
- Kopfzeilen und Metadaten
//+------------------------------------------------------------------+ //| Metrics Board.mql5| //| Copyright 2025, Christian Benjamin| //| https://www.mql5.com| //+------------------------------------------------------------------+ #property copyright "2025, MetaQuotes Software Corp." #property link "https://www.mql5.com/en/users/lynnchris" #property version "1.0" #property strictDer Kommentarblock beschreibt den Zweck des Skripts und nennt die Verdienste, was für die Identifizierung der Urheberschaft und die Sicherstellung der korrekten Zuordnung für zukünftige Nutzer unerlässlich ist. Die #property-Direktiven dienen dazu, verschiedene Eigenschaften des Skripts zu definieren, wie z. B. Copyright-Informationen, einen Link zum Autor oder zur Dokumentation, die Versionsnummer und die Einstellung des Strict-Modus, der dabei hilft, mögliche Probleme während der Kompilierung zu erkennen.
- Einschließlich notwendiger Bibliotheken
Als Nächstes fügen wir die für unsere Anwendung erforderlichen Bibliotheken ein. Diese Bibliotheken bieten vordefinierte Funktionen, die die Codierung vereinfachen.
#include <Trade\Trade.mqh> #include <Controls\Dialog.mqh> #include <Controls\Button.mqh> #include <Controls\Label.mqh> #include <Controls\Panel.mqh>
Hier werden die Bibliotheken für die Handelsoperationen und die Bedienelemente der Nutzeroberfläche integriert. Beispielsweise ist Trade.mqh für die Ausführung von Handelsfunktionen unerlässlich, während Dialog.mqh, Button.mqh, Label.mqh und Panel.mqh zur Erstellung und Verwaltung der Nutzeroberflächenkomponenten des Metrics Board verwendet werden.
- Definition der Klasse
class CMetricsBoard : public CAppDialog { private: CButton m_btnClose; CButton m_btnHighLowAnalysis; CButton m_btnVolumeAnalysis; CButton m_btnTrendAnalysis; CButton m_btnVolatilityAnalysis; CButton m_btnMovingAverage; CButton m_btnSupportResistance; CPanel m_panelResults; CLabel m_lblResults;
Die Klasse enthält auch einen Konstruktor und einen Destruktor.
public: CMetricsBoard(void); ~CMetricsBoard(void); CMetricsBoard::CMetricsBoard(void) {} CMetricsBoard::~CMetricsBoard(void) {}
Der Konstruktor initialisiert die Klasse, und der Destruktor ist definiert (wenn auch in diesem Fall leer), um sicherzustellen, dass alle notwendigen Aufräumarbeiten stattfinden, wenn eine Instanz von CMetricsBoard zerstört wird. Dies ist eine wesentliche Voraussetzung für eine effiziente Verwaltung der Ressourcen.
- Erstellen des Dialogs
Die Methode Create ist für den Aufbau des gesamten Kontrolldialogs zuständig. In dieser Methode versuchen wir zunächst, den Dialog über die Basisklasse (CAppDialog::Create) zu erstellen. Schlägt es fehl, wird ein Fehler protokolliert und false zurückgegeben. Als Nächstes erstellen wir eine Ergebnistafel und Schaltflächen und prüfen erneut auf mögliche Fehler. Wenn alle Schritte erfolgreich waren, wird der Dialog angezeigt und true zurückgegeben.
bool CMetricsBoard::Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2) { if(!CAppDialog::Create(chart, name, subwin, x1, y1, x2, y2)) { Print("Failed to create CAppDialog instance."); return false; } if(!CreateResultsPanel()) { Print("Failed to create results panel."); return false; } if(!CreateButtons()) { Print("Failed to create buttons."); return false; } Show(); return true; }
Nun wird das Dialogfeld Ausführen (Run) angezeigt. Die Methode Run ist wichtig, damit der Dialog funktioniert.
bool CMetricsBoard::Run() { if(!Show()) { Print("Failed to show the control."); return false; } return true; }
Hier wird der Dialog mit der Methode Show angezeigt. Wenn die Anzeige des Dialogs fehlschlägt, wird eine Fehlermeldung ausgegeben und false zurückgegeben.
- Erstellen der Ergebnistafel
Mit der Methode CreateResultsPanel wird das Panel erstellt, in dem die Analyseergebnisse angezeigt werden sollen. Zunächst erstellen wir die Ergebnistafel und legen ihre Eigenschaften, wie Farbe und Abmessungen, fest. Anschließend fügen wir dieses Panel dem Dialog hinzu. Wir erstellen auch einen Bereich innerhalb des Panels, um die Ergebnisse anzuzeigen, und passen dessen Aussehen an, bevor wir es dem Panel hinzufügen. Diese Methode gibt bei erfolgreicher Erstellung true zurück.
bool CMetricsBoard::CreateResultsPanel(void) { if(!m_panelResults.Create(0, "ResultsPanel", 0, 10, 10, 330, 60)) return false; m_panelResults.Color(clrLightGray); Add(m_panelResults); if(!m_lblResults.Create(0, "ResultsLabel", 0, 15, 15, 315, 30)) return false; m_lblResults.Text("Results will be displayed here."); m_lblResults.Color(clrBlack); m_lblResults.FontSize(12); Add(m_lblResults); return true; }
- Schaltflächen erstellen
Die Methode CreateButtons ist für die Initialisierung der interaktiven Schaltflächen im Dialog zuständig.
bool CMetricsBoard::CreateButtons(void) { int x = 20; int y = 80; int buttonWidth = 300; int buttonHeight = 30; int spacing = 15; if(!m_btnClose.Create(0, "CloseButton", 0, x, y, x + buttonWidth, y + buttonHeight)) return false; m_btnClose.Text("Close Panel"); Add(m_btnClose); y += buttonHeight + spacing; struct ButtonData { CButton *button; string name; string text; }; ButtonData buttons[] = { {&m_btnHighLowAnalysis, "HighLowButton", "High/Low Analysis"}, {&m_btnVolumeAnalysis, "VolumeButton", "Volume Analysis"}, {&m_btnTrendAnalysis, "TrendButton", "Trend Analysis"}, {&m_btnVolatilityAnalysis, "VolatilityButton", "Volatility Analysis"}, {&m_btnMovingAverage, "MovingAverageButton", "Moving Average"}, {&m_btnSupportResistance, "SupportResistanceButton", "Support/Resistance"} }; for(int i = 0; i < ArraySize(buttons); i++) { if(!buttons[i].button.Create(0, buttons[i].name, 0, x, y, x + buttonWidth, y + buttonHeight)) return false; buttons[i].button.Text(buttons[i].text); Add(buttons[i].button); y += buttonHeight + spacing; } return true; }
In dieser Implementierung legen wir die Anfangskoordinaten, Abmessungen und Abstände für unsere Schaltflächen fest. Wir erstellen jede Schaltfläche, zuerst für das Schließen des Panels, und fügen sie dem Dialog hinzu. Anschließend verwenden wir ein Array von ButtonData-Strukturen, mit denen wir die Schaltflächendefinitionen in einer Schleife durchlaufen können. Jede Schaltfläche wird mit einem entsprechenden Text versehen und dem Dialogfeld hinzugefügt. Die Methode schließt mit der Rückgabe von true ab, wenn alle Schaltflächen erfolgreich erstellt wurden.
- Handhabung von Ereignissen
1. Tastenklicks
Die Methode OnEvent verarbeitet Ereignisse, die durch Nutzerinteraktion erzeugt werden, wie z. B. das Klicken auf eine Schaltfläche.
bool CMetricsBoard::OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_OBJECT_CLICK) { Print("Event ID: ", id, ", Event parameter (sparam): ", sparam); if(sparam == "CloseButton") { OnClickButtonClose(); return true; } // ... Handling for other button clicks } return false; }
Wenn ein Ereignis eintritt, wird zunächst geprüft, ob es sich um ein Tastenklick-Ereignis handelt. Wir drucken die Ereignisdetails zu Debugging-Zwecken aus und reagieren auf bestimmte Schaltflächenklicks, indem wir die entsprechenden Bearbeitungsfunktionen aufrufen. Wenn es sich bei der angeklickten Schaltfläche um die Schaltfläche zum Schließen handelt, rufen wir die Methode OnClickButtonClose() auf.
2. Chart-Ereignisse
Die Methode ChartEvent dient einem ähnlichen Zweck, konzentriert sich aber speziell auf chartbezogene Ereignisse.
bool CMetricsBoard::ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { Print("ChartEvent ID: ", id, ", lparam: ", lparam, ", dparam: ", dparam, ", sparam: ", sparam); if(id == CHARTEVENT_OBJECT_CLICK) { return OnEvent(id, lparam, dparam, sparam); } return false; }
Diese Methode erfasst alle Klicks auf Chartobjekte und übergibt das Ereignis zur weiteren Verarbeitung an die Methode OnEvent.
- Analyse Operationen
Die folgenden Methoden implementieren die verschiedenen Marktanalysetypen, die unser Metrics Board durchführen kann. Die PerformHighLowAnalysis beispielsweise ruft die Hochs und Tiefs für einen bestimmten Zeitraum ab:
void CMetricsBoard::PerformHighLowAnalysis(void) { double high = iHigh(Symbol(), PERIOD_H1, 0); double low = iLow(Symbol(), PERIOD_H1, 0); Print("Retrieved High: ", high, ", Low: ", low); if(high == 0 || low == 0) { m_lblResults.Text("Failed to retrieve high/low values."); return; } string result = StringFormat("High: %.5f, Low: %.5f", high, low); m_lblResults.Text(result); }
Bei dieser Methode verwenden wir integrierte Funktionen, um die höchsten und niedrigsten Preise der letzten Stunde zu ermitteln. Bei Erfolg werden die Ergebnisse auf dem Panel angezeigt. Wenn nicht, wird eine Fehlermeldung angezeigt.
Eine ähnliche Logik wird auf andere Analysefunktionen angewandt, wie PerformVolumeAnalysis, PerformTrendAnalysis, PerformVolatilityAnalysis, PerformMovingAverageAnalysis und PerformSupportResistanceAnalysis. Jede Methode ruft die für ihren Analysetyp spezifischen Daten ab und aktualisiert die Nutzeroberfläche entsprechend.
- Berechnung des gleitenden Durchschnitts
Eine der enthaltenen Hilfsmethoden ist CalculateMovingAverage, mit der der gleitende Durchschnitt über einen bestimmten Zeitraum berechnet wird. Bei dieser Methode werden die Schlusskurse über den angegebenen Zeitraum summiert und durch diese Zahl dividiert, um den Durchschnitt zu ermitteln. Es prüft, ob die Eingabe gültig ist und die Daten ausreichen, bevor die Berechnung durchgeführt wird.
double CMetricsBoard::CalculateMovingAverage(int period) { if(period <= 0) return 0; double sum = 0.0; int bars = Bars(Symbol(), PERIOD_H1); if(bars < period) { return 0; } for(int i = 0; i < period; i++) { sum += iClose(Symbol(), PERIOD_H1, i); } return sum / period; }
- Globale Instanz und Initialisierung
Eine Instanz der Klasse CMetricsBoard wird global erstellt, gefolgt von den Initialisierungs- und Deinitialisierungsprozessen für die Anwendung.
CMetricsBoard ExtDialog; int OnInit() { if(!ExtDialog.Create(0, "Metrics Board", 0, 10, 10, 350, 500)) { Print("Failed to create Metrics Board."); return INIT_FAILED; } if(!ExtDialog.Run()) { Print("Failed to run Metrics Board."); return INIT_FAILED; } return INIT_SUCCEEDED; }
In der Funktion OnInit wird das Metrics Board durch den Aufruf der Methode Create initialisiert. Wenn dies erfolgreich war, führen wir es aus. Fehler werden entsprechend protokolliert, wobei die Funktion den Erfolg oder Misserfolg anzeigt.
Der Deinitialisierungsprozess stellt sicher, dass die Ressourcen korrekt freigegeben werden, wenn der EA entfernt wird.
void OnDeinit(const int reason) { ExtDialog.Destroy(reason); // Properly call Destroy method }
- Chart-Ereignisbehandlung
Schließlich definieren wir die Funktion OnChartEvent, um Ereignisse im Zusammenhang mit dem Chart zu verwalten. Dadurch werden die Nutzerinteraktionen direkt in die Funktionalität der Anwendung integriert. Diese Methode erfasst Chartereignisse und übergibt sie an die ChartEvent-Methode unserer CMetricsBoard-Instanz.
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { ExtDialog.ChartEvent(id, lparam, dparam, sparam); }
Einbinden der Bibliotheken
Wenn Sie Ihren Code kompilieren, ohne die im vorigen Abschnitt erwähnten Bibliotheken einzubinden, können Fehler auftreten. Um dies zu beheben, öffnen Sie MetaEditor und navigieren Sie zum Navigator-Panel. Blättern Sie nach unten zum Abschnitt „Einbinden“, wo Sie auf die erforderlichen Bibliotheken zugreifen können. Öffnen Sie die erforderlichen Unterordner, wählen Sie die entsprechenden Dateien aus und kompilieren Sie sie einzeln. Stellen Sie sicher, dass die Bibliotheken in Ihrem Code korrekt referenziert werden, indem Sie die Direktive #include am Anfang Ihres Skripts verwenden. Dieser Schritt stellt sicher, dass alle Abhängigkeiten korrekt geladen werden, um mögliche Kompilierungsfehler zu vermeiden. Das folgende GIF zeigt, wie man auf Bibliotheken in MetaEditor zugreift und sie einbindet.
Abb. 2. Einbinden von Bibliotheken
In MQL5 ermöglicht eine eingebundene Bibliothek die Integration von externem Code, Funktionen oder Klassen in Ihr Programm, um dessen Funktionalität zu erweitern und die Wiederverwendung von Code aus verschiedenen Quellen zu ermöglichen. Wenn Sie eine Bibliothek einbinden, erhalten Sie Zugriff auf die darin definierten Funktionen, Klassen oder Variablen und können diese in Ihrem Skript, Expert Advisor (EA) oder Indikator verwenden. Die meisten Bibliotheken in MQL5 sind integriert und bieten fertige Lösungen für gängige Aufgaben wie Handelsfunktionen, technische Indikatoren und mehr.
Ergebnisse
Nachdem Sie den EA erfolgreich kompiliert haben, können Sie nun zu MetaTrader 5 gehen und den EA mit einem Chart verbinden. Schauen wir uns die Ergebnisse an, die wir bei den Tests erzielt haben.
Abb. 3. Ergebnisse
Anhand des obigen Diagramms ist ersichtlich, dass der EA Metrics Board eine optimale Funktionalität bietet und effektiv auf jeden Tastendruck reagiert. Diese Fähigkeit stellt sicher, dass der EA die erforderlichen Zahlen in Echtzeit bereitstellt, was die Interaktion mit dem Nutzer und die Leistung verbessert.
- EA-Protokollierung
Wir können auch das Expertenprotokoll in MetaTrader 5 einsehen, um die Interaktion zwischen den gedrückten Tasten und den Ereignissen auf dem Chart zu beobachten. Da unser EA über eine integrierte Protokollierungsfunktion verfügt, werden diese Interaktionen erfasst. Werfen wir einen Blick auf die protokollierten Informationen und analysieren wir, was aufgezeichnet wurde.
Abb. 4. Experten Logging
Schlussfolgerung
Der Metrics Board EA verfügt über ein dynamisches und nutzerfreundliches Panel-Interface, das direkt in MetaTrader 5 eingebettet ist und die Draw-Object-Funktion beinhaltet. Die nahtlose Integration vermittelt den Eindruck, mit nativen MetaTrader 5-Steuerungen zu arbeiten, und bietet eine Erfahrung, die mit der Verwendung einer integrierten Anwendung vergleichbar ist. Meiner Meinung nach stellt es einen bedeutenden Fortschritt bei den Handelswerkzeugen dar, da es eine Funktionalität und Nutzerfreundlichkeit bietet, die die Möglichkeiten einiger Analyseskripte, die ich zuvor entwickelt habe, übersteigt. Durch die Möglichkeit, sich mit einem einzigen Mausklick auf bestimmte Informationen zu konzentrieren, wird sichergestellt, dass nur die erforderlichen Daten angezeigt werden, was den Analyseprozess vereinfacht. Während diese früheren Skripte ihren Zweck effektiv erfüllten, hebt das Metrics Board EA die Marktanalyse auf ein höheres Niveau der Effizienz und Zugänglichkeit.
Zu den wichtigsten Merkmalen des Metrics Board EA gehören:
Merkmal | Vorteil |
---|---|
Hoch/Tief-Analyse | Identifiziert schnell wichtige Marktniveaus, um Händlern zu helfen. |
Volumenverfolgung | Bietet aktuelle Informationen über das Handelsvolumen für einen besseren Marktkontext. |
Identifizierung von Trends | Vereinfacht das Erkennen von aktuellen Markttrends. |
Unterstützungs-/Widerstandsniveaus | Zeigt genau die entscheidenden Preiszonen für den strategischen Handel an. |
Dieses Tool ermöglicht es Händlern, die Märkte effektiv zu analysieren und bessere Entscheidungen zu treffen. Sein unkompliziertes Design vereinfacht komplexe Analysen, sodass sich die Nutzer auf die Verfeinerung ihrer Strategien konzentrieren können. Mit Blick auf die Zukunft besteht die Möglichkeit, den Funktionsumfang zu erweitern, indem neue Funktionen hinzugefügt und die Schnittstelle weiter verbessert werden.
Datum | Name des Werkzeugs | Beschreibung | Version | Aktualisierungen | Hinweis |
---|---|---|---|---|---|
01/10/24 | Chart Projector | Skript zur Überlagerung der Kursentwicklung des Vortages mit Geistereffekt. | 1.0 | Erste Veröffentlichung | Erstes Werkzeug in Lynnchris Tool Chest |
18/11/24 | Analytischer Kommentar | Er liefert Informationen zum Vortag in Tabellenform und nimmt die zukünftige Marktentwicklung vorweg. | 1.0 | Erste Veröffentlichung | Zweites Werkzeug in Lynnchris Tool Chest |
27/11/24 | Analytics Master | Regelmäßige Aktualisierung der Marktmetriken alle zwei Stunden | 1.01 | Zweite Veröffentlichung | Drittes Werkzeug in Lynnchris Tool Chest |
02/12/24 | Analytics Forecaster | Regelmäßige Aktualisierung der Marktmetriken alle zwei Stunden mit Telegram-Integration | 1.1 | Dritte Auflage | Werkzeug Nummer 4 |
09/12/24 | Volatilitäts-Navigator | Der EA analysiert die Marktbedingungen anhand der Indikatoren Bollinger Bands, RSI und ATR | 1.0 | Erste Veröffentlichung | Werkzeug Nummer 5 |
19/12/24 | Umkehr zur Mitte, Signal Reaper | Analysiert den Markt anhand der Strategie der Umkehr zur Mitte und liefert Signale | 1.0 | Erste Veröffentlichung | Werkzeug Nummer 6 |
9/01/2025 | Signal-Impulse | Analysator für mehrere Zeitrahmen | 1.0 | Erste Veröffentlichung | Werkzeug Nummer 7 |
17/01/2025 | Metrics Board | Bedienfeld mit Taste für die Analyse | 1.0 | Erste Veröffentlichung | Werkzeug Nummer 8 |
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/16584





- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.