Der MQL5-Standardbibliotheks-Explorer (Teil 7): Interaktive Positionskennzeichnung mit CCanvas
Inhalt:
Einführung
Willkommen zu diesem Teil der Reihe, in der wir die MQL5-Standardbibliothek näher betrachten. Ich hoffe, dass jede Folge Ihnen im Laufe der Zeit etwas Nützliches oder Inspirierendes geboten hat. Mit zunehmender Erfahrung wird Ihnen schnell klar, dass die MQL5-Programmierung eine Reise ist, die aus unzähligen Bausteinen besteht – es gibt immer etwas Neues zu lernen, zu verfeinern und zu entdecken. Letztendlich dienen all diese Bemühungen einem einzigen Ziel: Tradern effiziente, zuverlässige und gut durchdachte Trading-Tools an die Hand zu geben.
In diesem Abschnitt gehen wir auf eine häufige Lücke in der Bedienbarkeit zwischen dem Chartfenster und der Registerkarte „Handel“ im Fenster „Werkzeuge“ des MetaTrader 5 ein. Positionen werden in der Regel über die „Werkzeuge“ verwaltet, wo sie oft zusammen mit anderen Orders und Geschäften angezeigt werden, was es erschwert, sich in Echtzeit auf eine bestimmte Position zu konzentrieren. Um dieses Problem zu lösen, führen wir die Positionskennzeichnung direkt im Chart ein. Indem Sie jede offene Position mit einer visuellen Kennzeichnung verknüpfen, die direkt im Chart platziert wird, können Sie eine Position sofort mit der aktuellen Kursbewegung und Marktstruktur in Beziehung setzen. Dies sorgt für mehr Übersichtlichkeit, beschleunigt die Entscheidungsfindung und ermöglicht es Ihnen, anhand der aktuellen Marktbedingungen zu entscheiden, ob eine Position geschlossen oder gehalten werden sollte.
Dieser Artikel knüpft an die vorangegangene Diskussion zur Optimierung von mit dem Assistenten erstellten Expert Advisors an, wobei der Schwerpunkt bewusst verlagert wurde. Anstatt uns zum jetzigen Zeitpunkt eingehender mit der Optimierung zu befassen, nehmen wir etwas Abstand und kehren zur Einfachheit zurück, um den Lernerfolg zu festigen. Die Teile 4, 5 und 6 bildeten die Grundlage für die Arbeit mit dem Wizard und den verfügbaren Modulen und boten einen praktischen Einstieg in die Erstellung von Expert Advisors mit minimalem Programmieraufwand. Auch wenn das Thema Optimierung natürlich viele Fragen aufwirft – und nach wie vor von großer Bedeutung ist –, ist es doch so umfangreich, dass es später in dieser Reihe eine eigene Behandlung verdient, in der wir uns eingehender damit befassen werden.
Im nächsten Abschnitt konzentrieren wir uns darauf, das Kernkonzept der heutigen Diskussion zu verstehen, bevor wir zur Umsetzung übergehen. Diese konzeptionelle Ebene ist der wichtigste Teil des Artikels, da sie verdeutlicht, wie die Lösung funktioniert und warum sie von Bedeutung ist. Bitte nehmen Sie sich die Zeit, den Inhalt gründlich zu verinnerlichen, bevor Sie mit dem Abschnitt zur Umsetzung fortfahren.
Konzept
In MetaTrader 5 werden Positionen in der Regel über die Registerkarte „Handel“ im Fenster „Werkzeuge“ verwaltet. Da die Zahl der offenen Positionen und ausstehenden Orders zunimmt, kann dieser listenbasierte Ansatz schnell unübersichtlich und weniger intuitiv werden. Noch wichtiger ist jedoch, dass wichtige Kontextinformationen – wie beispielsweise die Marktstruktur und das Preisverhalten zum Zeitpunkt des Markteintritts – visuell nicht mit der Position selbst verknüpft sind.
Zwar bietet MetaTrader 5 bereits einige grundlegende Funktionen zur Positionsverwaltung direkt im Chart, doch sind diese im Umfang begrenzt. Wie in der folgenden Abbildung dargestellt, können Sie Einstiegskurse, Ordertyp, Lotgröße und Orderpreis direkt im Chart einsehen.

Abb. 1. Standardmäßige Positionsverwaltung im Chart
In Abb. 1. zeigt das Chart den Einstiegskurs der Position sowie deren Art und Volumen an, während der Kurs auf der rechten Achse in Echtzeit aktualisiert wird. Allerdings fehlt ein wesentliches Element: eine übersichtliche, dynamische Darstellung der Gewinne und Verluste auf Positionsebene. Zudem bieten die standardmäßigen Chart-Elemente nur wenig Flexibilität bei der Gestaltung und keine direkte, intuitive Möglichkeit, eine Position schnell direkt über das Chart selbst zu schließen. Zwar ist das Schließen von Trades über das Kontextmenü der rechten Maustaste und die Registerkarte „Handel“ möglich, doch konzentrieren wir uns hier darauf, was das Chart selbst leisten kann.
Diese Einschränkungen zeigen einen Verbesserungsbedarf auf – einen, der mithilfe der MQL5-Standardbibliothek behoben werden kann. Indem wir das Chart um benutzerdefinierte, interaktive visuelle Elemente erweitern, können wir die Lücke zwischen Handelsdaten und Kursentwicklung schließen. Im nächsten Abschnitt stellen wir eine konzeptionelle Lösung vor, die Positionsinformationen, Echtzeit-Feedback zu Gewinn und Verlust sowie einen direkten Zugriff zum schnellen Schließen der Order zusammenführt. Obwohl diese Funktion auf der Registerkarte „Handel“ verfügbar ist, konzentrieren wir uns vorerst darauf, was das Chart zu bieten hat. Im Folgenden stelle ich unsere konzeptionelle Lösung für dieses Problem vor.

Abb. 2. Info zur konzeptionellen schwebenden Informationsblase für Positionen
In Abb. 2. veranschaulichen wir das Verfahren zur Positionskennzeichnung mithilfe grafischer Sprechblasen, um zu zeigen, wie Order-Tickets und Echtzeit-Gewinne oder -Verluste direkt im Chart dargestellt werden können. Anstatt sich ausschließlich auf die Registerkarte „Handel“ zu verlassen, werden Positionen als interaktive Blasen dargestellt, die an den jeweiligen Kurs und Zeitpunkt gekoppelt sind, sodass Sie die Marktstruktur und die Handelsperformance auf einen Blick einschätzen können.
Dieses konzeptionelle Design verlagert die Positionsverwaltung von einer separaten Liste in den Handelskontext selbst. Indem wir jede Position visuell mit ihrem Einstiegspunkt verknüpfen, erhalten wir einen unmittelbaren Einblick in das Kursverhalten im Verhältnis zum Trade, wodurch die Bewertung und Entscheidungsfindung schneller und intuitiver werden.
Das System ist in drei übergeordnete Ebenen gegliedert. Die strategische Logikebene legt fest, wann und wie Positionen eröffnet werden. Die Visualisierungsebene ist dafür zuständig, Positionsinformationen mithilfe übersichtlicher, aussagekräftiger Grafiken im Chart darzustellen. Schließlich ermöglicht die Interaktionsschicht direkte Benutzereingaben, sodass Sie Positionen durch einfache Mausaktionen verwalten können.
Zusammen verdeutlichen diese Ebenen, wie Handelslogik, Chartdarstellung und Benutzerinteraktion mithilfe der MQL5-Standardbibliothek nahtlos aufeinander abgestimmt werden können und damit die Grundlage für fortschrittlichere und intuitivere Handelstools in zukünftigen Implementierungen bilden.
Behandelte Komponenten der Standardbibliothek
Wenn Sie dieser Erläuterung folgen, werden Sie mit einigen wichtigen Dateien der MQL5-Standardbibliothek und deren Funktionen im Projekt vertraut:
- Canvas – zum Erstellen eigener Grafiken, zum Zeichnen von Formen, Text und interaktiven Elementen
- PositionInfo – zum Abrufen von Echtzeit-Positionsdaten wie Ticketnummer, Eröffnungskurs und Gewinn
- Trade – zur programmgesteuerten Ausführung und zum Abschluss von Handelsgeschäften
- Trend – zur Erstellung und Nutzung von Indikatoren für gleitende Durchschnitte als Teil der Strategie
Weitere Einzelheiten zur Verwendung und Kombination dieser einzelnen Module werden im Abschnitt zur Implementierung behandelt, in dem der vollständige Code diese Konzepte veranschaulicht.
Umsetzung
In diesem Abschnitt gehen wir vom Konzept zur Umsetzung über. Das Ziel besteht nicht darin, eine ausgefeilte Handelsstrategie zu entwickeln, sondern darin, zu zeigen, wie sich verschiedene Komponenten der MQL5-Standardbibliothek zu einem schlüssigen, interaktiven System kombinieren lassen.
Behalten Sie während dieser Anleitung im Hinterkopf, dass jede Klasse, die wir hier verwenden, auch weit über dieses Projekt hinaus wiederverwendbar ist. Der Interactive Position Labeler ist hier schlicht das Mittel, mit dem wir diese Komponenten in diesem Kontext auf praktische, visuelle und intuitive Weise erkunden können.
In jedem MQL5-Programm stößt der Compiler als Erstes auf Metadaten und nicht auf Funktionscode. In diesem Header-Teil wird definiert, was das Programm ist, nicht was es tut. Eigenschaften wie der Dateiname, das Banner, das Copyright, die Version und die Beschreibung dienen der formellen Identifizierung. Sie werden von MetaTrader verwendet, um Informationen im Navigator, im Strategietester und in den Protokollen anzuzeigen.
//+------------------------------------------------------------------+ //| Part7_InteractivePositionLabeler.mq5| //| Copyright 2025, MQL5 Standard Lib Explorer| //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Clemence Benjamin" #property version "1.00" #property description "Interactive Position Info Bubbles with MA Cross Strategy"
Erst nach diesem Metadatenblock beginnen wir damit, die Bausteine des Programms zusammenzusetzen, indem wir Dateien aus der Standardbibliothek einbinden. Diese Reihenfolge ist nicht nur stilistischer Natur, sondern spiegelt auch ein klares Denkmodell wider: Zunächst definieren wir, was das Programm ist, und entscheiden dann, welche Funktionen es benötigt. Die #include-Anweisungen binden vorgefertigte Klassen ein, die sich im Stammverzeichnis der MQL5-Installation befinden – dem Ordner MQL5\Include\. Es ist äußerst wichtig, diesen Stammordner zu kennen, da fast alle Komponenten der Standardbibliothek von dort aus in übersichtliche Unterordner wie Trade, Canvas, Indicators, Controls und viele weitere verzweigen.
1. Einbinden der Standardbibliothek:
Zunächst stellen wir die Werkzeuge wie im folgenden Code gezeigt zusammen. Anstatt Rohcode zum Zeichnen von Pixeln oder zum Ausführen von Handelsgeschäften zu schreiben, importieren wir spezielle Klassen aus der Standardbibliothek.
//--- 1. INCLUDES #include <Canvas\Canvas.mqh> // For drawing custom graphics #include <Trade\PositionInfo.mqh> // For reading trade details #include <Trade\Trade.mqh> // For executing trades #include <Indicators\Trend.mqh> // For Moving Averages
Diese vier Kopfzeilen definieren den gesamten Geltungsbereich der Anwendung. Jede davon steht für einen bestimmten Bereich, der von der Standardbibliothek abgedeckt wird:
| Bibliotheksdatei | Beschreibung |
|---|---|
| Canvas: | Stellt die Klasse CCanvas für das Zeichnen auf Pixelebene direkt im Chart bereit. Dies ist die zentrale Grafik-Engine des Projekts und sie ermöglicht benutzerdefinierte Formen, Transparenz, Textdarstellung sowie interaktive Überlagerungen, die über die Standard-Chartelemente hinausgehen. |
| PositionInfo: | Stellt die Klasse CPositionInfo bereit, die als zustandsbehafteter Wrapper für offene Positionen dient. Anstatt immer wieder einzelne Positionseigenschaften abzufragen, wählt das System eine Position einmal aus und arbeitet mit dieser als Objekt. |
| Trade: | Enthält die Klasse CTrade, eine übergeordnete Schnittstelle zur Ausführung und Verwaltung von Handelsgeschäften. Es abstrahiert Auftragstickets, Ausführungsergebnisse und die Fehlerbehandlung, sodass die Strategielogik übersichtlich und gut lesbar bleibt. |
| Trend: | Beherbergt Indikator-Klassen wie beispielsweise CiMA. Diese Klassen vereinen die Indikatorverarbeitung unter einer einheitlichen API (Create → Refresh → Main), wodurch sich Indikatoren leicht erweitern oder ersetzen lassen, ohne den Strategiecode umstrukturieren zu müssen. |
Bereits an dieser Stelle wird ein zentraler Gedanke der Standardbibliothek deutlich: Jede Klasse löst ein bestimmtes Problem und lässt sich nahtlos in andere integrieren.
2. Eingaben und globale Variablen: Die Bibliothek soll die Hauptarbeit übernehmen
Wir definieren eine Enumeration, mit der wir zwischen verschiedenen Blasenformen wechseln können. Indem wir Formen in eine Enumeration abstrahieren, vermeiden wir eine fest codierte Layout-Logik und machen das Rendering-System erweiterbar.
Anschließend deklarieren wir die Eingabeparameter und trennen dabei die Strategiekonfiguration von der visuellen Konfiguration. Diese Trennung stellt sicher, dass visuelle Experimente die Handelslogik nicht beeinträchtigen.
//--- 2. INPUTS enum EnumBubbleShape { SHAPE_ROUNDED_RECT, SHAPE_CIRCLE, SHAPE_TRIANGLE }; input group "Strategy Settings" input int InpFastMA = 10; // Fast MA Period input int InpSlowMA = 20; // Slow MA Period input int InpSL = 300; // Stop Loss (Points) input int InpTP = 600; // Take Profit (Points) input group "Visual Settings" input EnumBubbleShape InpShape = SHAPE_TRIANGLE; // Default to test layout logic //--- 3. GLOBAL OBJECTS CCanvas ExtCanvas; // The drawing canvas CPositionInfo ExtPosition; // Position reader CTrade ExtTrade; // Execution module CiMA ExtFastMA; // Fast Moving Average CiMA ExtSlowMA; // Slow Moving Average
Anstatt gleitende Durchschnitte manuell zu berechnen, überlassen wir die Zwischenspeicherung und Neuberechnung den CiMA-Objekten. Diese Objekte werden global deklariert, da sie persistente Systemkomponenten darstellen:
- CTrade verwaltet den Ausführungskontext (wie z. B. Magische Zahlen).
- CPositionInfo fungiert als verschiebbarer Cursor über den Positionen.
- CCanvas stellt eine langlebige Zeichenfläche dar (würde man sie bei jedem Tick neu erstellen, würde dies die Leistung stark beeinträchtigen).
3. Die Struktur der Hitbox: Interaktion ermöglichen
Da das Canvas keine nativen Schaltflächen kennt, definieren wir unsere eigene Hitbox-Struktur. Auf diese Weise können wir die Pixelkoordinaten den Ticketnummern der Trades/Positionen zuordnen
Jedes Mal, wenn wir eine Schaltfläche zum Schließen zeichnen, registrieren wir deren anklickbaren Bereich. Später werden wir Mausklicks anhand dieser Grenzen auswerten.
//--- HITBOX STRUCTURE (For Mouse Clicks) struct BubbleHitbox { ulong ticket; int x1, y1, x2, y2; }; BubbleHitbox ExtHitboxes[]; // Dynamic array to store clickable areas
Mit dieser einfachen Struktur können wir ein visuelles Rechteck (Koordinaten x1.y1 bis x2.y2) einem bestimmten Handelsticket zuordnen. Dieses Muster – die Trennung der visuellen Darstellung vom Logikbereich – lässt sich für Schaltflächen, Schieberegler oder jedes andere benutzerdefinierte Steuerelement, das Sie in Zukunft entwickeln, wiederverwenden.
4. Initialisierung: Vorbereitung der Komponenten
Beim Start des Expert Advisors fungiert die Funktion OnInit() als Startsequenz für das gesamte System. Alles innerhalb dieser Funktion wird nur einmal ausgeführt, und ihre Aufgabe besteht darin, sicherzustellen, dass alle erforderlichen Komponenten erfolgreich erstellt wurden, bevor der EA den Betrieb aufnehmen darf. Sollte in dieser Phase ein kritisches Teilsystem ausfallen, wird die Funktion vorzeitig beendet, und die EA gelangt nie in ihren Laufzustand.
int OnInit() {
Der erste Schritt initialisiert den Indikator für den schnellen gleitenden Durchschnitt. Zu diesem Zeitpunkt werden noch keine Werte berechnet; stattdessen fordert das Programm MetaTrader 5 auf, einen Indikator-Handle zuzuweisen und diesen an das aktuelle Symbol und den aktuellen Zeitrahmen zu binden. Der Indikator ist als einfacher gleitender Durchschnitt der Schlusskurse konfiguriert. Sollte die Plattform aus irgendeinem Grund den Indikator nicht erstellen können, wird die Initialisierung sofort abgebrochen, um ein undefiniertes Verhalten der Strategie zu verhindern.
if(!ExtFastMA.Create(_Symbol, _Period, InpFastMA, 0, MODE_SMA, PRICE_CLOSE)) return(INIT_FAILED);
Unmittelbar danach wird der langsame gleitende Durchschnitt auf dieselbe Weise erstellt/initialisiert. Indem wir diesen Schritt während der Initialisierung durchführen, stellen wir sicher, dass beide Indikatoren vorhanden sind und später während der Live-Ausführung aktualisiert werden können. Genau wie beim schnellen Durchschnitt führt ein Fehler hier dazu, dass der EA gestoppt wird, bevor er in einem unvollständigen Zustand weiterlaufen kann.
if(!ExtSlowMA.Create(_Symbol, _Period, InpSlowMA, 0, MODE_SMA, PRICE_CLOSE)) return(INIT_FAILED);
Sobald die Strategieindikatoren eingerichtet sind, wird das Chart so konfiguriert, dass mausbezogene Ereignisse an den EA weitergeleitet werden. Dadurch kann das Programm über den OnChartEvent()-Handler detaillierte Daten zu Benutzerinteraktionen wie Mausbewegungen und Klicks empfangen. Dieser Schritt ist für jede auf einer Canvas-Oberfläche basierende interaktive Chartschnittstelle unerlässlich, da er es grafischen Elementen ermöglicht, auf Benutzereingaben zu reagieren.
ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true);
Der nächste Block erstellt die Zeichenfläche (Canvas), auf der alle visuellen Elemente angezeigt werden. Eine Bitmap-Beschriftung wird zugewiesen und in der oberen linken Ecke des Charts positioniert, wobei ihre Breite und Höhe genau an die Pixelabmessungen des Charts angepasst werden. Diese Bitmap dient als Off-Screen-Rendering-Fläche, wodurch wir Formen, Text und UI-Komponenten effizient zeichnen können. Das ARGB-Farbformat ermöglicht Transparenz und sorgt dafür, dass sich die Grafiken nahtlos in den Hintergrund des Charts einfügen. Wenn die Bitmap nicht erstellt werden kann, schlägt die Initialisierung fehl, da das EA für seine interaktive Darstellung auf diese Zeichenfläche angewiesen ist.
if(!ExtCanvas.CreateBitmapLabel("TradeBubblesCanvas", 0, 0, (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS), (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS), COLOR_FORMAT_ARGB_NORMALIZE)) return(INIT_FAILED);
Nachdem die Zeichenfläche erfolgreich erstellt wurde, wird die Standardschriftart konfiguriert, die für die Darstellung aller Texte verwendet wird. Wenn die Schriftart einmalig bei der Initialisierung festgelegt wird, werden bei jedem nachfolgenden Text-Draw-Aufruf automatisch dieselbe Schriftart und dieselbe Schriftgröße verwendet. Dieser Ansatz verbessert die Leistung und gewährleistet eine einheitliche Darstellung aller gerenderten Elemente.
ExtCanvas.FontSet("Calibri", 16);
Schließlich meldet die Funktion, dass die Initialisierung erfolgreich verlaufen ist. Zu diesem Zeitpunkt sind alle erforderlichen Systeme – Indikatoren, Chart-Ereignisse und die Darstellungsfläche – vollständig vorbereitet. Durch die Rückgabe von INIT_SUCCEEDED kann MetaTrader den EA in den aktiven Zustand versetzen, in dem er mit dem Empfang von Ticks und Chart-Ereignissen beginnen kann.
return(INIT_SUCCEEDED); }
Beachten Sie das Flag COLOR_FORMAT_ARGB_NORMALIZE bei der Erstellung der Zeichenfläche. Dies ist von entscheidender Bedeutung. Dadurch wird die Standardbibliothek angewiesen, den Alphakanal (Transparenz) zu unterstützen. Ohne diese Einstellung wäre unsere Ebene komplett schwarz und würde das Kurschart vollständig verdecken.
5. OnTick(): Strategie und Visualisierung voneinander trennen
Sobald ein neuer Markt-Tick eintrifft, führt der EA die Funktion OnTick() aus, die alle nachfolgenden Aktionen koordiniert. Diese Funktion ist dafür zuständig, die Handelsstrategie auszuwerten und visuelle Aktualisierungen effizient zu verwalten. In diesem Prozess überwacht der EA kontinuierlich die Marktbedingungen, überprüft bestehende Positionen und entscheidet, ob er auf dem Chart zeichnet oder Trades ausführt.
Zu Beginn jedes Ticks aktualisiert der EA seine Indikatoren für den gleitenden Durchschnitt, um sicherzustellen, dass er mit den aktuellsten Marktdaten arbeitet. Diese sofortige Aktualisierung gewährleistet, dass alle nachfolgenden Preis- oder Crossover-Auswertungen auf aktuellen Werten und nicht auf veralteten Informationen basieren.
Anschließend prüft der EA, ob offene Positionen bestehen. Werden keine gefunden, wird geprüft, ob ein neues Geschäft eingegangen werden sollte. Dies wird intern durch den Aufruf von PositionsTotal() geregelt, um die Ein-Position-Regel durchzusetzen – wodurch sich überschneidende Positionen verhindert und das Risiko kontrolliert wird.
Der EA überprüft zudem seine Ausführungsumgebung, bevor er etwas zeichnet. Wenn die Strategie im Strategietester ausgeführt wird, ohne dass der visuelle Modus aktiviert ist, wird die Darstellung gänzlich übersprungen, um Ressourcen zu sparen.
Für visuelle Aktualisierungen nutzt die EA einen internen Timer, um die Bildrate zu regulieren. Bei jedem Tick vergleicht er die aktuelle Systemzeit mit dem Zeitstempel der letzten Bildaktualisierung. Eine neue Zeichenroutine wird erst nach einem festgelegten Intervall ausgelöst, wodurch ein Gleichgewicht zwischen flüssiger Darstellung und Leistung gewährleistet wird – in der Regel bei etwa 30 Bildern pro Sekunde.
//+------------------------------------------------------------------+ //| Expert tick function (SPEED OPTIMIZED) | //+------------------------------------------------------------------+ void OnTick() { // --- PRIORITY 1: STRATEGY (Always Run) --- // We never skip this. The EA must react to every price change instantly. ExtFastMA.Refresh(-1); ExtSlowMA.Refresh(-1); if(PositionsTotal() == 0) { CheckStrategy(); } // --- PRIORITY 2: VISUALS (Throttled) --- // Optimization A: If running a backtest WITHOUT visual mode, skip drawing completely. if(MQLInfoInteger(MQL_TESTER) && !MQLInfoInteger(MQL_VISUAL_MODE)) return; // Optimization B: Frame Rate Limiter (Max 30 FPS) static uint last_render_time = 0; uint current_pc_time = GetTickCount(); if(current_pc_time - last_render_time > 30) { DrawBubbles(); last_render_time = current_pc_time; } }
Indem wir die Darstellung mithilfe von GetTickCount() auf etwa 30 Bilder pro Sekunde drosseln, ermöglichen wir es, dass die Handelslogik mit maximaler Geschwindigkeit läuft, während die CPU-Auslastung niedrig bleibt. Dieses Muster lässt sich auf jedes Dashboard oder jede Übersicht übertragen, die Sie erstellen.
6. Strategische Logik: Verwendung von Indikator-Klassen
Die Strategie selbst ist einfach und dient lediglich dazu, Positionen zu generieren, die wir visualisieren können.
void CheckStrategy() { // Request indicator values through the library API double fast0 = ExtFastMA.Main(0); double fast1 = ExtFastMA.Main(1); double slow0 = ExtSlowMA.Main(0); double slow1 = ExtSlowMA.Main(1); // ... (Symbol Info & Trade Logic) ... // Example: Golden Cross if(fast1 < slow1 && fast0 > slow0) { double sl = ask - (InpSL * point); double tp = ask + (InpTP * point); // Clean execution using CTrade ExtTrade.Buy(0.10, _Symbol, ask, sl, tp, "MA_Cross_Buy"); } // ... (Sell Logic Symmetrical) ... }
Wir verwenden ExtFastMA.Main(index), um sauber auf die Pufferwerte zuzugreifen. Diese Abstraktion verhindert die bei direkt verwendeten Arrays häufig auftretenden Fehler vom Typ Array außerhalb des zulässigen Bereichs.
7. Zeichnungsebene: Von Marktdaten zu Bildschirmpixeln
Diese Funktion schlägt eine Brücke zwischen Handelsdaten (Zeit/Preis) und der Visualisierung (X/Y-Pixel).
void DrawSingleBubble() { // ... (Get Position Data) ... int x, y; // Convert Market Info to Screen Pixels // This function aligns graphics with candles during scrolling if(!ChartTimePriceToXY(0, 0, time, open_price, x, y)) return; // ... (Color and Shape Logic) ... // Example: Drawing the Text ExtCanvas.TextOut(text_x_final, text_y_final, text, text_color, text_align_final); // Example: Registering the Hitbox for the "X" button int new_idx = ArraySize(ExtHitboxes); ArrayResize(ExtHitboxes, new_idx + 1); ExtHitboxes[new_idx].ticket = ticket; ExtHitboxes[new_idx].x1 = btn_x1_final; // ... (Save coordinates) ... }
Die Funktion ChartTimePriceToXY ist von entscheidender Bedeutung. Sie wandelt den Eröffnungskurs des Handels in Pixelkoordinaten um. Nach der Konvertierung übernimmt die CCanvas-API das Zeichnen von Formen, das Mischen von Farben und das Rendern von Text. Beachten Sie, dass wir die Position der Schaltfläche bereits beim Zeichnen in ExtHitboxes speichern.
8. Interaktionsschicht: Grafiken anklickbar machen
Zum Schluss verknüpfen wir die Benutzereingaben mit den Bibliotheksaktionen.
//+------------------------------------------------------------------+ //| Chart Event Handler (Clicks & Scrolls) | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { // Handle Resizing/Scrolling if(id == CHARTEVENT_CHART_CHANGE) { ExtNeedResize = true; DrawBubbles(); } // Handle Clicks if(id == CHARTEVENT_CLICK) { int mouse_x = (int)lparam; int mouse_y = (int)dparam; for(int i = 0; i < ArraySize(ExtHitboxes); i++) { // Check if click is inside a button's hitbox if(mouse_x >= ExtHitboxes[i].x1 && mouse_x <= ExtHitboxes[i].x2 && mouse_y >= ExtHitboxes[i].y1 && mouse_y <= ExtHitboxes[i].y2) { Print("Interactive Close: Ticket #", ExtHitboxes[i].ticket); // Use Standard Library to close the specific ticket ExtTrade.PositionClose(ExtHitboxes[i].ticket); DrawBubbles(); return; } } } }
Durch die Behandlung von CHARTEVENT_CLICK schließen wir den Kreis:
- Benutzereingabe: Klick erkannt.
- Visuelle Logik: Überprüfen Sie ExtHitboxes, um festzustellen, ob eine Schaltfläche gedrückt wurde.
- Handelsausführung: Verwenden Sie ExtTrade.PositionClose, um den Befehl auszuführen.
Dieses Interaktionsmodell verwandelt ein statisches Chart in ein dynamisches Handelsinstrument.
Tests und Ergebnisse
Nachdem wir das System nun aufgebaut haben, ist es an der Zeit, es in Aktion zu sehen. Öffnen Sie den Strategietester in MetaTrader 5 und wählen Sie Part7_InteractivePositionLabeler.ex5 aus. Stellen Sie sicher, dass der visuelle Modus mit eingeblendeten Charts aktiviert ist, bevor Sie auf Start klicken.
Da diese Funktion auf der Echtzeit-Darstellung von Charts und der Interaktion mit der Maus basiert, muss die Optimierung während des Testens deaktiviert werden. Verwenden Sie im Strategietester stets einen einzelnen visuellen Durchlauf, wenn Sie interaktive Komponenten wie Canvas-basierte Beschriftungen und Schaltflächen validieren.
Da der Expert Advisor die Strategie des gleitenden Durchschnitts-Crossovers umsetzt, werden neben jeder neuen Position sofort benutzerdefinierte Bezeichnungen angezeigt. Diese Etiketten aktualisieren ihre Gewinnwerte und Farben in Echtzeit, sobald sich die Preise ändern.
Um die Interaktivität in einem Live-Chart zu testen, bewegen Sie den Mauszeiger einfach über die rote X-Schaltfläche auf einer beliebigen Beschriftung und klicken Sie darauf. Der entsprechende Trade wird sofort geschlossen, und die Markierung verschwindet aus dem Chart.
Sehen Sie sich die folgenden Screenshots an, um meine Testergebnisse in Aktion zu sehen.

Abb. 3. Testen anhand eines Live-Charts

Abb. 4. Testen in der Visualisierung des Strategietesters
Der vollständige, kompilierbare Quellcode für dieses Projekt ist am Ende dieses Artikels beigefügt. Laden Sie ihn herunter, kompilieren Sie ihn und entdecken Sie die Leistungsfähigkeit der MQL5-Standardbibliothek.
Schlussfolgerung
In diesem Teil der Reihe MQL5 Standard Library Explorer haben wir erfolgreich einen interaktiven EA zur Positionskennzeichnung erstellt, der Strategielogik mit dynamischer Chartvisualisierung verbindet. Wir haben globale Objekte für Indikatoren, die Zeichenfläche und das Handelsmanagement definiert und initialisiert und dabei gelernt, wie man über CPositionInfo auf offene Positionen als Objekte zugreift, mit CTrade effizient Handelsgeschäfte ausführt und mithilfe von CiMA aus der Trend-Bibliothek gleitende Durchschnitte berechnet. Gleichzeitig haben wir uns mit CCanvas für das Zeichnen auf Pixelebene beschäftigt und interaktive Blasen erstellt, die Positionsinformationen anzeigen und direkt auf Klicks im Chart reagieren.
Im Rahmen dieses Projekts haben wir Erfahrungen darüber ausgetauscht, wie die MQL5-Standardbibliothek eine einheitliche Schnittstelle auf höherer Abstraktionsebene für verschiedene Aspekte von Handelsanwendungen bereitstellt. Wir haben gelernt, Ressourcen effizient zu verwalten, das Rendering zu drosseln, um die Leistung aufrechtzuerhalten, und Chartereignisse zu verarbeiten, um Ihre Visualisierungen interaktiv zu gestalten. Über diesen EA hinaus können Sie denselben Ansatz nutzen, um jede Position im Chart zu kennzeichnen, auch solche, die manuell oder von anderen EAs eröffnet wurden, da in diesem Zusammenhang keine Magic Number verwendet wurde.
Sie können diese Funktion gerne in Ihrem Konto oder in einer Demo-Umgebung testen, mit verschiedenen Blasenformen, Indikatoreinstellungen und mehreren Symbolen experimentieren und beobachten, wie die Zeichenfläche und die interaktive Logik darauf reagieren.
Ihre Erfahrungen und Ideen sind wertvoll, daher bitten wir Sie, Ihre Gedanken in den Kommentaren mitzuteilen. Dieses Feedback wird uns als Orientierung für den nächsten Teil der Reihe dienen, in dem wir uns weiter mit den fortgeschrittenen Funktionen der MQL5-Standardbibliothek befassen werden. Bis dahin: Viel Spaß beim Programmieren und beim Erkunden der Charts!
Anlagen
| Name der Quelldatei | Beschreibung: |
|---|---|
| Part7_InteractivePositionLabeler.mq5 | Der vollständige Quellcode für den Interactive Position Labeler-EA mit der MA-Cross-Strategie und der CCanvas-Integration. |
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/20892
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.
Entwicklung eines Toolkits zur Price-Action-Analyse (Teil 59): Einsatz geometrischer Asymmetrie zur Erkennung präziser Ausbrüche aus fraktalen Konsolidierungsphasen
MQL5-Handelswerkzeuge (Teil 18): Abgerundete Sprechblasen mit Orientierungssteuerung
Larry Williams’ Marktgeheimnisse (Teil 10): Automatisierung von „Smash-Day“-Umkehrmustern in MQL5
MQL5 und Datenverarbeitungspakete integrieren (Teil 7): Entwicklung von Multi-Agenten-Umgebungen für die symbolübergreifende Zusammenarbeit
- 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.