English 日本語
preview
Entwicklung des Price Action Analysis Toolkit (Teil 44): Aufbau eines VWMA Crossover Signal EA in MQL5

Entwicklung des Price Action Analysis Toolkit (Teil 44): Aufbau eines VWMA Crossover Signal EA in MQL5

MetaTrader 5Beispiele |
45 4
Christian Benjamin
Christian Benjamin

Einführung

Erfolgreiches Handeln hängt von der Fähigkeit ab, aussagekräftige Preistrends von den Hintergrundrauschen des Marktes zu unterscheiden. Seit Jahrzehnten helfen gleitende Durchschnitte wie der Simple Moving Average (SMA) und der Exponential Moving Average (EMA) den Händlern, die Volatilität zu glätten und die Marktrichtung zu klären. Diese traditionellen Indikatoren übersehen jedoch eine wesentliche Komponente der Kursbewegung: das Handelsvolumen, das oft die wahre Bedeutung eines Trends bestimmt.

Mit der Entwicklung des Volume-Weighted Moving Average (VWMA) wurde diese Einschränkung behoben, indem den Kursen, die mit einer höheren Handelsaktivität verbunden sind, eine größere Bedeutung zugewiesen wurde. Infolgedessen liefert der VWMA einen klareren, zuverlässigeren Hinweis auf die tatsächliche Marktdynamik und hilft Händlern, zwischen starken, volumengestützten Bewegungen und schwachen, wenig partizipativen Schwankungen zu unterscheiden.

Dieser Artikel befasst sich mit der praktischen Anwendung des Kreuzens des VWMA im algorithmischen Handel. Er wird den VWMA-Ansatz vorstellen, seine Implementierung in MQL5 erläutern, Testergebnisse präsentieren und die wichtigsten Erkenntnisse sowohl für diskretionäre als auch für systematische Trader zusammenfassen.

Aufbauend auf diesen Prinzipien bietet der Expert Advisor VWMA Crossover eine VWMA-Kreuzungsstrategie in Kombination mit einem intuitiven On-Chart-Dashboard. Dieses Tool, das für Klarheit und Nutzerfreundlichkeit auf jedem Chart-Hintergrund konzipiert ist, erkennt automatisch Kreuzungsereignisse, hebt handlungsrelevante Signale hervor und liefert zeitnahe Warnungen, was sowohl die Handelsausführung als auch die Marktüberwachung vereinfacht.

Das folgende Inhaltsverzeichnis gibt einen Überblick über die einzelnen Abschnitte dieses Artikels, auf die im Folgenden näher eingegangen wird:


Zum Verständnis des VWMA-Konzepts

Im Gegensatz zu vielen Indikatoren, die an einen bekannten Schöpfer gebunden sind, ist der VWMA organisch aus der Gemeinschaft der technischen Analyse hervorgegangen, da die Praktiker versuchten, Durchschnittswerte nach dem tatsächlichen Marktvolumen zu gewichten. Es baut auf der langen Tradition der gleitenden Durchschnitte auf (die auf die frühen Glättungsverfahren um 1900 zurückgehen) und lehnt sich an die institutionellen Praktiken rund um den VWAP an, der historisch eindeutiger zugeordnet werden kann.

Nachfolgend sind einige Vorteile der VWMA gegenüber SMA und EMA aufgeführt

Vorteil Erklärung
Berücksichtigung des Volumens Der VWMA spiegelt wider, wo die meisten Handelsgeschäfte getätigt wurden, und nicht nur, wo sich die Kurse bewegten.
Überlegene Trendbestätigung Bestätigt echte Umkehrungen oder Fortsetzungen mit Volumenunterstützung.
Adaptive Reaktionsfähigkeit Reagiert auf Marktbewegungen mit hohem Volumen und filtert gleichzeitig Rauschen mit geringem Volumen heraus.
Erkennt die institutionelle Stärke Nützlich für die Identifizierung von Smart Money Akkumulation oder Distribution.
Der volumengewichtete gleitende Durchschnitt (Volume-Weighted Moving Average, VWMA) ist ein technischer Indikator, der sowohl den Preis als auch das Handelsvolumen berücksichtigt, um einen umfassenderen Überblick über die Markttrends zu bieten. Im Gegensatz zu den traditionellen gleitenden Durchschnitten, die nur den Preis berücksichtigen, verleiht der VWMA den Zeiträumen mit höherer Handelsaktivität mehr Gewicht. Er wird berechnet, indem das Produkt aus dem Schlusskurs jeder Kerze und dem entsprechenden Volumen addiert und dann durch die Summe der Volumina im gleichen Zeitraum geteilt wird.


VWMA-Formel:

wobei:

  • 𝑃(𝑖) = Preis der Kerze i (normalerweise der Schlusskurs)
  • 𝑉(𝑖) = Handelsvolumen der Kerze i
  • 𝑛 = Anzahl der Perioden (z. B. 20)

Nehmen wir an, wir wollen einen 5-Perioden-VWMA anhand der folgenden Daten berechnen:

Kerze Schlusskurs Volumen
1 10 100
2 11 200
3 12 150
4 13 300
5 14 250

Nun rechnen wir:

  • Wir multiplizieren jeden Preis mit seinem Volumen:

(10×100) + (11×200) + (12×150) + (13×300) + (14×250) = 1000 + 2200 + 1800 + 3900 + 3500 = 12,400

  • summieren die Volumina:

100 + 200 + 150 + 300 + 250 = 1000

  • und teilen die Summe von (Preis × Volumen) durch das Gesamtvolumen:

VWMA = 12,400/1000 = 12.4

Der 5-Perioden-VWMA = 12,4.

  1. Wenn der Kurs > VWMA ist, befindet sich der Markt häufig in einem volumengestützten Aufwärtstrend.
  2. Wenn der Kurs < VWMA ist, signalisiert das einen volumengestützten Abwärtstrend.
  3. Ein flacher oder seitwärts laufender VWMA deutet auf eine schwache Beteiligung oder einen Handel innerhalb einer Handelsspanne hin.

Hier ist ein kurzes Code-Fragment, das zeigt, wie man den volumengewichteten gleitenden Durchschnitt (VWMA) in einem MQL5 Expert Advisor oder Indikator manuell berechnet:

double VWMA(const string symbol, ENUM_TIMEFRAMES timeframe, int period, int shift)
{
   if(period <= 0) return EMPTY_VALUE;
   MqlRates rates[];
   if(CopyRates(symbol, timeframe, shift, period, rates) != period)
      return EMPTY_VALUE;
   double sumPriceVolume = 0, sumVolume = 0;
   for(int i = 0; i < period; i++)
   {
      sumPriceVolume += rates[i].close * rates[i].tick_volume;
      sumVolume += rates[i].tick_volume;
   }
   return (sumVolume == 0) ? EMPTY_VALUE : sumPriceVolume / sumVolume;
}

In dieser Entwicklung verwenden wir sowohl einen schnellen als auch einen langsamen volumengewichteten gleitenden Durchschnitt (VWMA), um kurzfristige bzw. langfristige Markttrends zu erfassen.

Schneller VWMA

  • Hat eine kürzere Dauer (z. B. 10 oder 20 Balken).
  • Reagiert schnell auf aktuelle Preis- und Volumenänderungen.
  • Reagiert stärker auf kurzfristige Marktbewegungen.
  • Nutz bei der Erkennung kurzfristiger Trends, der Dynamik oder möglicher Einstiegs- und Ausstiegspunkte.

Langsamer VWMA

  • Hat einen längeren Zeitraum (z. B. 50 oder 60 Balken).
  • Reagiert langsamer auf die jüngsten Preis- und Volumenänderungen.
  • Glättet kleinere Schwankungen und konzentriert sich auf den größeren Trend.
  • Nutz, die allgemeine Marktrichtung zu erkennen oder Störungen herauszufiltern.

Die Logik für die Generierung von Handelssignalen in diesem EA spiegelt die Logik von Standardstrategien mit gleitendem Durchschnitt (MA) wider, bei denen Kauf- oder Verkaufssignale erzeugt werden, wenn der schnelle VWMA über oder unter den langsamen VWMA fällt.

Abwärtssignal

Abwärts-Kreuzen

Verkaufssignale werden generiert, wenn der schnelle VWMA unter den langsamen VWMA fällt.

Konkret lauten die Bedingungen für ein Verkaufssignal:

  • Auf dem vorherigen Balken lag der schnelle VWMA über dem langsamen VWMA.
  • Auf dem aktuellen Balken hat sich der schnelle VWMA unter den langsamen VWMA bewegt.

Dieses „abwärts gerichtete Kreuzen“ deutet auf einen potenziellen Wechsel von einem steigenden zu einem fallenden Momentum hin, was einen günstigen Zeitpunkt für einen Verkauf darstellen könnte.

bool bear = (f_prev > s_prev) && (f_now < s_now);
if(bear /* && other filters */) {
   // Generate sell signal
}

Aufwärtssignal

Kaufsignale (Kursanstieg) werden generiert, wenn der schnelle VWMA den langsamen VWMA übersteigt.

Im Einzelnen sind die Bedingungen für ein Kaufsignal:

  • Auf dem vorherigen Balken lag der schnelle VWMA unter dem langsamen VWMA.
  • Auf dem aktuellen Balken hat sich der schnelle VWMA über den langsamen VWMA bewegt.

Dieses „Aufwärts-Kreuzen“ deutet auf einen potenziellen Wechsel von einem fallenden zu einem steigenden Momentum hin, was auf einen günstigen Zeitpunkt für Käufe hinweist.

bool bull = (f_prev < s_prev) && (f_now > s_now);
if(bull /* && other filters */) {
   // Generate buy signal
}

Bitte beachten Sie, dass der volumengewichtete gleitende Durchschnitt (VWMA) nicht als standardmäßiger, integrierter Indikator in MetaTrader 5 verfügbar ist. Um VWMA in Ihrem EA oder Indikator zu verwenden, muss die Berechnung manuell mit Hilfe der oben genannten Formel implementiert werden.


MQL5-Implementierung

Um mit der MQL5-Entwicklung zu beginnen, stellen Sie zunächst sicher, dass Sie MetaTrader 5 auf Ihrem Computer installiert haben. Der MetaEditor, die offizielle Umgebung zum Schreiben und Bearbeiten von MQL5-Code, wird mit jeder MetaTrader 5-Installation mitgeliefert, sodass Sie es nicht separat installieren müssen. Sobald MetaTrader 5 bereit ist, starten Sie MetaEditor entweder aus dem MetaTrader 5-Terminal (indem Sie auf das MetaEditor-Symbol klicken oder F4 drücken) oder direkt aus Ihrem Anwendungsmenü. Gehen Sie in MetaEditor auf „Datei“ > „Neu“, wählen Sie „Expert Advisor (Vorlage)“ und geben Sie einen Namen für Ihren EA ein. Nachdem Sie diese Schritte durchgeführt haben, sind Sie bereit, den detaillierten Anweisungen zu folgen, die ich Ihnen im Folgenden gebe, um Ihren eigenen MQL5 Expert Advisor von Grund auf zu erstellen.

1. Dateikopf und Meta-Informationen

//+------------------------------------------------------------------+
//|                                             VWMA CROSSOVER EA.mq5|
//|                               Copyright 2025, Christian Benjamin.|
//|                           https://www.mql5.com/en/users/lynnchris|
//+------------------------------------------------------------------+
#property copyright "https://www.mql5.com/en/users/lynnchris"
#property version   "1.0"
#property strict

Die allerersten Zeilen der Quelldatei enthalten drei #property-Direktiven, die das Programm für das MetaTrader 5-Terminal beschreiben. Die Copyright-URL gibt die Urheberschaft an, während der Versionsstring eine offizielle Versionsnummer angibt, die später im Navigator des Terminals erscheint. Schließlich zwingt #property strict den Compiler, die neuesten Sprachregeln anzuwenden. Die Codierung im Strict-Modus verhindert veraltete Vereinfachungen, fängt zweideutige Typkonvertierungen ab und macht die Codebasis daher robuster.

2. Externe Eingänge

input ENUM_TIMEFRAMES InpTimeframe = PERIOD_CURRENT;
input uint   FastPeriod  = 20;
input uint   SlowPeriod  = 60;
input uint   SR_LookBack = 50;
input double SR_OffsetPips = 3.0;

input bool   Draw_Arrows = true;
input bool   Send_Alerts = true;
input bool   Show_VWMA_Lines = true;
input int    PlotDepth = 500;

Unmittelbar nach der Kopfzeile folgen die Eingabevariablen – die öffentlichen Parameter, die der Nutzer im Einstellungsdialog des EA sehen wird. InpTimeframe legt den Zeitrahmen des Arbeitscharts fest; wenn es auf PERIOD_CURRENT belassen wird, übernimmt der EA einfach den Zeitrahmen des Charts, auf dem er läuft. FastPeriod und SlowPeriod sind die Rückblickfenster der beiden VWMAs, die später verglichen werden. Das nächste Paar, SR_LookBack und SR_OffsetPips, steuert den leichtgewichtigen Unterstützungs-Widerstands-Filter: Der EA durchsucht die letzten N Bars nach Extremen und lässt einen Handel nur zu, wenn sich der Preis mindestens um Offset-Pips darüber hinaus bewegt hat. Mit drei booleschen Flags kann der Händler entscheiden, ob Pfeile gezeichnet, Warnungen gesendet oder gleitende Durchschnittslinien gezeichnet werden sollen, während PlotDepth begrenzt, wie viele historische Balken auf dem Chart dargestellt werden, um die Rendering-Zeit angemessen zu halten.

3. Globale Laufzeitvariablen

datetime g_last_bar_time = 0;
int      g_last_signal = 0; // 1 = BUY, -1 = SELL, 0 = none
datetime g_last_signal_time = 0;
string   DASH_BASE = "VWMA_DASH_";

Vier globale Variablen bewahren den Zustand des EA zwischen den Ticks. g_last_bar_time merkt sich die Öffnungszeit der Kerze, die bereits verarbeitet wurde, sodass die Logik nur einmal pro Bar ausgeführt wird. g_last_signal und g_last_signal_time behalten die Richtung und den Zeitstempel des letzten Alarms im Auge; diese Informationen werden vom Dashboard wiederverwendet. DASH_BASE schließlich ist ein Textpräfix, das sicherstellt, dass jedes Objekt, das zum Chart-Panel gehört, einen eindeutigen, leicht identifizierbaren Namen hat.

4. Die VWMA-Berechnungsroutine

double VWMA(const string sym, ENUM_TIMEFRAMES tf, uint per, int shift)
  {
   if(per == 0)
      return EMPTY_VALUE;
   MqlRates r[];
   if(CopyRates(sym, tf, shift, per, r) != (int)per)
      return EMPTY_VALUE;
   double num = 0, den = 0;
   for(int i = 0; i < (int)per; i++)
     {
      double vol = (double)r[i].tick_volume;
      num += r[i].close * vol;
      den += vol;
     }
   return (den == 0) ? EMPTY_VALUE : num / den;
  }

double VWMA(const string sym, ENUM_TIMEFRAMES tf, uint per, int shift) verkörpert das mathematische Herzstück des Programms. Es beginnt mit dem Kopieren der Kerzen aus der Historie unter Verwendung von CopyRates, beginnend mit den ältesten Balken. In einer einfachen Schleife akkumuliert die Funktion zwei laufende Summen: num, die Summe von close × volume, und den, das Gesamtvolumen. Dividiert man den ersten durch den zweiten Wert, erhält man den kanonischen volumengewichteten gleitenden Durchschnitt.

Können keine Kursdaten ermittelt werden oder ist der Nenner zufällig gleich Null, gibt die Funktion die MetaTrader-Konstante EMPTY_VALUE zurück, die von nachgelagerten Routinen wie NaN behandelt wird.

5. Unterstützungs- und Widerstandshelfer

double HighestHigh(const string s, ENUM_TIMEFRAMES tf, uint lb)
  {
   if(lb == 0)
      return EMPTY_VALUE;
   double a[];
   if(CopyHigh(s, tf, 0, lb, a) != (int)lb)
      return EMPTY_VALUE;
   double m = a[0];
   for(uint i = 1; i < lb; i++)
      if(a[i] > m)
         m = a[i];
   return m;
  }

double LowestLow(const string s, ENUM_TIMEFRAMES tf, uint lb)
  {
   if(lb == 0)
      return EMPTY_VALUE;
   double a[];
   if(CopyLow(s, tf, 0, lb, a) != (int)lb)
      return EMPTY_VALUE;
   double m = a[0];
   for(uint i = 1; i < lb; i++)
      if(a[i] < m)
         m = a[i];
   return m;
  }

bool ValidateSR(bool buy, double bid, double ask, double& sup, double& res)
  {
   res = HighestHigh(_Symbol, InpTimeframe, SR_LookBack);
   sup = LowestLow(_Symbol, InpTimeframe, SR_LookBack);
   if(res == EMPTY_VALUE || sup == EMPTY_VALUE)
      return false;
   double off = SR_OffsetPips * _Point;
   return buy ? (bid >= sup + off) : (ask <= res - off);
  }

Zwei kurze Wrapper, HighestHigh und LowestLow, durchsuchen die letzten N Balken nach dem extremen Hoch bzw. Tief, indem sie Roh-Arrays von CopyHigh und CopyLow lesen. Über ihnen befindet sich ValidateSR, ein boolesches Gatter, das einen rudimentären, aber effektiven Handelsfilter implementiert. Zunächst werden die beiden Wrapper aufgerufen, um die letzten Höchst- (res) und Tiefstwerte (sup) zu ermitteln. Dann wird der vom Nutzer angegebene Pip-Offset addiert oder subtrahiert und schließlich geprüft, ob der aktuelle Geld- oder Briefkurs (Bid, Ask)) diese Niveaus überschritten hat. In der Praxis verhindert dies, dass der EA direkt an einem potenziellen Widerstand kauft oder an einer potenziellen Unterstützung verkauft.

6. Hilfsprogramme für die Objektverwaltung

//+------------------------------------------------------------------+
//| Chart Utilities                                                  |
//+------------------------------------------------------------------+
void SafeDeleteObject(const string name)
  {
   if(ObjectFind(0, name) != -1)
      ObjectDelete(0, name);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PlotChartArrow(const string n, datetime t, double price, color clr, int code)
  {
   SafeDeleteObject(n);
   ObjectCreate(0, n, OBJ_ARROW, 0, t, price);
   ObjectSetInteger(0, n, OBJPROP_COLOR, clr);
   ObjectSetInteger(0, n, OBJPROP_ARROWCODE, code);
   ObjectSetInteger(0, n, OBJPROP_WIDTH, 2);
  }

SafeDeleteObject ist ein Einzeiler, der zunächst prüft, ob ein grafisches Objekt existiert und es nur dann löscht, wenn es vorhanden ist. Die Methode verhindert Terminalprotokoll-Spam, der sonst beim Versuch, ein bereits gelöschtes Objekt zu entfernen, auftreten würde. PlotChartArrow ist eine Hilfsfunktion, die einen OBJ_ARROW mit einheitlichem Styling – Farbe, Pfeilcode und Breite – zum angegebenen Zeitpunkt und Preis konstruiert. Durch die Zentralisierung des Löschens und Erstellens in diesen beiden Hilfsprogrammen kann sich der Rest des Codes auf die Handelslogik und nicht auf die Verwaltung des Charts konzentrieren.

7. Zeichnen von Polylinien mit gleitendem Durchschnitt

void DrawLineVWMA(const string name, int period, color clr, int depth)
  {
   if(!Show_VWMA_Lines)
     {
      SafeDeleteObject(name);
      int total = ObjectsTotal(0);
      for(int i = total - 1; i >= 0; i--)
        {
         string nm = ObjectName(0, i);
         if(StringFind(nm, name + "_seg_") == 0)
            ObjectDelete(0, nm);
        }
      return;
     }
   const int extra = period + 2;
   MqlRates r[];
   if(CopyRates(_Symbol, InpTimeframe, 0, depth + extra, r) < depth + extra)
      return;
   int total = ObjectsTotal(0);
   for(int i = total - 1; i >= 0; i--)
     {
      string nm = ObjectName(0, i);
      if(StringFind(nm, name + "_seg_") == 0)
         ObjectDelete(0, nm);
     }
   for(int i = 0; i < depth - 1; i++)
     {
      double vw1 = VWMA(_Symbol, InpTimeframe, period, i);
      double vw2 = VWMA(_Symbol, InpTimeframe, period, i + 1);
      if(vw1 == EMPTY_VALUE || vw2 == EMPTY_VALUE)
         continue;
      datetime t1 = r[i].time;
      datetime t2 = r[i + 1].time;
      string seg = name + "_seg_" + IntegerToString(i);
      if(ObjectCreate(0, seg, OBJ_TREND, 0, t1, vw1, t2, vw2))
        {
         ObjectSetInteger(0, seg, OBJPROP_COLOR, clr);
         ObjectSetInteger(0, seg, OBJPROP_WIDTH, 1);
         ObjectSetInteger(0, seg, OBJPROP_RAY_RIGHT, false);
        }
     }
  }

Anstatt einen separaten Indikator mit Puffern zu schreiben, zeichnet dieser Expert Advisor seine volumengewichteten gleitenden Durchschnitte (VWMAs) mit der Funktion DrawLineVWMA direkt in den Chart, was eine nahtlose Integration in die Logik des EAs ermöglicht und sicherstellt, dass die gleitenden Durchschnitte immer mit dem Chart und den Parametern synchronisiert sind. Die Funktion beginnt mit der Überprüfung des Flags Show_VWMA_Lines; wenn der Nutzer das Zeichnen von VWMA-Linien deaktiviert, führt sie sofort eine gründliche Bereinigung durch, indem sie alle Objekte löscht, die für die Anzeige der VWMA verwendet wurden und durch ihr Namenspräfix identifiziert werden, und beendet sich dann, um das Chart übersichtlich zu halten.

Wenn das Zeichnen von Linien aktiviert ist, fordert die Funktion einen Block historischer Kerzendaten unter Verwendung von CopyRates an und sammelt genügend Balken (basierend auf der vom Nutzer angegebenen Tiefe plus einige zusätzliche für die Berechnungsgenauigkeit), um die VWMA über den gesamten sichtbaren Bereich zu berechnen. Bevor neue Linien gezeichnet werden, werden alle Chart-Objekte erneut durchlaufen und alle Überreste alter VWMA-Segmente gelöscht, um Unordnung und grafische Artefakte aus früheren Läufen zu vermeiden. Die Haupt-Zeichenroutine durchläuft dann eine Schleife über jedes aufeinanderfolgende Balkenpaar in der angegebenen Tiefe und berechnet für jedes Paar die VWMA an beiden Segment-Endpunkten; wenn einer der VWMA-Werte ungültig ist (z. B. wegen unzureichender Daten), wird zum nächsten Paar übergegangen. Andernfalls wird eine kurze Zweipunkt-Trendlinie (OBJ_TREND) erstellt, die diese beiden VWMA-Werte zu ihren jeweiligen Zeitpunkten und Preisen miteinander verbindet. Dabei wird jedes Segment eindeutig benannt, um spätere Bereinigungen zu erleichtern, und mit der gewählten Farbe und Breite gestaltet, wobei sichergestellt wird, dass die Linien nicht über ihre Endpunkte hinausgehen.

Durch Wiederholung dieses Prozesses für viele Balkenpaare konstruiert die Funktion eine visuell kontinuierliche VWMA-Linie. Dieser segmentierte Ansatz ist sowohl effizient als auch effektiv, da er die Speichernutzung minimiert und schnelle Aktualisierungen gewährleistet, selbst wenn neue Balken hinzugefügt oder Parameter geändert werden. Die Funktion ist für eine robuste automatische Wartung ausgelegt; bei jedem Aufruf werden veraltete Segmente entfernt und neue Segmente auf der Grundlage der neuesten VWMA-Berechnungen gezeichnet, sodass die visuelle Darstellung immer aktuell und genau ist. Zusammenfassend lässt sich sagen, dass DrawLineVWMA einen praktischen und robusten Mechanismus für die Überlagerung von VWMAs auf dem Chart als Teil der visuellen Ausgabe des EAs bietet, der ein Gleichgewicht zwischen Klarheit, Effizienz und Nutzerkontrolle herstellt und die Notwendigkeit einer separaten Indikatordatei oder von Puffern eliminiert, während er dem Nutzer die Möglichkeit bietet, VWMA-Linien je nach Wunsch ein- oder auszuschalten, um den Chart sowohl informativ als auch ordentlich zu halten.

8. Aufbau und Pflege des Dashboards

void UpdateDashboard(double fast_vwma, double slow_vwma)
  {
   int corner = 0, x = 12, y = 12;
   int panel_w = 320, panel_h = 130, pill_w = 120, pill_h = 36, gap_y = 12;
   int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
   string prefix = DASH_BASE;
   // ... (creation and property setting for each rectangle and label)
   // See full code for all label/rectangle setup
   string sia = prefix + "SIGN_ARROW";
   if(ObjectFind(0, sia) == -1)
      ObjectCreate(0, sia, OBJ_LABEL, 0, 0, 0);
   ObjectSetInteger(0, sia, OBJPROP_CORNER, corner);
   ObjectSetInteger(0, sia, OBJPROP_XDISTANCE, x + pill_w + 130);
   ObjectSetInteger(0, sia, OBJPROP_YDISTANCE, y + (pill_h + gap_y) * 2 + 10);
   ObjectSetInteger(0, sia, OBJPROP_FONTSIZE, 28);
   string txt = "";
   color arrclr = clrGray;
   if(g_last_signal == 1)
     {
      txt = "▲";
      arrclr = clrLime;
     }
   if(g_last_signal == -1)
     {
      txt = "▼";
      arrclr = clrRed;
     }
   ObjectSetInteger(0, sia, OBJPROP_COLOR, arrclr);
   ObjectSetString(0, sia, OBJPROP_TEXT, txt);
  }

UpdateDashboard synthetisiert ein kompaktes dreireihiges Bedienfeld in der oberen linken Ecke des Charts. Ein schwarzes OBJ_RECTANGLE bildet den Hintergrund; darin zeigen zwei farbcodierte „pills“ die letzten schnellen und langsamen VWMA-Werte an, und eine breitere „pill“ darunter zeigt das letzte Handelssignal an. Alle Rechtecke und Beschriftungen werden mit einem gemeinsamen DASH_BASE-Präfix benannt, sodass eine Massenlöschung durch DeleteDashboardObjects möglich ist, wenn der EA entladen wird. Die Funktion wählt dynamisch die Pfeilglyphe, ihre Farbe und die numerische Genauigkeit der VWMA-Messwerte aus, sodass der Händler Informationen auf einen Blick erhält, ohne Tooltips oder das Expertenprotokoll einsehen zu müssen.

9. Ausführen eines Handelssignals

void ExecuteSignal(bool buy, const string cmt)
  {
   g_last_signal = buy ? 1 : -1;
   g_last_signal_time = TimeCurrent();

   // Plot arrow
   if(Draw_Arrows)
     {
      string name = (buy ? "SIGNAL_BUY_" : "SIGNAL_SELL_") + (string)g_last_signal_time;
      color clr = buy ? clrLime : clrRed;
      int code = buy ? 233 : 234;
      double price = buy ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      PlotChartArrow(name, g_last_signal_time, price, clr, code);
     }
   // Alert
   if(Send_Alerts)
     {
      string msg = (buy ? "VWMA SIGNAL BUY " : "VWMA SIGNAL SELL ") + _Symbol + " | " + cmt;
      Alert(msg);
      PlaySound("alert.wav");
     }
   // Update dashboard
   double f = VWMA(_Symbol, InpTimeframe, FastPeriod, 0);
   double s = VWMA(_Symbol, InpTimeframe, SlowPeriod, 0);
   if(f != EMPTY_VALUE && s != EMPTY_VALUE)
      UpdateDashboard(f, s);
  }

Wenn die Strategielogik feststellt, dass ein neues Kauf- oder Verkaufssignal aufgetreten ist, ruft sie die Funktion ExecuteSignal auf, die alle damit verbundenen Aktionen mit Ausnahme der Platzierung von Handelsgeschäften verwaltet. Zunächst werden die globalen Variablen aktualisiert, um den neuesten Signaltyp und die Uhrzeit aufzuzeichnen, sodass andere Komponenten, wie z. B. Dashboards, synchronisiert bleiben. Wenn die Pfeildarstellung aktiviert ist, markiert die Funktion den Chart an der Position des Signals mit einem farbigen Pfeil – limonenfarben für Käufe und rot für Verkäufe – und erleichtert so die visuelle Erkennung von Signalen. Wenn Warnungen aktiviert sind, zeigt die Funktion auch eine Popup-Meldung an und spielt einen Benachrichtigungston ab, sodass der Nutzer sofort ein Feedback mit Informationen über das Signal und das Symbol erhält. Schließlich wird das Dashboard mit den neuesten VWMA-Werten aktualisiert, sodass die visuelle Zusammenfassung die neueste Marktanalyse widerspiegelt. Es ist wichtig zu beachten, dass diese Funktion nur Signale generiert und sie anzeigt; er führt keine Handelsgeschäfte aus, sodass der EA als Signalgenerator dienen kann, der in Zukunft mit automatisierten Handelsfunktionen erweitert werden kann.

10. Lebenszyklus-Ereignishandlung

int OnInit()
  {
   Print("VWMA Crossover Dashboard (signal-only) loaded.");
   g_last_bar_time = 0;
   g_last_signal = 0;
   g_last_signal_time = 0;
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   SafeDeleteObject("VWMA_FAST");
   SafeDeleteObject("VWMA_SLOW");
   int total = ObjectsTotal(0);
   for(int i = total - 1; i >= 0; i--)
     {
      string nm = ObjectName(0, i);
      if(StringFind(nm, "SIGNAL_BUY_") == 0 || StringFind(nm, "SIGNAL_SELL_") == 0)
         ObjectDelete(0, nm);
      if(StringFind(nm, "VWMA_FAST_seg_") == 0 || StringFind(nm, "VWMA_SLOW_seg_") == 0)
         ObjectDelete(0, nm);
     }
   DeleteDashboardObjects();
  }

OnInit wird einmal ausgeführt, wenn der EA mit einem Chart verbunden oder neu kompiliert wird. Es setzt alle Statusvariablen auf Null und gibt eine Konsolenansage aus, damit der Nutzer bestätigen kann, dass die Initialisierung erfolgreich war. OnDeinit führt die gegenteilige Aufgabe aus: Es säubert das Chart, indem es einzelne Master-Objekte („VWMA_FAST“, „VWMA_SLOW“) löscht und dann in einer Schleife jedes verbleibende Chart-Objekt durchläuft und alle Objekte entfernt, deren Name mit „SIGNAL_BUY_“, „SIGNAL_SELL_“ oder den Segment-Präfixen beginnt, die bei den Zeichnungen verwendet wurden. Das Dashboard wird ebenfalls abgebaut, um das Chart genau so zu belassen, wie es war, bevor der EA geladen wurde.

11. Der Heartbeat – OnTick

void OnTick()
  {
   // Update dashboard every tick
   double f_now_dash = VWMA(_Symbol, InpTimeframe, FastPeriod, 0);
   double s_now_dash = VWMA(_Symbol, InpTimeframe, SlowPeriod, 0);
   if(f_now_dash != EMPTY_VALUE && s_now_dash != EMPTY_VALUE)
      UpdateDashboard(f_now_dash, s_now_dash);

   datetime cur = iTime(_Symbol, InpTimeframe, 0);
   if(cur == g_last_bar_time)
     {
      DrawLineVWMA("VWMA_FAST", FastPeriod, clrDodgerBlue, PlotDepth);
      DrawLineVWMA("VWMA_SLOW", SlowPeriod, clrOrangeRed, PlotDepth);
      return;
     }
   g_last_bar_time = cur;

   double f_prev = VWMA(_Symbol, InpTimeframe, FastPeriod, 1);
   double s_prev = VWMA(_Symbol, InpTimeframe, SlowPeriod, 1);
   double f_now  = VWMA(_Symbol, InpTimeframe, FastPeriod, 0);
   double s_now  = VWMA(_Symbol, InpTimeframe, SlowPeriod, 0);
   if(f_prev == EMPTY_VALUE || s_prev == EMPTY_VALUE || f_now == EMPTY_VALUE || s_now == EMPTY_VALUE)
      return;

   bool bull = (f_prev < s_prev && f_now > s_now);
   bool bear = (f_prev > s_prev && f_now < s_now);

   double sup, res;
   if(bull && ValidateSR(true, SymbolInfoDouble(_Symbol, SYMBOL_BID), SymbolInfoDouble(_Symbol, SYMBOL_ASK), sup, res))
      ExecuteSignal(true, "VWMA BUY");
   if(bear && ValidateSR(false, SymbolInfoDouble(_Symbol, SYMBOL_BID), SymbolInfoDouble(_Symbol, SYMBOL_ASK), sup, res))
      ExecuteSignal(false, "VWMA SELL");

   DrawLineVWMA("VWMA_FAST", FastPeriod, clrDodgerBlue, PlotDepth);
   DrawLineVWMA("VWMA_SLOW", SlowPeriod, clrOrangeRed, PlotDepth);
  }

Jeder eingehende Tick des Marktes löst OnTick aus, aber der rechenintensive Teil des Algorithmus läuft nur einmal pro Balken. Die Funktion beginnt damit, die Werte des Dashboards bei jedem Tick zu aktualisieren, damit die Zahlen aktuell bleiben. Sie prüft dann, ob sich die aktuelle Zeit der Kerzen iTime(...,0) von g_last_bar_time unterscheidet; wenn nicht, werden nur die MA-Linien neu gezeichnet und die Funktion wird schnell beendet.  Wenn ein neuer Balken erkannt wird, sammelt der EA die schnelle und langsame VWMA für die vorherige und die aktuelle Kerze. Ein Aufwärts-Kreuzen wird erkannt, wenn sich der schnelle VWMA von unten nach oben über den langsamen VWMA bewegt; der umgekehrte Fall ist ein Abwärts-Kreuzen. Jeder voraussichtliche Handel wird dann durch ValidateSR geleitet; wenn die Level-Prüfung bestanden ist, wird ExecuteSignal aufgerufen. Unabhängig davon, ob ein Signal ausgelöst wird, werden am Ende der Methode beide VWMA-Linien neu gezeichnet, damit die visuellen Elemente mit der neu gebildeten Kerze übereinstimmen.

Nachdem Sie Ihren MQL5 EA-Code fertiggestellt haben, klicken Sie im MetaEditor auf die Schaltfläche „Kompilieren“. Wenn es keine Fehler oder Warnungen gibt, ist Ihr EA bereit für den Einsatz und das Testen. Um seine Leistung zu bewerten, öffnen Sie MetaTrader 5, gehen Sie zum „Navigator“-Fenster, erweitern Sie den Bereich „Experten“ und ziehen Sie Ihren EA auf ein Chart für Live- oder Demotests. Alternativ können Sie auch den Strategy Tester verwenden, um das Verhalten Ihres EAs anhand historischer Daten zu testen.

Schritt für Schritt:

  • Kompilieren Sie Ihren EA in MetaEditor, indem Sie auf die Schaltfläche „Kompilieren“ klicken.
  • Prüfen Sie auf Fehler und Warnungen. Wenn keine derartigen Meldungen vorliegen, ist der EA bereit.
  • Öffnen Sie MetaTrader 5, gehen Sie zum „Navigator“ (normalerweise auf der linken Seite) und suchen Sie Ihren EA unter „Experten“.
  • Ziehen Sie den EA per Drag & Drop auf einen Chart, um ihn live oder im Demomodus auszuführen.
  • Für eine historische Performance-Analyse öffnen Sie den Strategy Tester (drücken Sie Strg+R oder verwenden Sie das Menü „Ansicht“), wählen Sie Ihren EA aus, wählen Sie Ihre Einstellungen und starten Sie den Backtest.


Ergebnisse

Nachfolgend finden Sie eine Illustration der Backtest-Ergebnisse für unser Tool. Ein spezielles Panel wird angezeigt, das in Echtzeit aktualisiert wird und die aktuellen Werte der schnellen und langsamen VWMA mit jedem neuen Tick anzeigt. Auf dem Chart zeigen grüne Pfeile Kaufsignale an, während rote Pfeile Verkaufssignale markieren, was klare visuelle Hinweise für jedes Handelsereignis liefert. Insgesamt beobachten wir eine Reihe von positiven Signalen, von denen die meisten auf günstige Handelsmöglichkeiten hindeuten. Es gibt zwar einige Fehlsignale, doch sind diese relativ begrenzt, was die potenzielle Wirksamkeit des Tools beim Herausfiltern von Marktstörungen und beim Erkennen echter Trends zeigt.

Backtest


Schlussfolgerung

Zusammenfassend lässt sich sagen, dass herkömmliche gleitende Durchschnitte wie der einfache gleitende Durchschnitt (SMA) und der exponentielle gleitende Durchschnitt (EMA) zwar nach wie vor wertvolle Instrumente für die technische Analyse sind, sich aber in erster Linie auf Preisdaten konzentrieren und die Bedeutung des Handelsvolumens für die Marktbewegungen mitunter übersehen können. Der VWMA Crossover EA ergänzt diese Ansätze, indem er das Volumen in seine Berechnungen einbezieht und so eine nuanciertere Perspektive auf das Kursgeschehen bietet. Da das Tool sowohl den Preis als auch das Volumen berücksichtigt, hilft es Händlern, potenzielle Aufwärts- und Abwärtsbewegungen effektiver zu erkennen, insbesondere in Zeiten erhöhter Marktaktivität. Dieser zusätzliche Einblick kann die Entscheidungsfindung verbessern und den Handelssignalen mehr Kontext verleihen, was den VWMA Crossover EA zu einer nützlichen Ergänzung des analytischen Werkzeugkastens eines jeden Händlers macht.

Lesen Sie meine anderen Artikel.

Anmerkung: Dieser Artikel und der VWMA Crossover EA werden zu Bildungszwecken zur Verfügung gestellt, damit Sie Ihr Verständnis der technischen Analyse und des signalbasierten Handels vertiefen können. Der EA dient als Signalgenerator; er führt keine Handelsgeschäfte automatisch aus, sodass Sie die volle Kontrolle über Ihre Handelsentscheidungen behalten. Wir ermutigen Sie, mit dem Tool zu experimentieren, es gründlich zu testen und die Eingabeeinstellungen an Ihre persönliche Strategie und Marktpräferenzen anzupassen. Nutzen Sie die Signale als wertvollen Teil Ihrer Analyse und überprüfen Sie sie stets mit Ihrem eigenen Urteil. Mit sorgfältigen Tests und durchdachten Anpassungen kann dieses Tool zu einer wertvollen Ergänzung Ihres Handelsinstrumentariums werden.

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

Beigefügte Dateien |
Letzte Kommentare | Zur Diskussion im Händlerforum (4)
Wilson Malinda
Wilson Malinda | 9 Okt. 2025 in 15:50
Gerade versucht dies, und das Signal ist nicht zeigen 5 Tage jetzt, für XAUSD, warum das Signal nicht angezeigt?
Christian Benjamin
Christian Benjamin | 9 Okt. 2025 in 16:53
Wilson Malinda #:
Gerade versucht dies, und das Signal ist nicht zeigen 5 Tage jetzt, für XAUSD, warum das Signal nicht zeigen?
Ich verstehe dich nicht, meinst du im Backtesting oder was? Dieses Tool wurde erst heute veröffentlicht, wie kann es also schon 5 Tage alt sein?
smartchartfx
smartchartfx | 17 Okt. 2025 in 12:15
Interessante Einrichtung. Das VWMA Crossover sieht sauber aus. Mir gefällt, wie Sie das Volumen mit der Trendbestätigung kombinieren, anstatt sich nur auf die Preisbewegung zu verlassen. Ich bin neugierig, wie es sich auf niedrigeren Zeitebenen verhält, insbesondere während volatiler Sitzungen.
beetle2008
beetle2008 | 27 Okt. 2025 in 07:41
Großartig, wie Sie die volumengewichteten gleitenden Durchschnitte mit der Kursbewegung mischen, um Umkehrungen zu erkennen. Die On-Chart-Panel sieht super sauber und leicht zu folgen. Es gibt viel Raum, um mit dieser Idee herumzuspielen. Danke, dass Sie sie mit allen geteilt haben.
Bivariate Copulae in MQL5 (Teil 1): Implementierung von Gauß- und Studentische t-Copulae für die Modellierung von Abhängigkeiten Bivariate Copulae in MQL5 (Teil 1): Implementierung von Gauß- und Studentische t-Copulae für die Modellierung von Abhängigkeiten
Dies ist der erste Teil einer Artikelserie, in der die Implementierung von bivariaten Copulae in MQL5 vorgestellt wird. Dieser Artikel enthält Code zur Implementierung der Gauß‘schen und Studentischen t-Copulae. Außerdem werden die Grundlagen der statistischen Copulae und verwandte Themen behandelt. Der Code basiert auf dem Python-Paket Arbitragelab von Hudson und Thames.
Automatisieren von Handelsstrategien in MQL5 (Teil 36): Handel mit Angebot und Nachfrage mit Retest und Impulsmodell Automatisieren von Handelsstrategien in MQL5 (Teil 36): Handel mit Angebot und Nachfrage mit Retest und Impulsmodell
In diesem Artikel erstellen wir ein Angebots- und Nachfragehandelssystem in MQL5, das Angebots- und Nachfragezonen durch Konsolidierungsbereiche identifiziert, sie mit impulsiven Bewegungen validiert und Retests mit Trendbestätigung und anpassbaren Risikoparametern handelt. Das System visualisiert die Zonen mit dynamischen Etiketten und Farben und unterstützt Trailing Stops für das Risikomanagement.
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 83):  Die Verwendung von Mustern des Stochastischen Oszillators und des FrAMA – Archetypen des Verhaltens MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 83): Die Verwendung von Mustern des Stochastischen Oszillators und des FrAMA – Archetypen des Verhaltens
Der Stochastik-Oszillator und der Fractal Adaptive Moving Average sind ein weiteres Indikatorpaar, das aufgrund seiner Fähigkeit, sich in einem MQL5 Expert Advisor zu ergänzen, verwendet werden kann. Wir betrachten den Stochastik aufgrund seiner Fähigkeit, Momentumverschiebungen zu erkennen, während der FrAMA zur Bestätigung der vorherrschenden Trends verwendet wird. Bei der Erkundung dieser Indikatorenkombination verwenden wir wie immer den MQL5-Assistenten, um ihr Potenzial zu ermitteln und zu testen.
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 82): Verwendung von TRIX- und WPR-Mustern mit DQN-Verstärkungslernen MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 82): Verwendung von TRIX- und WPR-Mustern mit DQN-Verstärkungslernen
Im letzten Artikel haben wir die Paarung von Ichimoku und ADX im Rahmen des Inferenzlernens untersucht. In diesem Beitrag greifen wir das Verstärkungslernen in Verbindung mit einem Indikatorpaar auf, das wir zuletzt in „Teil 68“ betrachtet haben. Der TRIX und Williams Percent Range. Unser Algorithmus für diese Überprüfung wird die Quantilregression DQN sein. Wie üblich stellen wir dies als nutzerdefinierte Signalklasse vor, die für die Implementierung mit dem MQL5-Assistenten entwickelt wurde.