English 日本語
preview
Entwicklung eines Toolkit zur Analyse von Preisaktionen (Teil 6): Der Mean Reversion Signal Reaper

Entwicklung eines Toolkit zur Analyse von Preisaktionen (Teil 6): Der Mean Reversion Signal Reaper

MetaTrader 5Handelssysteme | 28 April 2025, 14:41
59 0
Christian Benjamin
Christian Benjamin

Einführung

Mean Reversion (Rückkehr zur Mitte) ist eine faszinierende Handelsstrategie, die viele erfahrene Händler nutzen, um ihre Marktkenntnisse zu optimieren. Dieses Konzept beruht auf der Vorstellung, dass sich die Preise von Vermögenswerten tendenziell wieder auf ihre historischen Durchschnittswerte zubewegen und sich so strategische Gelegenheiten für zeitlich platzierte Handelsgeschäfte ergeben. Die manuelle Analyse von Kursbewegungen kann jedoch sowohl zeitaufwändig als auch anfällig für Fehler sein. Hier kann die Automatisierung das Handelserlebnis erheblich verbessern.

In diesem Artikel werden wir einen MQL5 Expert Advisor entwickeln, der darauf ausgelegt ist, Handelsmöglichkeiten zu identifizieren, die auf den Prinzipien der Mean Reversion beruhen. Durch die Verwendung eines 50-periodischen Exponential Moving Average (EMA) und des Relative Strength Index (RSI) generieren wir präzise Einstiegssignale, die es uns ermöglichen, von Marktschwankungen zu profitieren. Um den Handelsprozess noch intuitiver zu gestalten, zeigt unser EA Kauf- und Verkaufssignale als visuelle Pfeile direkt auf dem Chart an, zusammen mit einer informativen Zusammenfassung, die die Signale detailliert darstellt.

Wenn Sie Ihren Handel rationalisieren und die Macht der Automatisierung nutzen möchten, dann schauen Sie sich mit uns an, wie Sie einen MQL5 Expert Advisor erstellen können, der die Essenz der Mean Reversion einfängt. Schauen wir uns die Details an und werfen wir einen Blick auf das Inhaltsverzeichnis.



Was ist Mean Reversion?

Mean Reversion ist ein Finanzkonzept, das davon ausgeht, dass Vermögenspreise, Renditen oder andere Marktkennzahlen im Laufe der Zeit zu ihrem historischen Durchschnitt oder „Mittelwert“ zurückkehren. Dieser Mittelwert kann mit verschiedenen Methoden berechnet werden, z. B. mit dem Durchschnittspreis über einen bestimmten Zeitraum, einem gleitenden Durchschnitt oder einer Standard-Benchmark-Rendite.

Diese Theorie beruht auf der Annahme, dass extreme Marktschwankungen in der Regel nur von kurzer Dauer sind und sich die Preise letztlich stabilisieren. Händler und Analysten machen sich dieses Prinzip zunutze, um potenzielle Handelsmöglichkeiten zu erkennen, insbesondere wenn die Kurse deutlich von ihren historischen Durchschnittswerten abweichen.

Eine Kurze Geschichte und der Ursprung

Mean Reversion ist ein Konzept, das seine Wurzeln in der Statistik und im Finanzwesen hat und erstmals im frühen 20. Ursprünglich bei der Untersuchung von Naturphänomenen angewandt, wie z. B. der Tendenz von extremen Merkmalen in Populationen (z. B. Körpergröße), über Generationen hinweg zum Durchschnitt zurückzukehren, wurde die Mean Reversion später zu einem Eckpfeiler der Finanztheorie.
Auf den Finanzmärkten wurde diese Idee von Ökonomen wie John Maynard Keynes popularisiert, der feststellte, dass die Preise von Vermögenswerten häufig um ihre Fundamentalwerte schwanken. Dies führte zur Entwicklung von Handelsstrategien, die diese Tendenzen ausnutzen. Während der Dot-Com-Blase in den späten 1990er Jahren beispielsweise fielen viele überbewertete Technologieaktien schließlich wieder auf ihren fundamentalen Wert zurück, was die Mean Reversion in Aktion zeigt.

Praktische Beispiele für Mean Reversion

  • Aktienmarkt: Während der COVID-19-Pandemie wichen viele Aktien stark von ihren historischen Durchschnittswerten ab. So fielen beispielsweise die Aktien der Reisebranche drastisch unter ihre Durchschnittswerte, erholten sich aber später wieder, als sich der Markt normalisierte.
  • Währungspaare: Aufgrund der Politik der Zentralbanken und der wirtschaftlichen Fundamentaldaten kehren die Wechselkurse häufig zu ihren langfristigen Mittelwerten zurück. Das Währungspaar USD/JPY beispielsweise schwankt im Laufe der Zeit innerhalb einer vorhersehbaren Spanne.
  • Rohstoffe: Die Gold- und Ölpreise verhalten sich häufig wie ein Mittelwert, der sich nach extremen Preisspitzen oder -einbrüchen aufgrund geopolitischer Ereignisse wieder auf historische Niveaus einpendelt.

Definition von Mean Reversion im Kontext mit unserem Expert Advisor (EA)

Im Rahmen dieses Projekts bezieht sich der Begriff „Mean Reversion“ auf die Tendenz des Preises eines Vermögenswerts, zu seinem durchschnittlichen Niveau (Mittelwert) zurückzukehren, nachdem er sich deutlich über oder unter dieses Niveau bewegt hat. Dieses Prinzip bildet die Grundlage für die Handelssignale, die vom Expert Advisor (EA) generiert werden.

  • Mean (50 EMA): Der Code verwendet einen Exponential Moving Average (EMA) über 50 Perioden, um den Mittelwert darzustellen. Der EMA passt sich dynamisch an die jüngsten Kursdaten an und bietet so einen zuverlässigen Anhaltspunkt für den aktuellen Markttrend. Wenn der Kurs deutlich vom EMA abweicht, signalisiert dies eine mögliche Umkehrung. 
  • Reversion in Aktion: Ein Kaufsignal wird generiert, wenn der Kurs unter dem 50 EMA liegt und der RSI überverkauft ist. Der EA sagt eine Aufwärtsbewegung des Kurses zurück zum EMA voraus. Ein Verkaufssignal hingegen, wenn der Kurs über dem 50 EMA liegt und der RSI überkauft ist, bedeutet, dass der EA eine Kurskorrektur nach unten erwartet.


Überblick über die Strategie

Diese Strategie basiert auf dem Konzept der „Mean Reversion“, das besagt, dass die Preise nach erheblichen Abweichungen tendenziell zu ihrem Durchschnittsniveau zurückkehren. Dieses Verhalten schafft Handelsmöglichkeiten, wenn es mit zuverlässigen Indikatoren wie dem 50 EMA und dem Relative Strength Index (RSI) kombiniert wird.

  • Arbeitsprinzip

Die Strategie stützt sich auf zwei Schlüsselindikatoren:

  1. Der 50 EMA dient als Benchmark und stellt den dynamischen Durchschnittspreis über einen bestimmten Zeitraum dar. 
  2. Der RSI identifiziert überkaufte oder überverkaufte Bedingungen.

Wenn die Kurse zu weit von der 50 EMA abweichen und der RSI extreme Bedingungen bestätigt, geht die Strategie von einer wahrscheinlichen Umkehr zum Mittelwert aus.

Mean Reversion Konzept 

Abb. 1. Konzept von Mean Reversion

Das obige Chart (Abb. 1) veranschaulicht die Kursbewegungen im Verhältnis zum Exponential Moving Average (EMA) und hebt Handelssignale hervor, die bei extremen Werten des Relative Strength Index (RSI) ausgelöst werden.

Ein Kaufsignal wird generiert, wenn:
Der Kurs liegt unter dem 50 EMA, was auf eine Abweichung nach unten hindeutet. Der RSI liegt unter 30, was einen überverkauften Markt bestätigt. Diese Konstellation signalisiert eine mögliche Kurserholung zurück zum Mittelwert.

Ein Verkaufssignal tritt auf, wenn:
Der Kurs liegt über dem 50 EMA, was auf eine Abweichung nach oben hindeutet. Der RSI liegt über 70, was einen überkauften Markt bestätigt. Bei diesem Szenario wird eine Kurskorrektur zurück zum Mittelwert erwartet.

  • Visuelle Anhaltspunkte und Textzusammenfassung:
Grüne Pfeile zeigen Kaufsignale an. Rote Pfeile zeigen Verkaufssignale an. In der oberen rechten Ecke des Charts wird eine Übersicht als Text angezeigt, die den Signaltyp (Kauf/Verkauf) angibt. Die Strategie beinhaltet klare Stop-Loss- und Take-Profit-Regeln:
  1. Stop Loss: Bei Kaufpositionen unter dem jüngsten Tief und bei Verkaufspositionen über dem jüngsten Hoch platziert.
  2. Take Profit: Das Ziel liegt in der Nähe des 50 EMA, wo eine Preisumkehr erwartet wird.
  3. Mechanismus eines Cooldowns. Um redundante Signale und ein übermäßiges Handel zu vermeiden, wird eine Cooldown-Phase angewendet. Nach einem Signal wartet die Strategie eine bestimmte Anzahl von Balken ab, bevor sie neue Signale berücksichtigt. Diese Funktion trägt dazu bei, das Rauschen während volatiler Marktbedingungen zu reduzieren. 

Die ATR (Average True Range) wird verwendet, um dynamische Niveaus für die Festlegung von Take Profit (TP) und Stop Loss (SL) Werten festzulegen.

  • Die wichtigsten Vorteile der Strategie

Vorteile
Erklärung
Einfache, aber wirksame Logik
Kombiniert EMA und RSI für zuverlässige Mean-Reversion-Möglichkeiten.
Visuelle Signale 
Pfeile und Textzusammenfassungen machen Signale klar und umsetzbar.
Integration des Risikomanagements 
Klare Stop-Loss- und Take-Profit-Regeln schützen den Handel und steuern das Risiko. 
Rauschminderung Cooldown-Perioden helfen, überflüssige Signale in unruhigen Märkten herauszufiltern.
Konfigurierbare Parameter Sie können die EMA-Periode, die RSI-Stufen und die Cooldown-Einstellungen ganz einfach anpassen.

  • Der MQL5-Code für den Expert Advisor (EA).

//+------------------------------------------------------------------+
//|                                        Mean Reversion Reaper.mq5 |
//|                              Copyright 2024, Christian Benjamin. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Christian Benjamin"
#property link      "https://www.mql5.com"
#property version   "1.00"

#property strict
#property indicator_chart_window

//--- Input Parameters
input int EMA_Period = 50;                     // EMA Period
input int RSI_Period = 14;                     // RSI Period
input double RSI_Overbought = 70.0;            // RSI Overbought level
input double RSI_Oversold = 30.0;              // RSI Oversold level
input int CooldownBars = 3;                    // Cooldown bars between signals
input double ATR_Multiplier = 2.0;             // ATR Multiplier for TP and SL
input int ATR_Period = 14;                     // ATR Period
input color BuySignalColor = clrGreen;         // Buy signal arrow color
input color SellSignalColor = clrRed;          // Sell signal arrow color
input int ArrowSize = 2;                       // Arrow size
input color TextColor = clrDodgerBlue;         // Color for TP/SL text summary

//--- Global Variables
int EMA_Handle, RSI_Handle, ATR_Handle;
datetime lastSignalTime = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
// Create handles for indicators
   EMA_Handle = iMA(NULL, 0, EMA_Period, 0, MODE_EMA, PRICE_CLOSE);
   RSI_Handle = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE);
   ATR_Handle = iATR(NULL, 0, ATR_Period);

   if(EMA_Handle == INVALID_HANDLE || RSI_Handle == INVALID_HANDLE || ATR_Handle == INVALID_HANDLE)
     {
      Print("Failed to create indicator handles. Error: ", GetLastError());
      return INIT_FAILED;
     }

   Print("Mean Reversion EA initialized.");
   return INIT_SUCCEEDED;
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
// Clear the Signal Summary text object upon deinitialization
   ObjectDelete(0, "SignalSummary");
   Print("Mean Reversion EA deinitialized.");
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
// Avoid repeating signals on cooldown
   if(BarsSinceLastSignal() < CooldownBars)
      return;

   double EMA_Value = GetEMA();
   double RSI_Value = GetRSI();
   double ATR_Value = GetATR();

   if(EMA_Value == 0 || RSI_Value == 0 || ATR_Value == 0)
      return;

   double closePrice = iClose(NULL, 0, 0); // Current close price
   double highPrice = iHigh(NULL, 0, 1);   // Previous bar high
   double lowPrice = iLow(NULL, 0, 1);     // Previous bar low

// Check for Buy Signal
   if(closePrice < EMA_Value && RSI_Value <= RSI_Oversold)
     {
      DrawSignalArrow("BuySignal", closePrice, BuySignalColor);
      DisplayTextSummary("BUY", closePrice, lowPrice, ATR_Value);
      UpdateSignalTime();
     }
// Check for Sell Signal
   else
      if(closePrice > EMA_Value && RSI_Value >= RSI_Overbought)
        {
         DrawSignalArrow("SellSignal", closePrice, SellSignalColor);
         DisplayTextSummary("SELL", closePrice, highPrice, ATR_Value);
         UpdateSignalTime();
        }
  }

//+------------------------------------------------------------------+
//| Get EMA Value                                                    |
//+------------------------------------------------------------------+
double GetEMA()
  {
   double emaValues[1];
   if(CopyBuffer(EMA_Handle, 0, 0, 1, emaValues) <= 0)
      return 0;
   return emaValues[0];
  }

//+------------------------------------------------------------------+
//| Get RSI Value                                                    |
//+------------------------------------------------------------------+
double GetRSI()
  {
   double rsiValues[1];
   if(CopyBuffer(RSI_Handle, 0, 0, 1, rsiValues) <= 0)
      return 0;
   return rsiValues[0];
  }

//+------------------------------------------------------------------+
//| Get ATR Value                                                    |
//+------------------------------------------------------------------+
double GetATR()
  {
   double atrValues[1];
   if(CopyBuffer(ATR_Handle, 0, 0, 1, atrValues) <= 0)
      return 0;
   return atrValues[0];
  }

//+------------------------------------------------------------------+
//| Draw signal arrow on the chart                                   |
//+------------------------------------------------------------------+
void DrawSignalArrow(string signalType, double price, color arrowColor)
  {
   string arrowName = signalType + "_" + TimeToString(TimeCurrent(), TIME_MINUTES);
// Delete the existing arrow if it exists
   if(ObjectFind(0, arrowName) != -1)  // If the object exists
     {
      ObjectDelete(0, arrowName); // Delete the existing object
     }
   ObjectCreate(0, arrowName, OBJ_ARROW, 0, TimeCurrent(), price);
   ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, (signalType == "BuySignal") ? 233 : 234);
   ObjectSetInteger(0, arrowName, OBJPROP_COLOR, arrowColor);
   ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, ArrowSize);
  }

//+------------------------------------------------------------------+
//| Display TP and SL as text summary                                |
//+------------------------------------------------------------------+
void DisplayTextSummary(string signalType, double price, double refPrice, double ATR)
  {
   string objectName = "SignalSummary"; // Unique object name for the summary

// Delete the existing summary if it exists
   if(ObjectFind(0, objectName) != -1)  // If the object exists
     {
      ObjectDelete(0, objectName); // Delete the existing object
     }

   double SL = (signalType == "BUY") ? refPrice - (ATR * ATR_Multiplier) : refPrice + (ATR * ATR_Multiplier);
   double TP = (signalType == "BUY") ? price + (ATR * ATR_Multiplier) : price - (ATR * ATR_Multiplier);

   string summary = signalType + " Signal\n" +
                    "Price: " + DoubleToString(price, 5) + "\n" +
                    "TP: " + DoubleToString(TP, 5) + "\n" +
                    "SL: " + DoubleToString(SL, 5);

   ObjectCreate(0, objectName, OBJ_LABEL, 0, 0, 0);
   ObjectSetString(0, objectName, OBJPROP_TEXT, summary);
   ObjectSetInteger(0, objectName, OBJPROP_COLOR, TextColor);
   ObjectSetInteger(0, objectName, OBJPROP_FONTSIZE, 10); // Adjust font size if needed

// Position the label at the left upper corner
   ObjectSetInteger(0, objectName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
   ObjectSetInteger(0, objectName, OBJPROP_XDISTANCE, 10); // 10 pixels from the left
   ObjectSetInteger(0, objectName, OBJPROP_YDISTANCE, 10); // 10 pixels from the top
  }

//+------------------------------------------------------------------+
//| Update signal time to prevent frequent signals                   |
//+------------------------------------------------------------------+
void UpdateSignalTime()
  {
   lastSignalTime = iTime(NULL, 0, 0);
  }

//+------------------------------------------------------------------+
//| Calculate bars since the last signal                             |
//+------------------------------------------------------------------+
int BarsSinceLastSignal()
  {
   datetime currentBarTime = iTime(NULL, 0, 0);
   if(lastSignalTime == 0)
      return INT_MAX; // If no signal has been generated return a large number.
   return (int)((currentBarTime - lastSignalTime) / PeriodSeconds());
  }
//+------------------------------------------------------------------+


Code-Aufschlüsselung

Informationen im Kopfteil

Der Kopfteil enthält grundlegende Metadaten über den Expert Advisor (EA), einschließlich seines Namens, Autors und seiner Version. Diese Informationen sind hilfreich, um den EA zu identifizieren und die Zuordnung zu gewährleisten. Die #property-Direktiven geben Metadaten wie Copyright, Autorenlink und Version an, die angezeigt werden, wenn der EA verwendet wird. Außerdem zeigt die Direktive #property indicator_chart_window an, dass dieser EA im Hauptfenster des Charts und nicht in einem separaten Unterfenster arbeitet.
//+------------------------------------------------------------------+
//| Mean Reversion Reaper.mq5                                        |
//| Author: Christian Benjamin                                       |
//| Website: https://www.mql5.com                                    |
//+------------------------------------------------------------------+
#property copyright "Christian Benjamin"
#property link      "https://www.mql5.com"
#property version   "1.00"

// Indicator operates in the main chart window
#property indicator_chart_window

Eingabeparameter

Mit den Eingabeparametern können die Nutzer das Verhalten des EA anpassen, ohne den Code selbst zu verändern. Zu diesen Parametern gehören wichtige Einstellungen wie die Periodenlängen für EMA, RSI und ATR sowie die Schwellenwerte für überkaufte und überverkaufte RSI-Niveaus. Es kann eine Cooldown-Phase eingestellt werden, um ein zu häufiges Erzeugung von Signalen zu verhindern und so das Rauschen im Markt zu reduzieren und Klarheit zu schaffen. Die Nutzer können auch visuelle Elemente wie Pfeilfarben und -größen für Kauf- und Verkaufssignale sowie die Textfarbe für die im Chart angezeigte Zusammenfassung festlegen. Durch die Anpassung dieser Parameter können Händler den EA an ihre Handelsstrategie oder Marktbedingungen anpassen.

input int EMA_Period = 50;                     // EMA Period
input int RSI_Period = 14;                     // RSI Period
input double RSI_Overbought = 75.0;            // RSI Overbought level
input double RSI_Oversold = 25.0;              // RSI Oversold level
input int CooldownBars = 3;                    // Cooldown bars between signals
input double ATR_Multiplier = 2.0;             // ATR Multiplier for TP and SL
input int ATR_Period = 14;                     // ATR Period
input color BuySignalColor = clrGreen;         // Buy signal arrow color
input color SellSignalColor = clrRed;          // Sell signal arrow color
input int ArrowSize = 2;                       // Arrow size
input color TextColor = clrDodgerBlue;         // Color for TP/SL text summary

Globale Variablen

Der Abschnitt der globale Variablen definiert kritische Statusverfolgungsvariablen und Referenzen für Indikatoren, die von der EA verwendet werden. Die Handles für die Indikatoren EMA, RSI und ATR werden hier deklariert, ebenso wie lastSignalTime, das den Zeitstempel des letzten Signals speichert. Diese Variablen stellen sicher, dass der EA effizient auf die Indikatordaten zugreifen kann und eine Logik, wie z. B. die Cooldown-Phase zwischen den Signalen, durchsetzen kann.

int EMA_Handle, RSI_Handle, ATR_Handle;        // Handles for EMA, RSI, and ATR
datetime lastSignalTime = 0;                   // Tracks last signal time
Initialisierung (OnInit)

Die Funktion OnInit wird ausgeführt, wenn der EA in einen Chart geladen wird. Seine Hauptaufgabe ist die Initialisierung von Indikator-Handles mit Funktionen wie iMA für EMA, iRSI für RSI und iATR für ATR. Diese Handles sind für das Abrufen von Indikatorwerten während der Laufzeit unerlässlich. Die Funktion führt auch eine Fehlerprüfung durch, um sicherzustellen, dass alle Handles erfolgreich erstellt werden. Wenn die Erstellung eines Handles fehlschlägt, wird eine Fehlermeldung protokolliert, und der EA wird angehalten. Bei erfolgreicher Initialisierung wird eine Bestätigungsmeldung an das Journal ausgegeben, die signalisiert, dass der EA betriebsbereit ist.

int OnInit()
{
    EMA_Handle = iMA(NULL, 0, EMA_Period, 0, MODE_EMA, PRICE_CLOSE);
    RSI_Handle = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE);
    ATR_Handle = iATR(NULL, 0, ATR_Period);

    if (EMA_Handle == INVALID_HANDLE || RSI_Handle == INVALID_HANDLE || ATR_Handle == INVALID_HANDLE) {
        Print("Failed to create indicator handles. Error: ", GetLastError());
        return INIT_FAILED; // Stops EA if initialization fails
    }

    Print("Mean Reversion EA initialized.");
    return INIT_SUCCEEDED;
}

Aufräumen (OnDeinit)

Die Funktion OnDeinit wird automatisch aufgerufen, wenn der EA aus dem Chart entfernt oder neu initialisiert wird. Seine Hauptaufgabe besteht darin, die während der Laufzeit des EA erstellten Chartobjekte zu bereinigen. Insbesondere wird die Beschriftung „SignalSummary“ gelöscht, damit das Chart übersichtlich bleibt. Diese Funktion protokolliert auch eine Nachricht, die die Deinitialisierung des EAs bestätigt und damit Klarheit über den Beendigungsprozess schafft.

void OnDeinit(const int reason)
{
    ObjectDelete(0, "SignalSummary"); // Remove any signal summary text
    Print("Mean Reversion EA deinitialized.");
}

Signalverarbeitung (OnTick)

Die Funktion OnTick ist das Herzstück des EA und verarbeitet jeden neuen Markttick. Zunächst wird geprüft, ob die Cooldown-Phase seit dem letzten Signal verstrichen ist. Ist dies nicht der Fall, wird die Funktion vorzeitig beendet, um redundante Signale zu vermeiden. Anschließend werden die neuesten Werte für die Indikatoren EMA, RSI und ATR über die jeweiligen Handles abgerufen. Anhand dieser Werte bewertet der EA die Bedingungen für Kauf- oder Verkaufssignale.

Ein Kaufsignal wird ausgelöst, wenn der Kurs unter dem EMA liegt und der RSI sich im überverkauften Bereich befindet. Umgekehrt entsteht ein Verkaufssignal, wenn der Kurs über dem EMA liegt und der RSI überkauft ist. Für jedes Signal zeichnet die Funktion einen Pfeil auf dem Chart und zeigt eine Textzusammenfassung mit dem Preis, dem Stop-Loss (SL) und dem Take-Profit (TP) an. Der Zeitstempel des Signals wird aktualisiert, um den Mechanismus eines Cooldowns durchzusetzen.

void OnTick()
{
    if (BarsSinceLastSignal() < CooldownBars) return; // Skip if cooldown is active

    double EMA_Value = GetEMA();   // Fetch EMA value
    double RSI_Value = GetRSI();   // Fetch RSI value
    double ATR_Value = GetATR();   // Fetch ATR value

    double closePrice = iClose(NULL, 0, 0); // Current bar's close price

    if (closePrice < EMA_Value && RSI_Value <= RSI_Oversold) {
        // Buy Signal
        DrawSignalArrow("BuySignal", closePrice, BuySignalColor);
        DisplayTextSummary("BUY", closePrice, iLow(NULL, 0, 1), ATR_Value);
        UpdateSignalTime(); // Update last signal time
    } else if (closePrice > EMA_Value && RSI_Value >= RSI_Overbought) {
        // Sell Signal
        DrawSignalArrow("SellSignal", closePrice, SellSignalColor);
        DisplayTextSummary("SELL", closePrice, iHigh(NULL, 0, 1), ATR_Value);
        UpdateSignalTime(); // Update last signal time
    }
}

Hilfsfunktionen
  • Abrufen von Indikatorwerten

Hilfsfunktionen wie GetEMA, GetRSI und GetATR dienen dazu, die neuesten Werte der jeweiligen Indikatoren abzurufen. Diese Funktionen verwenden die CopyBuffer-Methode, um Daten aus Indikator-Handles zu extrahieren. Wenn der Datenabruf aus irgendeinem Grund fehlschlägt, geben die Funktionen Null zurück und signalisieren damit, dass der EA die Verarbeitung für den aktuellen Tick auslassen sollte. Diese Funktionen sind leichtgewichtig und modular, wodurch der Code sauber und wartbar bleibt.

double GetEMA()
{
    double emaValues[1];
    if (CopyBuffer(EMA_Handle, 0, 0, 1, emaValues) <= 0)
        return 0;
    return emaValues[0];
}

double GetRSI()
{
    double rsiValues[1];
    if (CopyBuffer(RSI_Handle, 0, 0, 1, rsiValues) <= 0)
        return 0;
    return rsiValues[0];
}

double GetATR()
{
    double atrValues[1];
    if (CopyBuffer(ATR_Handle, 0, 0, 1, atrValues) <= 0)
        return 0;
    return atrValues[0];
}
  • Zeichnen der Signalpfeile

Die Funktion DrawSignalArrow fügt dem Chart ein visuelles Signal hinzu, das ein Kauf- oder Verkaufssignal anzeigt. Es generiert dynamisch einen eindeutigen Namen für jeden Pfeil unter Verwendung des Signaltyps und der aktuellen Zeit, um Überschneidungen mit bestehenden Objekten zu vermeiden. Wenn bereits ein Pfeil mit demselben Namen existiert, wird er gelöscht, bevor ein neuer erstellt wird. Die Eigenschaften des Pfeils, wie z. B. Farbe, Größe und Typ, werden durch nutzerdefinierte Eingabeparameter bestimmt und ermöglichen eine klare und anpassbare visuelle Darstellung.

void DrawSignalArrow(string signalType, double price, color arrowColor)
{
    string arrowName = signalType + "_" + TimeToString(TimeCurrent(), TIME_MINUTES);
    if (ObjectFind(0, arrowName) != -1) ObjectDelete(0, arrowName);

    ObjectCreate(0, arrowName, OBJ_ARROW, 0, TimeCurrent(), price);
    ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, (signalType == "BuySignal") ? 233 : 234);
    ObjectSetInteger(0, arrowName, OBJPROP_COLOR, arrowColor);
    ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, ArrowSize);
}
  • Anzeige der Übersicht mit TP/SL

Die Funktion DisplayTextSummary liefert eine knappe Zusammenfassung des Signals, einschließlich des Preises, des Stop-Loss und Take-Profits. Diese Informationen werden als Test auf dem Chart in der oberen linken Ecke angezeigt. Die Funktion berechnet TP- und SL-Levels auf der Grundlage der ATR und ihres Multiplikators und bietet dynamische Levels, die sich der Marktvolatilität anpassen. Wenn bereits eine zusammenfassende Bezeichnung vorhanden ist, wird sie gelöscht, bevor eine neue erstellt wird. Dadurch wird sichergestellt, dass nur die neuesten Signalinformationen angezeigt werden, was die Übersichtlichkeit und Lesbarkeit erhöht.

void DisplayTextSummary(string signalType, double price, double refPrice, double ATR)
{
    string objectName = "SignalSummary";
    if (ObjectFind(0, objectName) != -1) ObjectDelete(0, objectName);

    double SL = (signalType == "BUY") ? refPrice - (ATR * ATR_Multiplier) : refPrice + (ATR * ATR_Multiplier);
    double TP = (signalType == "BUY") ? price + (ATR * ATR_Multiplier) : price - (ATR * ATR_Multiplier);

    string summary = signalType + " Signal\n" +
                     "Price: " + DoubleToString(price, 5) + "\n" +
                     "TP: " + DoubleToString(TP, 5) + "\n" +
                     "SL: " + DoubleToString(SL, 5);

    ObjectCreate(0, objectName, OBJ_LABEL, 0, 0, 0);
    ObjectSetString(0, objectName, OBJPROP_TEXT, summary);
    ObjectSetInteger(0, objectName, OBJPROP_COLOR, TextColor);
    ObjectSetInteger(0, objectName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
    ObjectSetInteger(0, objectName, OBJPROP_XDISTANCE, 10);
    ObjectSetInteger(0, objectName, OBJPROP_YDISTANCE, 10);
}
  • Cooldown-Management
Der EA erzwingt eine Cooldown-Phase zwischen den Signalen, um ein übermäßiges Handeln während volatiler Marktbedingungen zu vermeiden. Die Funktion UpdateSignalTime aktualisiert die Variable lastSignalTime mit dem Zeitstempel des letzten Signals, während die Funktion BarsSinceLastSignal die Anzahl der Balken berechnet, die seit dem letzten Signal verstrichen sind. Wenn noch kein Signal erzeugt wurde, wird ein großer Wert zurückgegeben, um den normalen Betrieb zu gewährleisten. Durch diesen Mechanismus wird sichergestellt, dass die Signale in angemessenen Abständen erfolgen, was den Händlern klarere und zuverlässigere Erkenntnisse liefert.
void UpdateSignalTime()
{
    lastSignalTime = iTime(NULL, 0, 0); // Store time of the current bar
}

int BarsSinceLastSignal()
{
    datetime currentBarTime = iTime(NULL, 0, 0);
    if (lastSignalTime == 0) return INT_MAX; // No signals generated yet
    return (int)((currentBarTime - lastSignalTime) / PeriodSeconds());
}


Tests und Ergebnisse

Lassen Sie uns über Backtests sprechen, ein wesentlicher Schritt bei der Bewertung Ihres Expert Advisors (EA). Im Wesentlichen geht es beim Backtests darum, Ihren EA auf historischen Marktdaten laufen zu lassen, um zu sehen, wie er in der Vergangenheit abgeschnitten hätte. Dieser Prozess ist von entscheidender Bedeutung, um festzustellen, ob Ihre Strategie mit den verschiedenen Marktbedingungen übereinstimmt, und um Erkenntnisse über ihre allgemeine Robustheit zu gewinnen.
Hier sind einige wichtige Punkte, die bei den Backtests zu beachten sind:
  • Historischer Datenbereich: Achten Sie darauf, dass Sie Daten verwenden, die verschiedene Marktbedingungen abdecken, wie z. B. Märkte mit Trend und mit Seitwärtsbewegungen. Dies hilft Ihnen zu beurteilen, wie anpassungsfähig Ihr EA ist.
  • Schlüsselmetriken: Konzentrieren Sie sich auf die Messung der Leistung anhand wichtiger Kennzahlen wie Gewinnfaktor, Gewinnrate, maximaler Drawdown und durchschnittliche Handelsdauer. So erhalten Sie ein klareres Bild davon, wie wirksam Ihre Strategie ist.
  • Optimierung: Zögern Sie nicht, mit Ihren Eingabeparametern - wie der EMA-Periode und den RSI-Levels - zu experimentieren, um die effektivsten Einstellungen für bestimmte Marktinstrumente oder Zeitrahmen zu finden.
  • Visuelle Validierung: Prüfen Sie schließlich immer, ob die von Ihrem EA generierten Pfeile und Signale mit Ihrer beabsichtigten Handelslogik übereinstimmen. Dies ist der Schlüssel, um sicherzustellen, dass Ihre Strategie so funktioniert, wie Sie sie geplant haben.

Wenn Sie Ihren EA unter Berücksichtigung dieser Überlegungen gründlich backtesten, können Sie eine zuverlässigere und effektivere Handelsstrategie entwickeln.

SIGNAL TEST

Abb. 2. Testergebnis 1

Das obige Chart zeigt die Tests, die in zwei verschiedenen Zeitrahmen für den Volatilitätsindex 75 (1s) über einen Zeitraum von 29 Tagen durchgeführt wurden. Im Folgenden sind die Ergebnisse der beiden Tests tabellarisch dargestellt.

Signalerzeugung und Leistungstabellen

  • Tabelle 1

Signalart  Zeitrahmen  Insgesamt erzeugte Signale
Echte Signale (wenn der Preis nach dem Signal gestiegen ist)
Kaufsignal-Genauigkeit(%)
Kaufen (buy) M30 41 33 80.5%
Verkaufen (sell) M30 21 15 71.4%

  • Tabelle 2

Signalart  Zeitrahmen  Insgesamt erzeugte Signale
Echte Signale (wenn der Preis nach dem Signal gestiegen ist)
Kaufsignal-Genauigkeit(%)
 Kaufen (buy) H1 19 14 73.6% 
 Verkaufen (sell) H1  13 61.5% 

Nachfolgend finden Sie eine Abbildung der Echtzeit-Testergebnisse für den Expert Advisor (EA).

Echtzeitsignal

Abb. 3. Testergebnis 2

Werfen wir auch einen Blick auf das folgende GIF.

TESTERGEBNIS

Abb. 4. Testergebnis 3

Referenzen:


Schlussfolgerung

Der Mean Reversion Reaper Expert Advisor (EA) bietet ein zuverlässiges System zur Generierung von Signalen, das auf den Prinzipien der Mean Reversion basiert und eine beeindruckende Rate seiner Genauigkeit von mindestens 70 % für Kaufsignale erreicht. Die Verwendung der Average True Range (ATR) für die Festlegung von Stop-Loss (SL) und Take-Profit (TP) ermöglicht es dem System, sich an die verschiedenen Volatilitätsbedingungen des Marktes anzupassen, was es besonders effektiv in schwankungsintensiven Märkten macht.

Es ist jedoch wichtig zu bedenken, dass der EA bei starken Markttrends weniger effektiv sein kann, was ein typisches Merkmal von Mean-Reversion-Strategien ist. Um Ihre Handelserfahrung zu verbessern, können Sie die Parameter feiner einstellen und zusätzliche Filter für Verkaufssignale ausprobieren. Da der EA den Handel nicht automatisch ausführt, können seine Signale besonders für manuelle Händler von Vorteil sein, die von kurzfristigen Umkehrungen profitieren möchten.

Im Wesentlichen kann der Mean Reversion Reaper EA ein mächtiger Verbündeter für Händler sein, die sich für Marktumkehrmuster interessieren. Wenn Sie die Marktbedingungen im Auge behalten und offen für Anpassungen Ihrer Strategie sind, können Sie das Potenzial dieses Instruments in Ihrem Handelsarsenal maximieren.

Datum Name des Werkzeugs  Beschreibung Version  Aktualisierungen  Hinweis
01/10/24 Chart Projector Skript zur Überlagerung der Kursentwicklung des Vortages mit Geistereffekt. 1.0 Erste Veröffentlichung Erstes Werkzeug in Lynnchris Tool Chest
18/11/24 Analytical Comment Er liefert Informationen zum Vortag in Tabellenform und nimmt die zukünftige Marktentwicklung vorweg. 1.0 Erste Veröffentlichung Zweites Werkzeug in Lynnchris Tool Chest
27/11/24 Analytics Master Regelmäßige Aktualisierung der Marktmetriken alle zwei Stunden  1.01 Zweite Veröffentlichung Drittes Werkzeug in Lynnchris Tool Chest
02/12/24 Analytics Forecaster  Regelmäßige Aktualisierung der Marktmetriken alle zwei Stunden mit Telegram-Integration 1.1 Dritte Auflage Werkzeug Nummer 4
09/12/24 Volatilitäts-Navigator Der EA analysiert die Marktbedingungen anhand der Indikatoren Bollinger Bands, RSI und ATR 1.0 Erste Veröffentlichung Werkzeug Nummer 5
19/12/24 Der Mean Reversion Signal Reaper  Analysiert den Markt anhand der Mean-Reversion-Strategie und liefert Signale  1.0  Erste Veröffentlichung  Werkzeug Nummer 6 

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

Beigefügte Dateien |
Mean_Reversion.mq5 (16.16 KB)
Entwicklung des Swing Entries Monitoring (EA) Entwicklung des Swing Entries Monitoring (EA)
Wenn sich das Jahr dem Ende zuneigt, denken langfristige Händler oft über die Geschichte des Marktes nach, um sein Verhalten und seine Trends zu analysieren und potenzielle zukünftige Bewegungen zu prognostizieren. In diesem Artikel befassen wir uns mit der Entwicklung eines Expert Advisors (EA) zur langfristigen Überwachung des Einstiegs mit MQL5. Ziel ist es, das Problem verpasster langfristiger Handelsmöglichkeiten zu lösen, das durch manuellen Handel und das Fehlen automatischer Überwachungssysteme verursacht wird. Wir werden eines der am häufigsten gehandelten Paare als Beispiel verwenden, um eine Strategie zu entwickeln und unsere Lösung effektiv zu gestalten.
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 52): Accelerator Oszillator MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 52): Accelerator Oszillator
Der Accelerator Oszillator ist ein weiterer Indikator von Bill Williams, der die Beschleunigung der Preisdynamik und nicht nur ihr Tempo verfolgt. Ähnlich wie der Awesome Oszillator, den wir in einem kürzlich erschienenen Artikel besprochen haben, versucht er, die Verzögerungseffekte zu vermeiden, indem er sich mehr auf die Beschleunigung als auf die Geschwindigkeit konzentriert. Wir untersuchen wie immer, welche Muster wir daraus ableiten können und welche Bedeutung sie für den Handel mit einem von einem Assistenten zusammengestellten Expert Advisor haben könnten.
Ensemble-Methoden zur Verbesserung von Klassifizierungsaufgaben in MQL5 Ensemble-Methoden zur Verbesserung von Klassifizierungsaufgaben in MQL5
In diesem Artikel stellen wir die Implementierung mehrerer Ensemble-Klassifikatoren in MQL5 vor und erörtern ihre Wirksamkeit in verschiedenen Situationen.
Meistern der Log-Einträge (Teil 2): Formatieren der Logs Meistern der Log-Einträge (Teil 2): Formatieren der Logs
In diesem Artikel erfahren Sie, wie Sie Protokollformatierer in der Bibliothek erstellen und anwenden können. Wir werden alles sehen, von der grundlegenden Struktur eines Formatierers bis hin zu praktischen Implementierungsbeispielen. Am Ende des Kurses werden Sie über die notwendigen Kenntnisse verfügen, um Protokolle in der Bibliothek zu formatieren und zu verstehen, wie alles hinter den Kulissen funktioniert.