Vom Neuling zum Experten: Backend Operations Monitor mit MQL5
Inhalt der Diskussion:
Einführung
Die erfolgreiche Kompilierung eines Handelswerkzeugs in MetaEditor 5 ist ein wichtiger Meilenstein, aber es ist erst der Anfang. Die Kompilierung bestätigt, dass der Code syntaktisch gültig ist, garantiert jedoch nicht Leistung, Stabilität oder Korrektheit. Der eigentliche Test beginnt, wenn wir das System im MetaTrader 5 ausführen, sei es auf der Live-Plattform oder im Strategy Tester, um zu sehen, wie sich die Theorie in die Praxis umsetzt.
In diesem Stadium stehen die Entwickler vor einer allgemeinen Herausforderung: Obwohl wir die Logik geschrieben haben, wissen wir nicht immer, wie sich der EA unter Echtzeitbedingungen verhalten wird. Das Programm führt jede Regel mechanisch aus, was manchmal zu Ergebnissen führt, die wir nicht erwartet haben. Um unsere Systeme zu verfeinern und zu optimieren, brauchen wir mehr als nur Ergebnisse – wir brauchen Einblick in das Innenleben des EAs, was ist passiert, wann ist es passiert und wo im Code ist es passiert.
Die Grenzen der integrierten Protokollierung und unsere Lösung
MetaTrader 5 bietet zwei Hauptinstrumente zur Überwachung der Aktivitäten:
- Die Registerkarte Experts, auf der die von allen laufenden EAs und Indikatoren erzeugten Protokolle angezeigt werden.
- Die Registerkarte Journal, auf der Terminal- und Serverereignisse aufgezeichnet werden.
Diese sind zwar nützlich, haben aber eine entscheidende Einschränkung: Alle Expert Advisors teilen sich dieselbe Registerkarte Experts. Auch wenn die Protokollzeilen den Namen des EA enthalten, werden die Ausgaben mehrerer Systeme schnell vermischt, was zu Unordnung und Verwirrung führt. Wenn mehrere EAs aktiv sind, wird es schwierig, Protokolle für ein bestimmtes Instrument zu isolieren, was die Fehlersuche verlangsamt und das Vertrauen in die Ergebnisse verringert.
Hier finden Sie Beispiele für Expertenprotokolleinträge für drei verschiedene Programme, die in derselben Reihenfolge aufgeführt sind.
2025.09.21 08:10:42.006 BEODemoEA (EURAUD,H4) Abnormal termination 2025.09.21 08:20:15.056 Correlation Matrix 3D (EURAUD,M5) Symbol 'EURUSD' is not synchronized 2025.09.21 08:20:40.862 Correlation Matrix 3D (EURAUD,M5) Symbol 'EURGBP' is not synchronized 2025.09.21 08:20:44.065 Correlation Matrix 3D (EURAUD,M5) Symbol 'EURCHF' is not synchronized 2025.09.21 08:20:44.067 Correlation Matrix 3D (EURAUD,M5) Symbol 'EURJPY' is not synchronized 2025.09.21 08:20:44.078 Correlation Matrix 3D (EURAUD,M5) Symbol 'GBPUSD' is not synchronized 2025.09.21 08:20:44.080 Correlation Matrix 3D (EURAUD,M5) Symbol 'GBPCHF' is not synchronized 2025.09.21 08:20:44.082 Correlation Matrix 3D (EURAUD,M5) Symbol 'GBPJPY' is not synchronized 2025.09.21 08:20:44.095 Correlation Matrix 3D (EURAUD,M5) Symbol 'USDCHF' is not synchronized 2025.09.21 08:20:44.112 Correlation Matrix 3D (EURAUD,M5) Symbol 'USDJPY' is not synchronized 2025.09.21 08:20:44.114 Correlation Matrix 3D (EURAUD,M5) Symbol 'CHFJPY' is not synchronized 2025.09.21 08:20:44.114 Correlation Matrix 3D (EURAUD,M5) Try again #0 2025.09.21 08:20:44.125 Correlation Matrix 3D (EURAUD,M5) Some symbols not ready to use: 2025.09.21 08:20:44.125 Correlation Matrix 3D (EURAUD,M5) EURUSD 2025.09.21 08:20:44.125 Correlation Matrix 3D (EURAUD,M5) EURGBP 2025.09.21 08:20:44.125 Correlation Matrix 3D (EURAUD,M5) EURCHF 2025.09.21 08:20:44.125 Correlation Matrix 3D (EURAUD,M5) EURJPY 2025.09.21 08:20:44.125 Correlation Matrix 3D (EURAUD,M5) GBPUSD 2025.09.21 08:20:44.125 Correlation Matrix 3D (EURAUD,M5) GBPCHF 2025.09.21 08:20:44.125 Correlation Matrix 3D (EURAUD,M5) GBPJPY 2025.09.21 08:20:44.125 Correlation Matrix 3D (EURAUD,M5) USDCHF 2025.09.21 08:20:44.125 Correlation Matrix 3D (EURAUD,M5) USDJPY 2025.09.21 08:20:44.125 Correlation Matrix 3D (EURAUD,M5) CHFJPY 2025.09.21 08:20:44.125 Correlation Matrix 3D (EURAUD,M5) Error. Symbols not synchronized. 2025.09.21 08:20:44.125 Correlation Matrix 3D (EURAUD,M5) Error. Rates data is not loaded. 2025.09.21 09:00:00.112 Institutional Trading Zones (EURAUD,M5) indicator | EURAUD,5 | Session Alert: Sydney End at 2025.09.21 07:00 2025.09.21 10:00:00.177 Institutional Trading Zones (EURAUD,M5) indicator | EURAUD,5 | Session Alert: London Start at 2025.09.21 08:00 2025.09.21 10:05:00.172 Institutional Trading Zones (EURAUD,M5) indicator | EURAUD,5 | Bearish overlap, look to sell
Hier beginnt unsere Diskussion über die Klasse der Backend Operations (BEO). Anstatt sich nur auf die gemeinsame Registerkarte der Experten zu verlassen, können wir ein spezielles Überwachungs- und Protokollierungssystem entwickeln, das die Informationen direkt im Chart anzeigt und organisiert. Durch den Aufbau einer Klasse speziell für Backend-Operationen profitieren die Entwickler;
- Eine saubere, EA-spezifische Debugging-Schnittstelle.
- Echtzeittransparenz von Leistungskennzahlen und internen Ereignissen.
- Leichtere Identifizierung von Fehlern, Fehlverhalten und Ausführungsabläufen.
Im heutigen Artikel werden wir untersuchen, wie wir eine solche Klasse entwerfen können, um unseren Debugging-Workflow zu stärken und Händlern und Entwicklern ein zuverlässiges Werkzeug an die Hand zu geben, mit dem sie verstehen können, was im Backend ihrer EAs passiert.
Konzeptstudie
Die Durchführbarkeit des Konzepts der Backend Operations (BEO) hängt davon ab, ob MetaTrader 5 und MQL5 genügend Systemhooks für die Überwachung und Diagnose innerhalb eines Expert Advisors bereitstellen. Glücklicherweise bietet die Plattform eine Vielzahl von Funktionen für den Zugriff auf den Kontostand, die Terminalumgebung und die Handelsoperationen. Diese reichen von AccountInfo*() und TerminalInfo*() für Umgebungsdetails bis zu MqlTradeRequest und MqlTradeResult für Ergebnisse der Handelsausführung. Dadurch wird sichergestellt, dass jede von uns erstellte Backend-Schicht immer auf dieselben Low-Level-Informationen verweisen kann, auf die sich das Terminal selbst stützt, wodurch das Konzept technisch solide ist.
Ein weiterer entscheidender Faktor ist die Art und Weise, wie diese Details dargestellt werden. MQL5 bietet mehrere Ausgabekanäle: die Registerkarte „Experts“ für EA-Protokolle, die Registerkarte „Journal“ für Terminal- und Servernachrichten und die chartbasierte Visualisierung mit Comment(), ObjectCreate() oder fortgeschrittenen Tools wie CCanvas. Unsere nutzerdefinierte Klasse nutzt diese, um Handelsergebnisse, Fehlercodes und Diagnosehinweise in strukturierte Ausgaben umzuleiten, die es den Entwicklern ermöglichen, die internen Aktivitäten eines EAs von denen eines anderen zu unterscheiden. Dadurch wird die Einschränkung gemischter Protokolle auf der Registerkarte „Experten“ überwunden, bei der mehrere Programme zu einem einzigen Nachrichtenstrom verschmelzen können.
Schließlich wird die Durchführbarkeit der Integration durch die Fehlerbehandlung und die Historienfunktionen der Plattform unterstützt. Mit GetLastError() und dem Zugriff auf die Historie kann unsere Systemschicht sowohl Echtzeit-Probleme als auch den vergangenen Handelskontext erfassen und diese dann auf entwicklerfreundliche Weise anzeigen oder protokollieren. Indem wir dies in einer eigenen Backend-Klasse organisieren, beweisen wir, dass die Idee realisierbar ist, und öffnen außerdem die Tür für ein konsistentes Debugging, einfachere Upgrades und eine transparente Überwachung von Handelssystemen auf MetaTrader 5.
Im nächsten Abschnitt unserer Diskussion werden wir diese Idee weiter vertiefen, indem wir ihre Umsetzung Schritt für Schritt untersuchen. Wir werden die Code-Details der Klasse Backend Operations (BEO) durchgehen und dabei hervorheben, wie sie wichtige Debugging-Informationen erfasst, organisiert und anzeigt. Sobald die Grundlagen geklärt sind, werden wir mit On-Chart-Tests fortfahren, bei denen das System Echtzeit-Feedback direkt auf dem Handelschart präsentiert.
Abschließend werden wir die vollständige Lösung vorstellen, damit Entwickler und Händler sie in ihre eigenen Arbeitsabläufe integrieren können, um die Lücke zwischen Theorie, Code und praktischer Ausführung zu schließen.
Implementierung und Code
Die Reise in den Backend-Betrieb beginnt mit einem strukturierten Ansatz, der Klarheit und Effizienz in Einklang bringt. Durch die Entwicklung einer speziellen Überwachungsklasse, CBEOMonitor, können wir die Verantwortung für die Verfolgung und Anzeige von Diagnosen von der eigentlichen Handelslogik trennen. Dies vereinfacht die Fehlersuche und stellt einen wiederverwendbaren Baustein dar, der in jeden Expert Advisor integriert werden kann, ohne dass die gleichen Routinen immer wieder neu geschrieben werden müssen. Das Konzept hier ist Modularität – die Isolierung einer leistungsstarken Code-Einheit für viele verschiedene Systeme.
Um dieses Konzept mit Leben zu erfüllen, habe ich es in zwei bewussten Schritten umgesetzt. Zunächst wurde die Klasse selbst mit allen wichtigen Mechanismen für die Erfassung von Ereignissen, die Formatierung von Informationen und die übersichtliche Darstellung im Chart entwickelt. Anschließend zeigte die Integration in einen Demo-EA, wie nahtlos sich eine solche Klasse in eine Live-Handelsumgebung einfügen lässt. Bei dieser zweistufigen Entwicklung steht die Effizienz im Vordergrund: Ein gut entwickeltes Werkzeug kann auf immer komplexere Systeme übertragen werden. Mit dieser Grundlage ist es nun an der Zeit, den Code zu öffnen und zu sehen, wie die einzelnen Teile in der Praxis funktionieren.
Schritt 1: Die Klasse CBEOMonitor
Eingebunden – wovon der Monitor abhängt und warum
Dieser Monitor baut auf den UI-Primitiven und Standardcontainern von MQL5 auf. Die #include-Zeilen enthalten die Leinwand (Canvas) für die Darstellung von Bitmap-Etiketten, List für einen kleinen speicherinternen Ringpuffer für Nachrichten, Object.mqh und ChartObject.mqh für Chart-Objekt-Konstanten und -Helfer sowie Trade.mqh, wo handelsbezogene Helfer von den Protokollierungshelfern des Monitors verwendet werden. Die Enums definieren die Meldungsschweregrade und den Anzeigemodus; sie werden überall zum Filtern, Einfärben und Auswählen der Anzahl der anzuzeigenden Zeilen verwendet. Die Verwendung kleiner, expliziter Enums hält die API lesbar und vermeidet magische Zahlen im EA-Code.
#include <Object.mqh> #include <Canvas\Canvas.mqh> #include <Arrays\List.mqh> #include <Trade\Trade.mqh> #include <ChartObjects\ChartObject.mqh> // enums enum BEO_Level { BEO_L_INFO=0, BEO_L_SUCCESS, BEO_L_WARNING, BEO_L_ERROR, BEO_L_TRADE, BEO_L_DEBUG }; enum BEO_DisplayMode { BEO_DM_COMPACT=0, BEO_DM_EXPANDED };
BEO_Item – die Einheit der protokollierten Informationen
Jeder Protokolleintrag wird durch die Klasse BEO_Item repräsentiert. Er speichert den von Menschen lesbaren Text, einen Schweregrad, einen Datumszeitstempel und einen Mikrosekunden-Auflösungsstempel für Perf-Metriken sowie eine optionale Herkunftsbezeichnung (von wo im EA die Nachricht kam). Die Speicherung von Nachrichten in Form von Objekten ermöglicht einen Ringpuffer mit fester Kapazität (über CList), während die Speicherverwaltung überschaubar bleibt. Diese kleine Struktur ist der Baustein für die Präsentation und für die Ausdrucke der Expertenprotokolle.
class BEO_Item : public CObject { public: string text; BEO_Level level; datetime time; ulong micro; string origin; BEO_Item() { text=""; level=BEO_L_INFO; time=0; micro=0; origin=""; } BEO_Item(string _text, BEO_Level _lvl, datetime _t, ulong _m, string _orig = "") { text=_text; level=_lvl; time=_t; micro=_m; origin=_orig; } void CopyFrom(const BEO_Item &src) { text=src.text; level=src.level; time=src.time; micro=src.micro; origin=src.origin; } };
Monitor-Kernzustand und Farbschema – warum undurchsichtige Farben und Volltontext?
Der Monitor verwaltet seinen eigenen CCanvas sowie Geometrie-, Sichtbarkeits-, Puffer- und Leistungszähler. Ich habe mich dafür entschieden, den Haupttext völlig undurchsichtig zu halten (einfarbig weiß) und verschiedene, undurchsichtige technische Farben für Überschriften, Hervorhebungen, Erfolgs-, Warn- und Fehlermeldungen zu verwenden. Das Ziel: vorhersehbare Lesbarkeit auf jedem Charthintergrund und konsistente Bedeutungszuordnung (z. B. m_error = rot). Diese Farben werden als Farbkomponenten gespeichert und beim Zeichnen von Linien angewendet. Das Speichern des Schriftnamens und einer geklammerten m_font_size schützt vor der Übergabe nicht unterstützter Werte an CCanvas::FontSizeSet() – deshalb berechnen wir einen sicheren CanvasFontSizeValue(), bevor wir die Canvas-API aufrufen.
// color and font members (excerpt) color m_text; // solid white color m_caption; // header/caption color color m_error; // error messages string m_font; int m_font_size; int m_transparent; // canvas transparency 0..255 // CanvasFontSizeValue() clamps m_font_size into safe range used by CCanvas::FontSizeSet
Lebenszyklus erstellen/wiederherstellen/zerstören mit sofort sichtbarem Platzhalter
Bei der Erstellung des Canvas wird sofort ein kleiner Platzhalter („BEO-Engine wird initialisiert...“) gezeichnet, sodass die Nutzer eine sofortige visuelle Rückmeldung erhalten, wenn der EA angehängt wird – dies ist für die Fehlersuche bei Anhänge-/Erstellungsproblemen sehr nützlich. CreateBitmapLabel() wird verwendet, um das Chart-Bitmap-Objekt zu erstellen, und anschließend wird mit FontNameSet()/FontSizeSet()/TransparentLevelSet() das Rendering konfiguriert. RecreateCanvas() zerstört die Leinwand sicher und erstellt sie neu, wenn sich Position oder Größe ändern. Destroy() bereinigt sowohl die Leinwand als auch den speicherinternen Nachrichtenpuffer; außerdem werden alle Ersatzkennzeichnungen entfernt, die von früheren Fehlern übrig geblieben sind. Diese Schritte spiegeln die Grundsätze guter Ressourcenverwaltung aus den MQL5-Dokumenten wider (Chartobjekte und Canvas-Ressourcen bei Bedarf erstellen/aktualisieren/zerstören, Lecks vermeiden).
bool CBEOMonitor::Create(string name,int x,int y,int w,int h) { m_res_name = StringFormat("BEOMON_%s", name); if(!m_canvas.CreateBitmapLabel(m_res_name, x, y, w, h, COLOR_FORMAT_ARGB_RAW)) return(false); m_canvas.FontNameSet(m_font); m_canvas.FontSizeSet(CanvasFontSizeValue()); // safe/clamped m_canvas.TransparentLevelSet((uchar)MathMax(0, MathMin(255, m_transparent))); // placeholder UI so chart shows something immediately m_canvas.Erase(m_bg); m_canvas.FillRectangle(2,2,w-4,24, ARGB(255,44,44,44)); m_canvas.TextOut(20,7,"BEO: " + name, m_caption, ALIGN_RIGHT); m_canvas.Update(true); return(true); }
Protokollierung, Buffer Trimming und Experten Output-Tracing sowohl auf dem Chart als auch in den Protokollen
Wenn der EA Log(...) (oder komfortable Wrapper wie Info()/Error()) aufruft, erstellt der Monitor ein BEO_Item, schiebt es in den CList-Puffer und gibt eine PrintFormat()-Meldung an das Expertenprotokoll aus, sodass dieselbe Meldung auf der Standardregisterkarte für Experten sichtbar ist. Der Puffer wird auf eine Kapazität getrimmt, um den Speicher zu begrenzen. Dieser doppelte Ansatz – auf der Zeichenfläche und beim Ausdrucken durch Experten – ermöglicht sowohl eine schnelle visuelle Diagnose als auch eine dauerhafte textliche Aufzeichnung im Terminalprotokoll.
void CBEOMonitor::Log(string text,BEO_Level lvl,string origin) { if(lvl==BEO_L_DEBUG && !m_show_debug) return; BEO_Item it; it.text=text; it.level=lvl; it.time=TimeCurrent(); it.micro=_nowMicros(); it.origin=origin; _pushItem(it); PrintFormat("BEO[%s] %s%s", (lvl==BEO_L_INFO?"INFO": "..."), (origin!=""?("["+origin+"] "):""), text); Update(); } void CBEOMonitor::_pushItem(const BEO_Item &it) { BEO_Item *p = new BEO_Item; p.CopyFrom(it); m_buf.Add(p); while(m_buf.Total() > m_capacity) { BEO_Item *old=(BEO_Item*)m_buf.GetNodeAtIndex(0); if(old) delete old; m_buf.Delete(0); } }
Leistungszeitmessung – Auflösung im Mikrosekundenbereich für nützliche Profilerstellung
Rufen Sie OnStartTick() zu Beginn der Tick-Verarbeitung und OnEndTick() am Ende auf; intern verwendet der Monitor GetMicrosecondCount() (bei MQL5) oder greift auf GetTickCount() multipliziert für eine grobe Auflösung zurück. Es speichert einen gleitenden Durchschnitt (m_tick_avg_ms) und einen Zähler, sodass die Anzeige im Chart zeigt, wie teuer die Tick-Verarbeitung ist. Diese schnelle Profilerstellung ist von unschätzbarem Wert, wenn es darum geht, Regressionen nach dem Hinzufügen neuer Funktionen zu verfolgen – wenn die Zeit des Ticks plötzlich größer geworden ist, zeigt der Monitor dies sofort an.
void CBEOMonitor::OnStartTick(void) { m_last_tick_start = _nowMicros(); } void CBEOMonitor::OnEndTick(void) { if(m_last_tick_start==0) return; ulong endm=_nowMicros(); double durms=(double)((endm>m_last_tick_start)?(endm-m_last_tick_start):0)/1000.0; m_tick_avg_ms=(m_tick_avg_ms*m_tick_count+durms)/(m_tick_count+1); m_tick_count++; m_last_tick_start=0; Update(); } ulong CBEOMonitor::_nowMicros(void) const { #ifdef __MQL5__ return (ulong)GetMicrosecondCount(); #else return (ulong)GetTickCount()*1000; #endif }
Zeichnen und Ausschneiden – lesbare, rechtsbündige Ausgabe, die nicht überläuft
_draw() setzt die Leinwand zusammen: Rahmen, Beschriftung, Perf-Zeile, EA-Backend-Zusammenfassung und Zeilen mit den letzten Nachrichten. Jede Textzeile wird mit _clipLineToWidth() beschnitten (wobei m_canvas.TextWidth() zur Messung der Pixel verwendet wird), um einen Überlauf oder unsichtbaren Text zu vermeiden. Alle TextOut()-Aufrufe verwenden wie gefordert ALIGN_RIGHT, und die Haupttextfarbe ist einfarbig weiß, während Beschriftungen und Hervorhebungen spezielle opake Farben verwenden. Nach dem Rendern überträgt m_canvas.Update(true) die Bitmap in das Chart, und BringToFrontInternal() stellt die Eigenschaften des Chartobjekts wieder her, damit das Canvas über anderen Objekten sichtbar bleibt. Dieser Ansatz sorgt dafür, dass die Diagnosen auf dem Chart über verschiedene Chartgrößen und Auflösungen hinweg konsistent und gut lesbar sind.
void CBEOMonitor::_draw(void) { if(!m_canvas_created) return; m_canvas.Erase(m_bg); m_canvas.Rectangle(1,1,m_w-2,m_h-2,m_border); m_canvas.FillRectangle(2,2,m_w-4,22, ARGB(255,44,44,44)); m_canvas.TextOut(20,6,"BEO: " + m_name, m_caption, ALIGN_RIGHT); // perf int y=28; string perf = StringFormat("TickAvg: %.2f ms | Ticks: %d | Mem: %d KB", m_tick_avg_ms, (int)m_tick_count, (int)m_mem_kb); m_canvas.TextOut(20,y, _clipLineToWidth(perf, MathMax(20,m_w-40)), m_text, ALIGN_RIGHT); y += 18; // messages (most recent first) for(int i=m_buf.Total()-1; i>=0 && drawn<max_lines; i--) { BEO_Item *it=_getItemAt(i); string line = _clipLineToWidth(TimeToString(it.time,TIME_MINUTES|TIME_SECONDS) + " " + it.text, avail_px); m_canvas.TextOut(20,y,line,_colorFor(it.level),ALIGN_RIGHT); y+=14; drawn++; } m_canvas.Update(true); BringToFrontInternal(); }
Schritt 2: Beispiel für die Integration des CBEOMonitors in einen eigenen Demo EA
EA-Kopfzeile und Einschlüsse
Ganz oben im EA befinden sich alle Kernbibliotheken, die sowohl für die Handelsausführung als auch für die Visualisierung im Chart unerlässlich sind. Dazu gehören Trade.mqh zur Verwaltung aller Handelsoperationen, Controls\Button.mqh zur Erstellung interaktiver Chart-Buttons und BEOMonitor.mqh, das ein robustes Überwachungssystem mit strukturierter Protokollierung und Diagnose bietet.
Unmittelbar danach deklarieren wir die Eingaben, damit jeder, der den EA anschließt, das Verhalten anpassen kann, ohne den Code zu ändern. Eingaben sind entwicklerdefinierte Standardwerte, die der EA bei OnInit() liest; sie ändern die Codelogik nicht. Achten Sie auf klare Bezeichnungen und sinnvolle Vorgaben. Bei der Verwendung von Pixel-/Positions-Inputs (MonitorW/MonitorH) ist zu beachten, dass der EA diese zur Laufzeit an beo.Create(...) übergibt und der Monitor sie zur Erstellung des Canvas-Objekts verwendet.
#include <Trade\Trade.mqh> #include <Controls\Button.mqh> #include <BEOMonitor.mqh> input string DemoEAName = "BEO Demo EA"; input bool EnableMonitor = true; input int MonitorX = 10; input int MonitorY = 60; input int MonitorW = 400; input int MonitorH = 220; input bool ShowDebugMessages = false; input int UpdateIntervalSec = 1; input bool AllowTrading = false; input double DemoLotSize = 0.01; input double DemoTakeProfit = 30; input double DemoStopLoss = 30;
Globale Objekte und Hilfsprogramme
Wir definieren globale Instanzen für den Handel (CTrade), die Überwachung (CBEOMonitor) und unsere interaktiven Schaltflächen (CButton). Diese Objekte verwalten ihren eigenen Lebenszyklus, werden aber im gesamten EA referenziert. Wir führen auch Hilfsfunktionen für die Erstellung von Ersatzkennzeichnungen ein. Diese Kennzeichnungen dienen als Sicherheitsmechanismus für den Fall, dass die Initialisierung des Monitor Canvas fehlschlägt. Sie geben sofortiges Feedback auf dem Bildschirm, sodass wir wissen, dass das System funktioniert, auch wenn der grafische Monitor nicht angezeigt werden kann.
CTrade trade; CBEOMonitor beo; CButton m_buyButton; CButton m_sellButton; static double g_prevBid = 0.0; static double g_prevAsk = 0.0; static datetime g_lastLogTime = 0; string MakeFallbackName(const string base) { return ("BEO_FALLBACK_" + base); }
Die Funktionen für die Ersatzkennzeichnungen (CreateFallbackLabel, UpdateFallbackLabel, RemoveFallbackLabel) ermöglichen es, Nachrichten im Chart dynamisch anzuzeigen oder zu aktualisieren, ohne den EA-Fluss zu unterbrechen. Sie behalten den Überblick über den Zustand des EA, wie z. B. „initializing“ oder „Canvas canvas failed“, was beim Testen und Debuggen von unschätzbarem Wert ist.
Chart-Diagnose
Um die Überwachung zu unterstützen, implementieren wir eine Diagnosefunktion, PrintChartObjects(). Diese Funktion durchläuft alle Chartobjekte und gibt deren Eigenschaften aus, einschließlich Name, Typ, Ecke, Position und Sichtbarkeit. Dies ist wichtig, um Ressourcenkonflikte zu beheben oder zu überprüfen, ob das BEO-Canvas korrekt erstellt wurde. Es spiegelt unser Prinzip der Transparenz wider: Zu wissen, was auf dem Chart vorhanden ist, verhindert Überraschungen zur Laufzeit und hilft bei der Reproduzierbarkeit von Tests.
void PrintChartObjects() { int total = ObjectsTotal(0); PrintFormat("BEO Diagnostic: ObjectsTotal = %d", total); for(int i=0;i<total;i++) { string nm = ObjectName(0,i); long type = ObjectGetInteger(0,nm,OBJPROP_TYPE); long corner = ObjectGetInteger(0,nm,OBJPROP_CORNER); long xdist = ObjectGetInteger(0,nm,OBJPROP_XDISTANCE); long ydist = ObjectGetInteger(0,nm,OBJPROP_YDISTANCE); bool hidden = (ObjectGetInteger(0,nm,OBJPROP_HIDDEN) != 0); PrintFormat(" [%d] name='%s' type=%d corner=%d x=%d y=%d hidden=%d", i, nm, (int)type, (int)corner, (int)xdist, (int)ydist, hidden ? 1 : 0); } }
Initialisierung (OnInit)
In der Funktion OnInit wird eine strukturierte Einrichtung sowohl für den Monitor als auch für die Schnellwahltasten vorgenommen. Wenn die Überwachung aktiviert ist, versucht das Programm, den CBEOMonitor-Canvas zu erstellen. Anschließend wird die Erstellung des Programms überprüft und bei Erfolg das Debugging aktiviert und eine Startmeldung protokolliert. Wenn die Erstellung einer Leinwand fehlschlägt, sorgt die Ersatzkennzeichnung dafür, dass die Rückmeldung auf der Chart erhalten bleibt.
Der EA erfasst auch die anfänglichen Geld- und Briefkurse und verwendet sie als Basis für die Verfolgung späterer Marktveränderungen. Anhand dieser Daten werden Schnellorder-Schaltflächen erstellt, die eine manuelle Handelssimulation oder -ausführung ermöglichen. Dieser Mechanismus bietet eine praktische Möglichkeit, die Handelslogik interaktiv zu validieren, anstatt sich ausschließlich auf automatische Auslöser zu verlassen. Um sicherzustellen, dass die Überwachungsanzeige immer auf dem neuesten Stand ist, stellt der EA außerdem einen Timer ein, der die Leinwand in regelmäßigen Abständen aktualisiert.
int OnInit() { if(EnableMonitor) { bool created = beo.Create(DemoEAName, MonitorX, MonitorY, MonitorW, MonitorH); if(created && beo.IsCanvasCreated()) { beo.EnableDebug(ShowDebugMessages); beo.Log("BEO engine initialized...", BEO_L_SUCCESS, "OnInit"); RemoveFallbackLabel(DemoEAName); } else { CreateFallbackLabel(DemoEAName, MonitorX, MonitorY, 12, clrSilver); } } g_prevBid = SymbolInfoDouble(_Symbol, SYMBOL_BID); g_prevAsk = SymbolInfoDouble(_Symbol, SYMBOL_ASK); if(EnableQuickButtons) { // Create BUY and SELL buttons... } EventSetTimer(MathMax(1, UpdateIntervalSec)); return(INIT_SUCCEEDED); }
Deinitialisierung (OnDeinit)
Beim Herunterfahren zerstört der EA die Monitorleinwand und die Schnelltasten und entfernt dabei auch alle Ersatzkennzeichnungen. Wenn Parameter geändert werden, wird die unnötige Protokollierung übersprungen, um nahtlose Aktualisierungen ohne Unterbrechung zu ermöglichen. Indem der EA seine Ressourcen auf diese Weise verwaltet, vermeidet er, dass das Chart mit ungenutzten Objekten vollgestopft wird oder Verweise zurückbleiben. Diese sorgfältige Bereinigung spiegelt die besten Praktiken im Lebenszyklusmanagement für automatisierte Handelssysteme wider.
void OnDeinit(const int reason) { if(EnableMonitor && reason != REASON_PARAMETERS) { beo.Log("Shutting down demo EA", BEO_L_INFO, "OnDeinit"); beo.ClearHistory(); beo.Destroy(); RemoveFallbackLabel(DemoEAName); } m_buyButton.Destroy(reason); m_sellButton.Destroy(reason); EventKillTimer(); }
Aktualisierungen des Timers (OnTimer)
Das Ereignis OnTimer verwaltet regelmäßige Aktualisierungen. Sie stellt sicher, dass die Monitorleinwand neu erstellt wird, falls sie fehlt, aktualisiert die Ersatzkennzeichnungen und die Monitoranzeige. Außerdem wird alle 30 Sekunden ein Heartbeat protokolliert, der Aufschluss über die Anzahl der Nachrichten, die Tickleistung und den Systemzustand gibt. Dieser regelmäßige Aktualisierungsmechanismus macht den EA robust gegenüber vorübergehenden Chart- oder Ressourcenproblemen.
void OnTimer() { if(!EnableMonitor) return; if(!beo.IsCanvasCreated()) { static int tries = 0; tries++; bool ok = beo.Create(DemoEAName, MonitorX, MonitorY, MonitorW, MonitorH); if(ok) { /* recovered canvas */ } else { string txt = StringFormat("BEO fallback: msgs=%d | TickAvg=%.3f ms", beo.MessagesCount(), beo.GetTickAvgMs()); UpdateFallbackLabel(DemoEAName, txt, MonitorX, MonitorY, 11, clrWhite); } } else RemoveFallbackLabel(DemoEAName); beo.Update(true); if(TimeCurrent() - g_lastLogTime >= 30) { string summary = StringFormat("Msgs:%d | TickAvg: %.3f ms | LastMicros: %llu", beo.MessagesCount(), beo.GetTickAvgMs(), beo.GetLastMicros()); beo.Log("Periodic heartbeat: " + summary, BEO_L_DEBUG, "OnTimer"); g_lastLogTime = TimeCurrent(); } }
Tick-Verarbeitung (OnTick)
Die Funktion OnTick ist der Kern der reaktiven Logik des EA. Bei jedem Markttick aktualisiert der EA den Monitor, verfolgt Geld- und Briefänderungen und protokolliert relevante Kursbewegungen. Eine einfache Demostrategie innerhalb des EA zeichnet signifikante Preisveränderungen auf und kann, wenn AllowTrading aktiviert ist, auch Handelsgeschäfte ausführen. Durch die Aufteilung der Logik in OnStartTick und OnEndTick behält der EA klare Grenzen für die Monitorinteraktionen bei, was die Modularität verstärkt und die Lesbarkeit verbessert.
void OnTick() { if(EnableMonitor) beo.OnStartTick(); double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); if(EnableMonitor && (bid != g_prevBid || ask != g_prevAsk)) { string txt = StringFormat("Bid: %.*f Ask: %.*f", (int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS), bid, (int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS), ask); beo.Info(txt, "OnTick"); g_prevBid = bid; g_prevAsk = ask; } // Simple demo strategy: log and optionally trade on price movement }
Die Schaltflächen für sofortige Aufträge (QuickOrder).
Das System verarbeitet Nutzerinteraktionen über OnChartEvent und ExecuteQuickOrder. Wenn Sie auf eine Schaltfläche klicken, wird entweder ein simulierter oder ein echter Handel ausgelöst, je nach dem Kennzeichen AllowTrading. Auf diese Weise können wir die Handelslogik sicher demonstrieren und gleichzeitig das System zur Überwachung des Backend-Betriebs vollständig integrieren, das detaillierte Protokolle und Handelsereignisse zur Überprüfung erfasst.
void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam) { if(id == CHARTEVENT_OBJECT_CLICK) { if(sparam == "BEO_BUY_BTN") ExecuteQuickOrder(ORDER_TYPE_BUY); else if(sparam == "BEO_SELL_BTN") ExecuteQuickOrder(ORDER_TYPE_SELL); } } void ExecuteQuickOrder(ENUM_ORDER_TYPE orderType) { if(!AllowTrading) { /* simulate */ return; } MqlTradeRequest req; MqlTradeResult res; ZeroMemory(req); ZeroMemory(res); if(orderType == ORDER_TYPE_BUY) { /* set buy parameters */ } else { /* set sell parameters */ } if(!OrderSend(req, res)) beo.LogErrorDetails(...); else beo.LogTradeDetails(res, ..., "QuickButton"); }
Dieser Ansatz demonstriert die vollständige Integration von CBEOMonitor; jede wichtige EA-Aktion – Initialisierung, Tick-Updates, Timer-Ereignisse, Handelsausführung und Schaltflächen-Interaktion – speist strukturierte Logs, erfasst Leistungsdaten und ermöglicht eine Ersatzanzeige, wenn die Leinwand des Monitors ausfällt. Das System ist modular, lesbar und robust und gewährleistet Übersichtlichkeit und Wartbarkeit sowohl für den Live-Handel als auch für Tests.
Tests
Um den Test auf dem Terminal durchzuführen, müssen sowohl der Expert Advisor als auch die Header-Datei, die die BEOMonitor-Klasse enthält, erfolgreich und ohne Fehler kompiliert worden sein. Unter der Rubrik Experten im MetaTrader 5-Terminalnavigator steht die BEODemoEA zur Verfügung. Ziehen Sie sie einfach auf das gewünschte Chart und lassen Sie sie mit den Standardeinstellungen initialisieren. Nach der Initialisierung erstellt das System automatisch die Monitor-Leinwand, richtet die Schnellorder-Schaltflächen ein und beginnt mit der Verarbeitung der eingehenden Tick-Daten.
Auf dem Chart werden die Ergebnisse der Codeausführung in Echtzeit sichtbar. Auf der Leinwand werden die Geld- und Briefkurse entsprechend den eingehenden Ticks aktualisiert, während Initialisierungsmeldungen bestätigen, dass der Monitor und die Schaltflächen erfolgreich erstellt wurden. Gleichzeitig liefern parallele Protokolle auf der Registerkarte Experten eine Backend-Bestätigung, die es ermöglicht, die Übereinstimmung der angezeigten Informationen mit den internen EA-Vorgängen zu überprüfen. Diese direkte Visualisierung stellt sicher, dass die Tests nicht nur funktional, sondern auch interaktiv sind und einen unmittelbaren Einblick in das Verhalten des Systems bei Live-Marktdaten geben.

Abbildung 1: Einsatz des EA im Chart

Abbildung 2: Darstellung der Backend-Interaktion mit Quick-Trade-Schaltflächen für den simulierten Handel
MetaTrader 5 Terminal Expertenprotokollierung:
2025.09.23 12:49:41.142 BEODemoEA (USDCHF,H1) BEOMonitor: Created canvas resource 'BEOMON_BEO Demo EA' at 10,60 size 600x220 2025.09.23 12:49:41.170 BEODemoEA (USDCHF,H1) BEO Demo: beo.Create returned true 2025.09.23 12:49:41.170 BEODemoEA (USDCHF,H1) BEO Demo: beo.IsCanvasCreated() = true 2025.09.23 12:49:41.170 BEODemoEA (USDCHF,H1) BEO Demo: expected canvas name = 'BEOMON_BEO Demo EA' 2025.09.23 12:49:41.178 BEODemoEA (USDCHF,H1) BEO Diagnostic: ObjectsTotal = 3 2025.09.23 12:49:41.179 BEODemoEA (USDCHF,H1) [0] name='BEOMON_BEO Demo EA' type=106 corner=0 x=10 y=60 hidden=0 2025.09.23 12:49:41.179 BEODemoEA (USDCHF,H1) [1] name='BEO_BUY_BTN' type=103 corner=0 x=10 y=300 hidden=1 2025.09.23 12:49:41.180 BEODemoEA (USDCHF,H1) [2] name='BEO_SELL_BTN' type=103 corner=0 x=100 y=300 hidden=1 2025.09.23 12:49:41.196 BEODemoEA (USDCHF,H1) BEO[OK] [OnInit] BEO engine initialized... 2025.09.23 12:49:41.228 BEODemoEA (USDCHF,H1) BEO[INFO] [OnInit] Quick Order Buttons (CButton) created: BUY/SELL for ops testing 2025.09.23 12:49:59.941 BEODemoEA (USDCHF,H1) BEO[INFO] [OnTick] Bid: 0.79537 Ask: 0.79551
Die obigen Diagnoseeinträge bestätigen, dass die Leinwand mit den vorgesehenen Koordinaten und Abmessungen initialisiert wurde und dass Validierungsprüfungen wie beo.Create und beo.IsCanvasCreated() den Wert true zurückgegeben haben. Dies zeigt, dass die Integration zwischen der nutzerdefinierten Monitorklasse und der Charting-Umgebung stabil ist. Außerdem wurde der erwartete Canvas-Name richtig zugeordnet, sodass eine korrekte Identifizierung der Ressource gewährleistet war. In der Diagnosezusammenfassung wurden auch die zugehörigen Objekte aufgezählt, einschließlich der ausgeblendeten Schaltflächen für die Schnellbestellung BUY und SELL, was zeigt, dass das System seine Hauptanzeigekomponente und die Hilfssteuerungen konsistent verwaltet.
Aus funktionaler Sicht zeigen die Initialisierungsprotokolle, dass die BEO-Engine zuverlässig in einen betriebsbereiten Zustand übergeht und dass die Schaltflächen für die Schnellbestellung wie vorgesehen generiert werden, auch wenn sie in dieser Phase nicht sichtbar sind. Der OnTick-Echtzeit-Feed bestätigt die Fähigkeit, Marktdaten über den Monitor zu erfassen und wiederzugeben, wobei Geld- und Briefkurse live in den Canvas-Bereich übertragen werden.
Dies bestätigt das Konzept. Wir können nun die Backend-Expert-Advisor-Aktivitäten in einer eigenen nutzerdefinierten Umgebung visualisieren, anstatt uns nur auf die Textprotokolle des Terminals zu verlassen. Die Grundlage ist zwar solide, aber künftige Verbesserungen sollten sich auf die Verfeinerung der Präsentationsebene, die Verbesserung der Interaktion mit den Quick-Order-Steuerungen und die Erweiterung des Umfangs des Diagnosefeedbacks auf komplexere EA-Vorgänge konzentrieren. Dies ist ein vielversprechender Anfang, der die Architektur validiert und eine solide Plattform für die iterative Entwicklung bietet.
Schlussfolgerung
Wir haben das BEO-Konzept erfolgreich zum Leben erweckt, wobei die Leinwand jetzt in anpassbaren Dimensionen gerendert wird und die Backend-Operationen des Expert Advisors dynamisch und in Echtzeit anzeigt. Auf dem Weg dorthin gab es einige Herausforderungen. Anfangs war die Sichtbarkeit des Textes schlecht, weil wir eine transparente Farbe gewählt hatten, die mit dem Hintergrund verschmolz; dies wurde später durch eine einfarbige, hellere Farbe korrigiert, um mehr Klarheit zu schaffen.
Auch die Ausrichtung erwies sich als schwierig – bei unseren ersten Versuchen schoss der Text über den linken Rand hinaus. Durch die Umstellung auf ALIGN_RIGHT haben wir eine saubere Darstellung erreicht, obwohl wir in Textverarbeitungsprogrammen üblicherweise eine linke Ausrichtung erwarten. Mit diesen Korrekturen wurde die Anzeige auf dem Chart sowohl funktional als auch visuell kohärent, und – was am wichtigsten ist – sie ist nicht statisch: Die Backend-Aktivität des EA wird Tick für Tick aktiv angezeigt.
Das Ergebnis bestätigt die Idee, aber es ist nur eine Grundlage. Wir haben ein zentrales Problem gelöst, indem wir dem EA einen eigenen, spezialisierten Protokollbereich zugewiesen haben, der von der überfüllten Registerkarte „Experten“ des Terminals getrennt ist, und gleichzeitig anerkannt haben, dass das Terminal eine bequeme Möglichkeit zum Kopieren von Protokollen zu Debugging-Zwecken bietet. Derzeit können wir wichtige Backend-Details direkt im Chart visualisieren, aber künftige Verfeinerungen könnten die Funktionalität erweitern, eine umfassendere Anpassung der Protokolldaten, erweiterte Filterung oder sogar interaktives Kopieren von Protokollen aus dem Canvas ermöglichen. Die Arbeit hier bildet eine solide Grundlage, aber es gibt noch Raum für Wachstum. In dieser Form zeigt das Projekt, was möglich ist, aber künftige Aktualisierungen könnten es noch viel weiter bringen.
Erforschen, experimentieren und erweitern Sie diese Idee in Ihren eigenen Projekten. Eine kurze Tabelle mit den wichtigsten Erkenntnissen und der beigefügte Code vervollständigen diese Diskussion – Ihre Kommentare und Beiträge werden dazu beitragen, die nächsten Schritte zu gestalten.
Wichtige Lektionen
| Lektion | Beschreibung: |
|---|---|
| Entwicklung nutzerdefinierter Klassen in MQL5 | Der Aufbau einer eigenen Klasse wie CBEOMonitor zeigt, wie komplexe Funktionalität in wiederverwendbare Module gekapselt werden kann, um die Wartbarkeit und Skalierbarkeit von Handelssystemen zu verbessern. |
| Integration von nutzerdefinierten Klassen und eingebauten MQL5-Bibliotheksklassen | Die Kombination von nutzerdefinierten Klassen mit Standard-Bibliothekskomponenten wie CTrade und CButton zeigt die Flexibilität von MQL5 bei der Verbindung von nutzerdefinierten Funktionen mit zuverlässigen integrierten Funktionen. |
| Canvas-Integration | Die Verwendung einer nutzerdefinierten Leinwand ermöglicht es Expert Advisors, Backend-Operationen visuell im Chart darzustellen und einen eigenen Bereich für die Überwachung zu schaffen, ohne vom Terminal-Log-Fenster abhängig zu sein. |
| Farb- und Sichtbarkeitsmanagement | Die Wahl geeigneter Volltonfarben anstelle von transparenten Farben ist für die Übersichtlichkeit von entscheidender Bedeutung, da so sichergestellt wird, dass Diagnosetext und Daten auch bei unterschiedlichen Charthintergründen sichtbar bleiben. |
| Textausrichtung | Die präzise Ausrichtung verhindert ein Überschießen oder eine Fehlplatzierung des angezeigten Textes. Wenn Sie verstehen, wie sich ALIGN_LEFT, ALIGN_RIGHT und Chartversätze verhalten, können Sie eine saubere Darstellung gewährleisten. |
| Ersatz-Mechanismen | Die Implementierung von Kennzeichnungen als Ersatz, wenn die Erstellung der Leinwand fehlschlägt, gewährleistet Robustheit. Dies bietet zumindest eine grundlegende Statusrückmeldung, auch wenn erweiterte Ressourcen nicht initialisiert werden können. |
| Diagnostik in Echtzeit | Durch die Aufzeichnung von Tick-Daten, Spread-Änderungen und Handelssignalen direkt im Chart schafft der Expert Advisor eine Live-Feedback-Schleife, die das Debugging und die Performance-Validierung erleichtert. |
Anlagen
| Dateiname | Version | Beschreibung |
|---|---|---|
| BEOMonitor.mqh | 1.00 | Hauptüberwachungsklasse, die die Canvas, Protokolle und visuellen Diagnosen der Expert Advisor Backend-Operationen verwaltet. Bietet wiederverwendbare Methoden zum Zeichnen, Protokollieren und zur strukturierten Ausgabe in einem Chart. |
| BEODemoEA.mq5 | 1.00 | Demonstration Expert Advisor mit Integration von CBEOMonitor, um Live-Protokollierung, Diagnose-Visualisierung und Quick-Order-Tests mit anpassbaren Steuerelementen zu präsentieren. |
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/19649
Warnung: Alle Rechte sind von MetaQuotes Ltd. vorbehalten. Kopieren oder Vervielfältigen untersagt.
Dieser Artikel wurde von einem Nutzer der Website verfasst und gibt dessen persönliche Meinung wieder. MetaQuotes Ltd übernimmt keine Verantwortung für die Richtigkeit der dargestellten Informationen oder für Folgen, die sich aus der Anwendung der beschriebenen Lösungen, Strategien oder Empfehlungen ergeben.
Klassische Strategien neu interpretiert (Teil 16): Doppelte Ausbrüche aus den Bollinger Bänder
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 85): Verwendung von Mustern des Stochastik-Oszillators und der FrAMA mit Beta-VAE-Inferenzlernen
Einführung in MQL5 (Teil 22): Aufbau eines Expert Advisors für das harmonische Muster 5-0
Dynamic Swing Architecture: Marktstrukturerkennung von Umkehrpunkten (Swings) bis zur automatisierten Ausführung
- 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.