English 日本語
preview
Der MQL5-Standardbibliotheks-Explorer (Teil 7): Interaktive Positionskennzeichnung mit CCanvas

Der MQL5-Standardbibliotheks-Explorer (Teil 7): Interaktive Positionskennzeichnung mit CCanvas

MetaTrader 5Beispiele |
77 0
Clemence Benjamin
Clemence Benjamin

Inhalt:

  1. Einführung
  2. Konzept
  3. Umsetzung
  4. Ergebnisse der Tests
  5. Schlussfolgerung
  6. Anlagen


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.

Schwebende Informationsblase für Positionen

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.

Test auf einem Live-Chart

Abb. 3. Testen anhand eines Live-Charts

metatester64_ID7Li6usp1.gif de

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.

Zurück zum Inhalt

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

Entwicklung eines Toolkits zur Price-Action-Analyse (Teil 59): Einsatz geometrischer Asymmetrie zur Erkennung präziser Ausbrüche aus fraktalen Konsolidierungsphasen Entwicklung eines Toolkits zur Price-Action-Analyse (Teil 59): Einsatz geometrischer Asymmetrie zur Erkennung präziser Ausbrüche aus fraktalen Konsolidierungsphasen
Bei der Untersuchung einer Vielzahl von Breakout-Setups ist mir aufgefallen, dass gescheiterte Breakouts selten auf mangelnde Volatilität zurückzuführen waren, sondern häufiger auf eine schwache interne Struktur. Diese Beobachtung führte zu dem in diesem Artikel vorgestellten Rahmenkonzept. Der Ansatz identifiziert Muster, bei denen das letzte Kurssegment eine überdurchschnittliche Länge, Steilheit und Geschwindigkeit aufweist – eindeutige Anzeichen für den Aufbau von Momentum im Vorfeld einer gerichteten Ausweitung. Indem sie diese subtilen geometrischen Ungleichgewichte innerhalb der Konsolidierungsphase erkennen, können Trader Ausbrüche mit höherer Wahrscheinlichkeit antizipieren, bevor der Kurs die Konsolidierungsspanne verlässt. Lesen Sie weiter, um zu erfahren, wie dieses auf Fraktalen basierende geometrische Modell strukturelle Ungleichgewichte in präzise Ausbruchsignale umsetzt.
MQL5-Handelswerkzeuge (Teil 18): Abgerundete Sprechblasen mit Orientierungssteuerung MQL5-Handelswerkzeuge (Teil 18): Abgerundete Sprechblasen mit Orientierungssteuerung
In diesem Artikel wird gezeigt, wie man in MQL5 abgerundete Sprechblasen erstellt, indem man ein abgerundetes Rechteck mit einem Zeigerdreieck kombiniert und die Ausrichtung (nach oben, unten, links, rechts) steuert. Darin werden die Vorberechnung der Geometrie, das Füllen mit Supersampling zur Kantenglättung, abgerundete Bögen an der Zeigerspitze sowie segmentierte Umrandungen mit einem Erweiterungsverhältnis für nahtlose Übergänge detailliert beschrieben. Leser erhalten konfigurierbaren Code für Größe, Radien, Farben, Deckkraft und Strichstärke, der sich direkt für Warnmeldungen oder Tooltips in Handelsoberflächen einsetzen lässt.
Larry Williams’ Marktgeheimnisse (Teil 10): Automatisierung von „Smash-Day“-Umkehrmustern in MQL5 Larry Williams’ Marktgeheimnisse (Teil 10): Automatisierung von „Smash-Day“-Umkehrmustern in MQL5
Wir implementieren das Umkehrmuster „Smash-Day“ von Larry Williams in MQL5, indem wir einen regelbasierten Expert Advisor mit dynamischem Risikomanagement, einer Logik zur Bestätigung von Ausbrüchen und mit einer Ausführungslogik, die immer nur eine Position gleichzeitig zulässt, erstellen. Mit dem MetaTrader 5-Strategietester und dem bereitgestellten Quellcode können Leser Backtests durchführen, die Strategie nachbilden und die Auswirkungen der Parameter untersuchen.
MQL5 und Datenverarbeitungspakete integrieren (Teil 7): Entwicklung von Multi-Agenten-Umgebungen für die symbolübergreifende Zusammenarbeit MQL5 und Datenverarbeitungspakete integrieren (Teil 7): Entwicklung von Multi-Agenten-Umgebungen für die symbolübergreifende Zusammenarbeit
Der Artikel stellt eine vollständige Python-MQL5-Integration für den Multi-Agenten-Handel vor: MT5-Datenerfassung, Berechnung von Indikatoren, Entscheidungen pro Agent und ein gewichteter Konsens, der zu einer einzigen Handelsaktion führt. Die Signale werden im JSON-Format gespeichert, über Flask bereitgestellt und von einem MQL5-Expert Advisor zur Ausführung mit Positionsgrößenbestimmung und aus dem ATR abgeleiteten SL/TP verarbeitet. Flask-Routen ermöglichen eine sichere Steuerung des Lebenszyklus und eine Statusüberwachung.