English 日本語
preview
Aufbau des Kerzenmodells Trend Constraint (Teil 10): Strategisches Goldenes und Todeskreuz (EA)

Aufbau des Kerzenmodells Trend Constraint (Teil 10): Strategisches Goldenes und Todeskreuz (EA)

MetaTrader 5Beispiele | 25 April 2025, 15:06
38 0
Clemence Benjamin
Clemence Benjamin

Einführung

In diesem Artikel befassen wir uns mit der Integration des strategischen Goldenen Kreuzes (Golden Cross) und des Todeskreuzes (Death Cross) in den Expert Advisor Trend Constraint, um das Potenzial dieser bewährten gleitenden Durchschnitts-Crossover-Techniken zu erschließen. Unser Ziel ist es, die Trendfolgemöglichkeiten im algorithmischen Handel zu verbessern, indem wir diese Strategien automatisieren und so Präzision, Konsistenz und nahtlose Kompatibilität mit breiteren Handelssystemen gewährleisten.

Viele Händler sehen sich mit der Herausforderung konfrontiert, starke Aufwärts- und Abwärtstrends effektiv zu erkennen und zu nutzen. Während das Goldene Kreuz, das ein Aufwärtsmomentum signalisiert, und das Todeskreuz, das eine Abwärtsstimmung anzeigt, ihren Wert im manuellen Handel unter Beweis gestellt haben, führt ihre fehlende Automatisierung häufig zu verpassten Chancen und inkonsequenter Ausführung.

Durch die Integration der Golden und Todeskreuz Strategien in einen automatisierten Expert Advisor können Händler systematisch Umkehrsignale ausführen, ohne die Einschränkungen, die anderen Trendfolgestrategien auferlegt sind. Im Gegensatz zu eingeschränkten Strategien, die von der täglichen Marktstimmung abhängen, arbeiten diese Crossover-Strategien unabhängig, um Umkehrungen zu erkennen und darauf zu reagieren, sobald sie auftreten. Dadurch wird sichergestellt, dass potenzielle Wendepunkte früher erfasst werden, was die Reaktionsfähigkeit und die allgemeine Handelsleistung verbessert und gleichzeitig die Ausrichtung auf breitere Trendstrategien beibehält.

Hauptinhalt:

  1. Die Strategie des Goldenen und des Totenkreuzes verstehen
  2. Analyse ihrer Bedeutung im breiteren Kontext der Trendbeobachtung
  3. Anpassung an trendbegrenzende Bedingungen
  4. Umsetzung der Strategie mit MQL5
  5. Erste Strategietests
  6. Zusammenführung der neuen Strategie in der Trend Constraint
  7. Test- und Optimierungsergebnisse
  8. Schlussfolgerung


Die Strategie des Goldenen und des Totenkreuzes verstehen

Die Strategie des Goldenen und des Todeskreuzes sind zentrale Konzepte in der technischen Analyse, die dazu dienen, potenzielle Aufwärts- oder Abwärtstrends auf der Grundlage von gleitenden Durchschnittskreuzungen zu signalisieren. Ein Goldenes Kreuz tritt auf, wenn ein kürzerfristiger gleitender Durchschnitt, in der Regel der 50-Tage-Durchschnitt, einen längerfristigen gleitenden Durchschnitt, oft den 200-Tage-Durchschnitt, übersteigt. Dieses Ereignis wird als starkes Aufwärtssignal betrachtet, das darauf hindeutet, dass ein langfristiger Aufwärtstrend beginnen könnte. Anleger und Händler könnten dies als Gelegenheit sehen, Aktien zu kaufen oder zu halten, in der Erwartung eines Kursanstiegs. 

Umgekehrt ist das Todeskreuz das gegenteilige Szenario, bei dem der kurzfristige gleitende Durchschnitt unter den längerfristigen gleitenden Durchschnitt fällt, was auf einen potenziellen Abwärtstrend hindeutet. Dies wird als Warnung angesehen, dass der Markt in einen anhaltenden Rückgang übergehen könnte. Das Todeskreuz kann Anleger dazu veranlassen, zu verkaufen oder Leerverkäufe zu tätigen, oder zumindest Vorsicht walten zu lassen, da es auf eine Abschwächung der Marktbedingungen hindeutet. Diese beiden Signale werden nicht nur für direkte Handelsentscheidungen verwendet, sondern auch für eine umfassendere Analyse der Marktstimmung, obwohl sie nicht unfehlbar sind und zusammen mit anderen Indikatoren oder Analyseformen zur Bestätigung von Trends verwendet werden sollten.


Analyse ihrer Bedeutung im breiteren Kontext der Trendbeobachtung

Im breiteren Kontext der Trendfolgestrategien dienen das Goldene Kreuz und das Todeskreuz als grundlegende Instrumente zur Identifizierung des Beginns und der potenziellen Umkehrung von Markttrends. Bei der Trendfolge handelt es sich um eine Strategie, bei der Händler versuchen, von anhaltenden Marktpreisbewegungen zu profitieren, indem sie ihre Trades auf die Richtung des etablierten Trends ausrichten. So passen das Goldene Kreuz und das Totenkreuz in dieses Paradigma:

1. Identifizierung von Trends: Die Hauptfunktion dieser Kreuzungen besteht darin, klare Signale für den Beginn neuer Trends zu liefern. Das Goldene Kreuz signalisiert den Beginn eines Aufwärtstrends und veranlasst Trendfolger, Kaufpositionen einzugehen oder ihr Engagement zu erhöhen. Umgekehrt zeigt das Todeskreuz den Beginn eines Abwärtstrends an, was bedeutet, dass es an der Zeit ist, Kaufpositionen zu schließen oder Verkaufspositionen zu erwägen.
2. Bestätigung von Trends: Diese Signale dienen als Bestätigungen im Rahmen von Trendfolgestrategien. Ein Trendfolger könnte dieses Kreuzen zusammen mit anderen Indikatoren wie Preisbewegung, Volumen oder Momentum-Indikatoren verwenden, um zu überprüfen, ob sich tatsächlich ein Trend entwickelt. Dieser Multi-Indikator-Ansatz trägt dazu bei, Fehlsignale zu reduzieren, was bei der Trendfolge von entscheidender Bedeutung ist, da das Ziel darin besteht, dem Trend so lange wie möglich zu folgen.
3. Risikomanagement: Bei der Trendfolge ist das Risikomanagement entscheidend, da sich Trends unerwartet umkehren oder anhalten können. Die Goldenen Kreuze und die Todeskreuze können zur Festlegung von Stop-Loss oder zur Entscheidung über die Reduzierung oder Erhöhung der Positionsgröße verwendet werden. So könnte beispielsweise ein Durchbruch unter die gleitenden Durchschnitte nach einem Goldenen Kreuz nahelegen, die Stopps zu straffen oder das Engagement zu reduzieren.
4. Langfristige Perspektive: Diese Signale sind aufgrund der Verwendung längerer gleitender Durchschnittsperioden von Natur aus langfristig und passen gut zur Trendfolge-Philosophie, die darauf abzielt, eher die großen Bewegungen des Marktes als kurzfristige Schwankungen zu erfassen. Diese langfristige Ausrichtung hilft dabei, Marktrauschen herauszufiltern und sich auf wichtige Kursbewegungen zu konzentrieren.
5. Anpassungsfähigkeit: Obwohl die Strategie traditionell mit gleitenden 50- und 200-Tage-Durchschnitten festgelegt wird, kann sie für andere Zeitrahmen oder Marktbedingungen angepasst werden. Auf schnelllebigen Märkten könnten Händler kürzere Zeiträume verwenden, um schnellere Signale zu erhalten, während sie auf stabileren Märkten längere Zeiträume bevorzugen könnten, um zu vermeiden, dass sie durch kleinere Korrekturen aus dem Konzept gebracht werden.

Die Bedeutung des Goldenen Kreuzes und des Todeskreuzes im Rahmen der Trendfolgebewertung kann jedoch wie folgt kritisch analysiert werden:

  • Verzögerung: Einer der Hauptkritikpunkte ist die mit den gleitenden Durchschnitten verbundene Verzögerung. Zu dem Zeitpunkt, an dem diese Überkreuzungen auftreten, haben sich möglicherweise bereits wesentliche Teile des Trends verflüchtigt, was die Gewinne von Handelsgeschäften, die ausschließlich auf diesen Signalen beruhen, verringern kann.
  • Falsche Signale: Die Trendfolge birgt naturgemäß das Risiko falscher Ausbrüche oder vorzeitiger Trendumkehrungen. Die Goldenen und die Todeskreuze sind dagegen nicht immun und sollten daher Teil einer umfassenderen Strategie sein, die auch andere Formen der Analyse oder Bestätigungssignale umfasst.
  • Marktumfeld: Ihre Wirksamkeit kann je nach Marktbedingungen erheblich variieren. In trendigen Märkten können diese Signale sehr effektiv sein, aber in schwankenden oder unruhigen Märkten können sie zu zahlreichen Fehlstarts führen.


Anpassung an trendbegrenzende Bedingungen

Bei langfristigen Strategien kann die Auferlegung übermäßiger Beschränkungen ihr Potenzial begrenzen. Nehmen wir zum Beispiel ein Szenario an, bei dem die tägliche Marktstimmung rückläufig ist. Ein Signal eines Goldenen Kreuzes, das innerhalb desselben Tages auf niedrigeren Zeitebenen erscheint, könnte auf eine potenzielle Trendwende hindeuten, was wiederum bedeutet, dass der Markt nach oben drehen könnte. Wenn es zu solchen Umkehrungen kommt, passen sich andere eingeschränkte Strategien oft an die entstehende Trendstimmung an und richten sich nach der neuen Marktrichtung aus.

Um von dieser Dynamik zu profitieren, können die Strategien Todeskreuz und Goldenes Kreuz als unabhängige Module in den Trend Constraint EA integriert werden. Auf diese Weise kann der EA seine Leistung maximieren, indem er Umkehrpositionen erfasst, die mit dem neu entstehenden Trend übereinstimmen.

Dieser Ansatz gewährleistet:

  1. Flexibilität über Zeiträume hinweg: Der EA kann kurzfristige Umkehrungen (z. B. Goldene Kreuze) erkennen und sie mit breiteren Marktbewegungen in Einklang bringen, was die Anpassungsfähigkeit verbessert.
  2. Verbesserte Einstiegspunkte: Durch das frühzeitige Erkennen von Stimmungsumschwüngen kann der EA strategische Positionen einnehmen und die Verzögerung bei der Reaktion auf Marktveränderungen minimieren.
  3. Synergie zwischen Strategien: Durch die unabhängige Integration des Goldenen Kreuzes und des Todeskreuzes kann der EA deren Stärken nutzen, ohne die primären Trendfolgemechanismen außer Kraft zu setzen.

Durch die Anwendung dieses zweischichtigen Ansatzes ist der Trend Constraint EA in der Lage, Marktumschwünge effektiv zu steuern und gleichzeitig die langfristige Rentabilität zu erhalten. Gehen wir nun zur nächsten Phase über, in der wir diese Strategie umsetzen und integrieren werden.


Umsetzung der Strategie mit MQL5

Wenn ich einen Multi-Strategie-EA entwickle, entwerfe ich jede Strategie zunächst als unabhängigen EA. Dies ermöglicht ein gezieltes Testen und Verfeinern, bevor es in eine einzige, einheitliche Codebasis zusammengeführt wird. Nach dieser Methode werden wir zunächst den Strategic Golden and Todeskreuz EA aufschlüsseln und unabhängig entwickeln, bevor wir ihn in den Haupt-Expert Advisor integrieren.

Öffnen Sie wie gewohnt Ihre MetaEditor 5-Anwendung von Ihrem Desktop aus, oder drücken Sie F4 in Ihrem MetaTrader 5-Terminal, um sie direkt zu starten. Befolgen Sie die unten beschriebenen Entwicklungsschritte. Anfängern wird empfohlen, den Code manuell einzutippen, anstatt ihn zu kopieren und einzufügen, da dies die Fertigkeit verstärkt und das Verständnis vertieft.

Wir beginnen hier mit unserem Goldenen und dem Totenkreuz:

Kopfzeile und Metadaten:

Dies ist der oberste Teil des Programms. Wir beginnen mit der Definition der Metadaten, um Klarheit und Professionalität zu gewährleisten. In den Metadaten erhält das Programm den Namen „Strategic Golden & Death Cross EA“ und weitere Angaben zum Copyright, eine Beschreibung und die Versionsnummer. Dieser Schritt hilft uns bei der Organisation des Projekts und stellt sicher, dass unsere Arbeit beim Einsatz in MetaTrader 5 richtig zugeordnet wird. Indem wir die Metadaten auf diese Weise einrichten, schaffen wir eine professionelle und gut dokumentierte Grundlage für unseren EA.

//+------------------------------------------------------------------+ 
//|                       Strategic Golden & Death Cross EA.mq5      |
//|                           Copyright 2024, Clemence Benjamin      |
//|        https://www.mql5.com/en/users/billionaire2024/seller      |
//+------------------------------------------------------------------+
#property copyright "Clemence Benjamin"
#property description "GOLDEN AND DEATH CROSS"
#property version "1.0"

Initialization: Einbinden und Instanziieren des Handelsobjektes „trade“.

Um die Ausführung des Handels zu vereinfachen, binden wir die MQL5-Handelsbibliothek mit #include<Trade\Trade.mqh> ein. Diese Bibliothek bietet Zugang zu leistungsstarken Handelsfunktionen. Wir instanziieren die Klasse CTrade für den Handel, sodass der EA Operationen wie Kauf, Verkauf und Schließen von Positionen ohne manuelle Implementierung dieser Routinen durchführen kann. Dies verringert die Komplexität und macht den Code zuverlässiger. Mit diesem Setup können wir uns auf die Strategie konzentrieren und uns bei der Ausführung unserer Aufträge auf die Handelsmanagement-Bibliothek verlassen.

#include<Trade\Trade.mqh>;
CTrade trade;

Eingabe Parameter:

Wir beginnen mit der Definition von vom Nutzer einstellbaren Parametern, um den EA flexibel und anpassbar zu machen.

Zum Beispiel:

  • Mit LotSize können wir das Handelsvolumen kontrollieren.
  • Die Preisabweichung gibt an, welche Preisabweichungen während der Ausführung zulässig sind.
  • FastEMAPeriod und SlowEMAPeriod definieren die Periodenlängen der gleitenden Durchschnitte, die das Rückgrat des Golden und des Todeskreuz bilden.
input double LotSize = 1.0;            // Trade volume (lots)
input int Slippage = 20;               // Slippage in points
input int TimerInterval = 10000;       // Timer interval in seconds
input double TakeProfitPips = 100;     // Take Profit in pips
input double StopLossPips = 50;        // Stop Loss in pips
input int FastEMAPeriod = 50;          // Fast EMA period (default 50)
input int SlowEMAPeriod = 200;         // Slow EMA period (default 200)

Durch die Einstellung dieser Parameter ermöglichen wir den Nutzern, den EA an ihre spezifischen Handelsbedingungen anzupassen.

Initialisierung und Timer-Setup:

Stellen wir sicher, dass der EA richtig initialisiert wird. In der Funktion OnInit() fügen wir eine Prüfung hinzu, um festzustellen, ob genügend Balken zur Berechnung des langsamen EMA vorhanden sind. Wenn nicht, protokolliert der EA einen Fehler und bricht die Ausführung ab. Dadurch wird sichergestellt, dass die Strategie nur dann ausgeführt wird, wenn genügend Daten vorhanden sind.

int OnInit()
{
   //--- create timer
   EventSetTimer(TimerInterval);

   //--- Check if there are enough bars for EMA calculation
   if(Bars(_Symbol,PERIOD_CURRENT)<SlowEMAPeriod)
   {
      Print("Not enough bars for EMA calculation");
      return(INIT_FAILED);
   }
   return(INIT_SUCCEEDED);
}

Außerdem verwenden wir EventSetTimer(), um die Funktion OnTimer() in regelmäßigen Abständen aufzurufen und die Handelslogik auszuführen. Die Funktion OnDeinit() sorgt dafür, dass der Timer deaktiviert wird, wenn der EA entfernt wird, wodurch Ressourcen frei werden.

void OnDeinit(const int reason)
{
   //--- delete timer
   EventKillTimer();
}

Handelslogik in OnTimer():

Kommen wir nun zum Kern der Strategie innerhalb der Funktion OnTimer():

EMA-Berechnung:

Zunächst werden mit iMA() die Handles für die schnellen und langsamen EMAs erstellt und ihre Werte mit CopyBuffer() abgefragt. Diese EMAs sind wichtig, um Einstiegssignale zu erkennen.

int fastEMAHandle = iMA(_Symbol, PERIOD_CURRENT, FastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
int slowEMAHandle = iMA(_Symbol, PERIOD_CURRENT, SlowEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);

double fastEMAArray[], slowEMAArray[];
CopyBuffer(fastEMAHandle, 0, 0, 2, fastEMAArray);
CopyBuffer(slowEMAHandle, 0, 0, 2, slowEMAArray);

Abruf von Marktdaten:

Als Nächstes rufen wir wichtige Marktdaten ab, wie z. B. den Briefkurs, den Geldkurs und die Punktgröße, um präzise Berechnungen für Stop-Loss und Take-Profit zu gewährleisten.

double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);

Eintrittssignale:

Hier legen wir die Bedingungen für die Eröffnung von Kauf- und Verkaufsgeschäften fest. Ein Goldenes Kreuz (der schnelle EMA kreuzt den langsamen EMA nach oben) signalisiert einen Kauf, während ein Todeskreuz (der schnelle EMA kreuzt den langsamen EMA nach unten) einen Verkauf signalisiert.

if(fastEMAArray[0] > slowEMAArray[0] && fastEMAArray[1] <= slowEMAArray[1]) // Death Cross 
{
   double sl = NormalizeDouble(ask + StopLossPips * point, _Digits);
   trade.Sell(LotSize, _Symbol, ask, sl);
}
else if(fastEMAArray[0] < slowEMAArray[0] && fastEMAArray[1] >= slowEMAArray[1]) // Golden Cross
{
   double sl = NormalizeDouble(bid - StopLossPips * point, _Digits);
   trade.Buy(LotSize, _Symbol, bid, sl);
}

Ausstiegssignale:

Stellen wir sicher, dass bestehende Positionen geschlossen werden, wenn sich das gegenteilige Signal ausbildet. Auf diese Weise wird die Strategie an die sich ändernden Marktbedingungen angepasst.

if((PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && fastEMAArray[0] < slowEMAArray[0]) ||
   (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && fastEMAArray[0] > slowEMAArray[0]))
{
   trade.PositionClose(PositionGetInteger(POSITION_TICKET));
}

Fehlerbehandlung:

Jetzt fügen wir Routinen zur Fehlerbehandlung hinzu, um alle Probleme bei der Handelsausführung oder Positionsschließung zu protokollieren, was bei der Fehlersuche hilft und eine reibungslose Leistung gewährleistet.

if(!trade.Sell(LotSize, _Symbol, ask, sl))
{
   Print("Sell order error: ", GetLastError());
}

Hier ist unser vollständiger Code:

//+------------------------------------------------------------------+ 
//|                          Golden & Death Cross Strategy.mq5       |
//|                           Copyright 2024, Clemence Benjamin      |
//|        https://www.mql5.com/en/users/billionaire2024/seller      |
//+------------------------------------------------------------------+

#property copyright "Clemence Benjamin"
#property description "GOLDEN AND DEATH CROSS"
#property version "1.0"


//+------------------------------------------------------------------+
//| Includes                                                         |
//+------------------------------------------------------------------+
#include<Trade\Trade.mqh>;
CTrade trade;

//+------------------------------------------------------------------+
//| Input parameters                                                 |
//+------------------------------------------------------------------+
input double LotSize = 1.0;            // Trade volume (lots)
input int Slippage = 20;               // Slippage in points
input int TimerInterval = 1000;          // Timer interval in seconds
input double StopLossPips = 1500;        // Stop Loss in pips
input int FastEMAPeriod = 50;          // Fast EMA period (default 50)
input int SlowEMAPeriod = 200;         // Slow EMA period (default 200)

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   //--- create timer
   EventSetTimer(TimerInterval);
   
   //--- Check if there are enough bars to calculate the EMA
   if(Bars(_Symbol,PERIOD_CURRENT)<SlowEMAPeriod)
     {
      Print("Not enough bars for EMA calculation");
      return(INIT_FAILED);
     }
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   //--- delete timer
   EventKillTimer();
  }
//+------------------------------------------------------------------+
//| Expert timer function                                            |
//+------------------------------------------------------------------+
void OnTimer()
{
   bool hasPosition = PositionSelect(_Symbol);
   
   int fastEMAHandle = iMA(_Symbol, PERIOD_CURRENT, FastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
   int slowEMAHandle = iMA(_Symbol, PERIOD_CURRENT, SlowEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);

   if(fastEMAHandle < 0 || slowEMAHandle < 0)
   {
      Print("Failed to create EMA handles. Error: ", GetLastError());
      return;
   }

   double fastEMAArray[], slowEMAArray[];
   if(CopyBuffer(fastEMAHandle, 0, 0, 2, fastEMAArray) <= 0 ||
      CopyBuffer(slowEMAHandle, 0, 0, 2, slowEMAArray) <= 0)
   {
      Print("Failed to copy EMA data. Error: ", GetLastError());
      return;
   }

   double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);

   if(!hasPosition)
   {
      if(fastEMAArray[0] > slowEMAArray[0] && fastEMAArray[1] <= slowEMAArray[1]) // Death Cross 
      {
         
         double sl = NormalizeDouble(ask + StopLossPips * point, _Digits);
         if(!trade.Sell(LotSize, _Symbol, ask, sl ))
            Print("Buy order error ", GetLastError());
         else
            Print("Buy order opened with TP ", " and SL ", StopLossPips, " pips");
      }
      else if(fastEMAArray[0] < slowEMAArray[0] && fastEMAArray[1] >= slowEMAArray[1]) // Golden Cross
      {
         
         double sl = NormalizeDouble(bid - StopLossPips * point, _Digits);
         if(!trade.Buy(LotSize, _Symbol, bid, sl ))
            Print("Sell order error ", GetLastError());
         else
            Print("Sell order opened with TP ",  " and SL ", StopLossPips, " pips");
      }
   }
   else
   {
     if((PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && fastEMAArray[0] < slowEMAArray[0]) ||
         (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && fastEMAArray[0] > slowEMAArray[0]))
    {
         ulong ticket = PositionGetInteger(POSITION_TICKET);
         if(!trade.PositionClose(ticket))
            Print("Failed to close position (Ticket: ", ticket, "). Error: ", GetLastError());
         else  
            Print("Position closed : ", ticket);
      }
   }
}

//+------------------------------------------------------------------+


Erste Strategietests

Nachdem wir den Code erfolgreich kompiliert haben, können wir nun die Leistung unserer Strategie mit dem Strategy Tester testen. Nachfolgend sehen Sie Bilder der Testergebnisse, bevor wir die Strategie in den Trend Constraint Expert Advisor integriert haben.

Einstellungen des Strategietesters

Einstellungen des Strategietesters: Boom 500 Index

Eingabe-Einstellungen

Eingabe-Einstellungen: Boom 500 Index

Boom 500 Index M5: Testen des Goldenen & des Todeskreuzes

Nach den ersten Tests funktioniert die Logik der Auftragsausführung reibungslos, aber die Ausstiegsstrategie muss verbessert werden. Bei der manuellen Beobachtung im Strategietester sind mir viele Positionen aufgefallen, die einen Gewinn hätten erzielen können, aber mit kleinen Gewinnen oder sogar Verlusten abgeschlossen wurden. Dies ist darauf zurückzuführen, dass die Umkehrkurse nach einem starken Rückgang der Kurse gekreuzt wurden, wodurch die Gewinne begrenzt wurden. Während der Marktkonsolidierung führten viele falsche Kreuzungen zu Verlusten. Um solch große Verluste zu vermeiden, muss die Ausstiegsstrategie verbessert werden.


Zusammenführung der neuen Strategie in der Trend Constraint

Schließlich haben wir das Ziel erreicht, einen Expert Advisor für mehrere Strategien zu erstellen, indem wir die zuvor entwickelte Strategie integriert haben. Um Ihr Gedächtnis für die bestehenden Strategien aufzufrischen, können Sie (Teil 9) erneut lesen. Hier finden Sie eine Liste der bereits integrierten Strategien:

  • Trendfolge
  • Donchian Channel Ausbruch
  • Divergenz-Strategie

Heute fügen wir die vierte Strategie hinzu, die, wie ich bereits erklärt habe, unabhängig arbeitet und frei von Zwängen ist, sodass sie alle Umkehrmöglichkeiten nutzen kann. Um dies zu erreichen, werden wir den aktuellen Trend Constraint Expert ändern, indem wir einen booleschen Schalter für die neue Strategie des Goldenen und des Todeskreuzes hinzufügen. Außerdem werden wir andere Codeabschnitte in die entsprechenden Funktionen des Hauptcodes umstrukturieren.

Um Konflikte mit anderen Begriffen, die bereits im Hauptprogramm vorhanden sind, zu vermeiden, haben wir den Variablen, die mit der Strategie des Goldenen und des Todeskreuzes verbunden sind, ein eindeutiges Präfix hinzugefügt. Zum Beispiel haben wir LotSize in GDC_LotSize = 1.0 umbenannt, um Klarheit zu schaffen und Verwirrung zu vermeiden.

Nachstehend finden Sie den vollständigen, fehlerfreien Code. Die neuen Ergänzungen und Änderungen sind zum besseren Verständnis und zur Klarheit deutlich hervorgehoben.

//+------------------------------------------------------------------+
//|                                      Trend Constraint Expert.mq5 |
//|                                Copyright 2024, Clemence Benjamin |
//|             https://www.mql5.com/en/users/billionaire2024/seller |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Clemence Benjamini"
#property link      "https://www.mql5.com/en/users/billionaire2024/seller"
#property version   "1.03"

#include <Trade\Trade.mqh>
CTrade trade;

// Input parameters for controlling strategies
input bool UseTrendFollowingStrategy = false;   // Enable/Disable Trend Following Strategy
input bool UseBreakoutStrategy = false;         // Enable/Disable Breakout Strategy
input bool UseDivergenceStrategy = false;       // Enable/Disable Divergence Strategy
input bool UseGoldenDeathCrossStrategy = true;  // Enable/Disable Golden/Death Cross Strategy

// Input parameters for Golden/Death Cross Strategy
input double GDC_LotSize = 1.0;            // Trade volume (lots) for Golden Death Cross
input int GDC_Slippage = 20;               // Slippage in points for Golden Death Cross
input int GDC_TimerInterval = 1000;        // Timer interval in seconds for Golden Death Cross
input double GDC_StopLossPips = 1500;      // Stop Loss in pips for Golden Death Cross
input int GDC_FastEMAPeriod = 50;          // Fast EMA period for Golden Death Cross
input int GDC_SlowEMAPeriod = 200;         // Slow EMA period for Golden Death Cross

int GDC_fastEMAHandle, GDC_slowEMAHandle;  // Handles for EMA indicators in Golden Death Cross

// Global variables
double prevShortMA, prevLongMA;

// Input parameters for Trend Constraint Strategy
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 double Lots = 0.1;                // Lot size
input double StopLoss = 100;            // Stop Loss in points
input double TakeProfit = 200;          // Take Profit in points
input double TrailingStop = 50;         // Trailing Stop in points
input int    MagicNumber = 12345678;    // Magic number for the Trend Constraint EA
input int    OrderLifetime = 43200;     // Order lifetime in seconds (12 hours)

// Input parameters for Breakout Strategy
input int InpDonchianPeriod = 20;       // Period for Donchian Channel
input double RiskRewardRatio = 1.5;     // Risk-to-reward ratio
input double LotSize = 0.1;             // Default lot size for trading
input double pipsToStopLoss = 15;       // Stop loss in pips for Breakout
input double pipsToTakeProfit = 30;     // Take profit in pips for Breakout

// Input parameters for Divergence Strategy
input int DivergenceMACDPeriod = 12;    // MACD Fast EMA period
input int DivergenceSignalPeriod = 9;   // MACD Signal period
input double DivergenceLots = 1.0;      // Lot size for Divergence trades
input double DivergenceStopLoss = 300;   // Stop Loss in points for Divergence
input double DivergenceTakeProfit = 500; // Take Profit in points for Divergence
input int DivergenceMagicNumber = 87654321;     // Magic number for Divergence Strategy
input int DivergenceLookBack = 8;       // Number of periods to look back for divergence
input double profitLockerPoints  = 20;  // Number of profit points to lock

// Indicator handle storage
int rsi_handle;                         
int handle;                             // Handle for Donchian Channel
int macd_handle;

double ExtUpBuffer[];                   // Upper Donchian buffer
double ExtDnBuffer[];                   // Lower Donchian buffer
double ExtMacdBuffer[];                 // MACD buffer
double ExtSignalBuffer[];               // Signal buffer
int globalMagicNumber;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
    prevShortMA = 0.0;
    prevLongMA = 0.0;
    // Initialize RSI handle
    rsi_handle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE);
    if (rsi_handle == INVALID_HANDLE)
    {
        Print("Failed to create RSI indicator handle. Error: ", GetLastError());
        return INIT_FAILED;
    }

    // Create a handle for the Donchian Channel
    handle = iCustom(_Symbol, PERIOD_CURRENT, "Free Indicators\\Donchian Channel", InpDonchianPeriod);
    if (handle == INVALID_HANDLE)
    {
        Print("Failed to load the Donchian Channel indicator. Error: ", GetLastError());
        return INIT_FAILED;
    }

    // Initialize MACD handle for divergence
    globalMagicNumber = DivergenceMagicNumber;
    macd_handle = iMACD(_Symbol, PERIOD_CURRENT, DivergenceMACDPeriod, 26, DivergenceSignalPeriod, PRICE_CLOSE);
    if (macd_handle == INVALID_HANDLE)
    {
        Print("Failed to create MACD indicator handle for divergence strategy. Error: ", GetLastError());
        return INIT_FAILED;
    }
    
    
    if(UseGoldenDeathCrossStrategy)
{
    // Check if there are enough bars to calculate the EMA
    if(Bars(_Symbol, PERIOD_CURRENT) < GDC_SlowEMAPeriod)
    {
        Print("Not enough bars for EMA calculation for Golden Death Cross");
        return INIT_FAILED;
    }
    GDC_fastEMAHandle = iMA(_Symbol, PERIOD_CURRENT, GDC_FastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
    GDC_slowEMAHandle = iMA(_Symbol, PERIOD_CURRENT, GDC_SlowEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
    if(GDC_fastEMAHandle < 0 || GDC_slowEMAHandle < 0)
    {
        Print("Failed to create EMA handles for Golden Death Cross. Error: ", GetLastError());
        return INIT_FAILED;
    }
}

    // Resize arrays for MACD buffers
    ArrayResize(ExtMacdBuffer, DivergenceLookBack);
    ArrayResize(ExtSignalBuffer, DivergenceLookBack);

    Print("Trend Constraint Expert initialized.");
    return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    IndicatorRelease(rsi_handle);
    IndicatorRelease(handle);
    IndicatorRelease(macd_handle);
    Print("Trend Constraint Expert deinitialized.");
}

//+------------------------------------------------------------------+
//| Check Golden/Death Cross Trading Logic                           |
//+------------------------------------------------------------------+
void CheckGoldenDeathCross()
{
    double fastEMAArray[2], slowEMAArray[2];
    double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
    double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
    double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);

    if(CopyBuffer(GDC_fastEMAHandle, 0, 0, 2, fastEMAArray) <= 0 ||
       CopyBuffer(GDC_slowEMAHandle, 0, 0, 2, slowEMAArray) <= 0)
    {
        Print("Failed to copy EMA data for Golden Death Cross. Error: ", GetLastError());
        return;
    }

    bool hasPosition = PositionSelect(_Symbol);

    if(!hasPosition)
    {
        if(fastEMAArray[0] > slowEMAArray[0] && fastEMAArray[1] <= slowEMAArray[1]) // Death Cross 
        {
            double sl = NormalizeDouble(ask + GDC_StopLossPips * point, _Digits);
            if(!trade.Sell(GDC_LotSize, _Symbol, ask, sl ))
                Print("Sell order error for Golden Death Cross ", GetLastError());
            else
                Print("Sell order opened for Golden Death Cross with SL ", GDC_StopLossPips, " pips");
        }
        else if(fastEMAArray[0] < slowEMAArray[0] && fastEMAArray[1] >= slowEMAArray[1]) // Golden Cross
        {
            double sl = NormalizeDouble(bid - GDC_StopLossPips * point, _Digits);
            if(!trade.Buy(GDC_LotSize, _Symbol, bid, sl ))
                Print("Buy order error for Golden Death Cross ", GetLastError());
            else
                Print("Buy order opened for Golden Death Cross with SL ", GDC_StopLossPips, " pips");
        }
    }
    else
    {
        if((PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && fastEMAArray[0] < slowEMAArray[0]) ||
           (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && fastEMAArray[0] > slowEMAArray[0]))
        {
            ulong ticket = PositionGetInteger(POSITION_TICKET);
            if(!trade.PositionClose(ticket))
                Print("Failed to close position for Golden Death Cross (Ticket: ", ticket, "). Error: ", GetLastError());
            else  
                Print("Position closed for Golden Death Cross: ", ticket);
        }
    }
}

//+------------------------------------------------------------------+
//| Check Trend Following Strategy                                   |
//+------------------------------------------------------------------+
void CheckTrendFollowing()
{
   if (PositionsTotal() >= 2) return; // Ensure no more than 2 orders from this strategy

    double rsi_value;
    double rsi_values[];
    if (CopyBuffer(rsi_handle, 0, 0, 1, rsi_values) <= 0)
    {
        Print("Failed to get RSI value. Error: ", GetLastError());
        return;
    }
    rsi_value = rsi_values[0];

    double ma_short = iMA(_Symbol, PERIOD_CURRENT, 50, 0, MODE_EMA, PRICE_CLOSE);
    double ma_long = iMA(_Symbol, PERIOD_CURRENT, 200, 0, MODE_EMA, PRICE_CLOSE);

    bool is_uptrend = ma_short > ma_long;
    bool is_downtrend = ma_short < ma_long;

    if (is_uptrend && rsi_value < RSI_Oversold)
    {
        double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
        double stopLossPrice = currentPrice - StopLoss * _Point;
        double takeProfitPrice = currentPrice + TakeProfit * _Point;

        // Corrected Buy method call with 6 parameters
        if (trade.Buy(Lots, _Symbol, 0, stopLossPrice, takeProfitPrice, "Trend Following Buy"))
        {
            Print("Trend Following Buy order placed.");
        }
    }
    else if (is_downtrend && rsi_value > RSI_Overbought)
    {
        double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
        double stopLossPrice = currentPrice + StopLoss * _Point;
        double takeProfitPrice = currentPrice - TakeProfit * _Point;

        // Corrected Sell method call with 6 parameters
        if (trade.Sell(Lots, _Symbol, 0, stopLossPrice, takeProfitPrice, "Trend Following Sell"))
        {
            Print("Trend Following Sell order placed.");
        }
    }
}

//+------------------------------------------------------------------+
//| Check Breakout Strategy                                          |
//+------------------------------------------------------------------+
void CheckBreakoutTrading()
{
    if (PositionsTotal() >= 2) return; // Ensure no more than 2 orders from this strategy

    ArrayResize(ExtUpBuffer, 2);
    ArrayResize(ExtDnBuffer, 2);

    if (CopyBuffer(handle, 0, 0, 2, ExtUpBuffer) <= 0 || CopyBuffer(handle, 2, 0, 2, ExtDnBuffer) <= 0)
    {
        Print("Error reading Donchian Channel buffer. Error: ", GetLastError());
        return;
    }

    double closePrice = iClose(_Symbol, PERIOD_CURRENT, 0);
    double lastOpen = iOpen(_Symbol, PERIOD_D1, 1);
    double lastClose = iClose(_Symbol, PERIOD_D1, 1);

    bool isBullishDay = lastClose > lastOpen;
    bool isBearishDay = lastClose < lastOpen;

    if (isBullishDay && closePrice > ExtUpBuffer[1])
    {
        double stopLoss = closePrice - pipsToStopLoss * _Point;
        double takeProfit = closePrice + pipsToTakeProfit * _Point;
        if (trade.Buy(LotSize, _Symbol, 0, stopLoss, takeProfit, "Breakout Buy") > 0)
        {
            Print("Breakout Buy order placed.");
        }
    }
    else if (isBearishDay && closePrice < ExtDnBuffer[1])
    {
        double stopLoss = closePrice + pipsToStopLoss * _Point;
        double takeProfit = closePrice - pipsToTakeProfit * _Point;
        if (trade.Sell(LotSize, _Symbol, 0, stopLoss, takeProfit, "Breakout Sell") > 0)
        {
            Print("Breakout Sell order placed.");
        }
    }
}

//+------------------------------------------------------------------+
//| Check Divergence Trading                                         |
//+------------------------------------------------------------------+
bool CheckBullishRegularDivergence()
{
    double priceLow1 = iLow(_Symbol, PERIOD_CURRENT, 2);
    double priceLow2 = iLow(_Symbol, PERIOD_CURRENT, DivergenceLookBack);
    double macdLow1 = ExtMacdBuffer[2];
    double macdLow2 = ExtMacdBuffer[DivergenceLookBack - 1];

    return (priceLow1 < priceLow2 && macdLow1 > macdLow2);
}

bool CheckBullishHiddenDivergence()
{
    double priceLow1 = iLow(_Symbol, PERIOD_CURRENT, 2);
    double priceLow2 = iLow(_Symbol, PERIOD_CURRENT, DivergenceLookBack);
    double macdLow1 = ExtMacdBuffer[2];
    double macdLow2 = ExtMacdBuffer[DivergenceLookBack - 1];

    return (priceLow1 > priceLow2 && macdLow1 < macdLow2);
}

bool CheckBearishRegularDivergence()
{
    double priceHigh1 = iHigh(_Symbol, PERIOD_CURRENT, 2);
    double priceHigh2 = iHigh(_Symbol, PERIOD_CURRENT, DivergenceLookBack);
    double macdHigh1 = ExtMacdBuffer[2];
    double macdHigh2 = ExtMacdBuffer[DivergenceLookBack - 1];

    return (priceHigh1 > priceHigh2 && macdHigh1 < macdHigh2);
}

bool CheckBearishHiddenDivergence()
{
    double priceHigh1 = iHigh(_Symbol, PERIOD_CURRENT, 2);
    double priceHigh2 = iHigh(_Symbol, PERIOD_CURRENT, DivergenceLookBack);
    double macdHigh1 = ExtMacdBuffer[2]; 
    double macdHigh2 = ExtMacdBuffer[DivergenceLookBack - 1];

    return (priceHigh1 < priceHigh2 && macdHigh1 > macdHigh2);
}

void CheckDivergenceTrading()
{
    if (!UseDivergenceStrategy) return;

    // Check if no position is open or if less than 3 positions are open
    int openDivergencePositions = CountOrdersByMagic(DivergenceMagicNumber);
    if (openDivergencePositions == 0 || openDivergencePositions < 3)
    {
        int barsAvailable = Bars(_Symbol, PERIOD_CURRENT);
        if (barsAvailable < DivergenceLookBack * 2)
        {
            Print("Not enough data bars for MACD calculation.");
            return;
        }

        int attempt = 0;
        while(attempt < 6)
        {
            if (CopyBuffer(macd_handle, 0, 0, DivergenceLookBack, ExtMacdBuffer) > 0 &&
                CopyBuffer(macd_handle, 1, 0, DivergenceLookBack, ExtSignalBuffer) > 0)
                break; 
            
            Print("Failed to copy MACD buffer, retrying...");
            Sleep(1000);
            attempt++;
        }
        if(attempt == 6)
        {
            Print("Failed to copy MACD buffers after ", attempt, " attempts.");
            return;
        }

        if(TimeCurrent() == iTime(_Symbol, PERIOD_CURRENT, 0))
        {
            Print("Skipping trade due to incomplete bar data.");
            return;
        }

        double currentClose = iClose(_Symbol, PERIOD_CURRENT, 0);
        double dailyClose = iClose(_Symbol, PERIOD_D1, 0);
        double dailyOpen = iOpen(_Symbol, PERIOD_D1, 0);
        bool isDailyBullish = dailyClose > dailyOpen;
        bool isDailyBearish = dailyClose < dailyOpen;

        // Only proceed with buy orders if D1 is bullish
        if (isDailyBullish)
        {
            if ((CheckBullishRegularDivergence() && ExtMacdBuffer[0] > ExtSignalBuffer[0]) ||
                CheckBullishHiddenDivergence())
            {
                ExecuteDivergenceOrder(true);
            }
        }

        // Only proceed with sell orders if D1 is bearish
        if (isDailyBearish)
        {
            if ((CheckBearishRegularDivergence() && ExtMacdBuffer[0] < ExtSignalBuffer[0]) ||
                CheckBearishHiddenDivergence())
            {
                ExecuteDivergenceOrder(false);
            }
        }
    }
    else
    {
        Print("Divergence strategy: Maximum number of positions reached.");
    }
}

void ExecuteDivergenceOrder(bool isBuy)
{
    // Ensure the magic number is set for the trade
    trade.SetExpertMagicNumber(DivergenceMagicNumber);
    
    double currentPrice = isBuy ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID);
    double stopLossPrice = isBuy ? currentPrice - DivergenceStopLoss * _Point : currentPrice + DivergenceStopLoss * _Point;
    double takeProfitPrice = isBuy ? currentPrice + DivergenceTakeProfit * _Point : currentPrice - DivergenceTakeProfit * _Point;

    if (isBuy)
    {
        if (trade.Buy(DivergenceLots, _Symbol, 0, stopLossPrice, takeProfitPrice, "Divergence Buy"))
        {
            Print("Divergence Buy order placed.");
        }
    }
    else
    {
        if (trade.Sell(DivergenceLots, _Symbol, 0, stopLossPrice, takeProfitPrice, "Divergence Sell"))
        {
            Print("Divergence Sell order placed.");
        }
    }
}

int CountOrdersByMagic(int magic)
{
    int count = 0;
    for (int i = 0; i < PositionsTotal(); i++)
    {
        ulong ticket = PositionGetTicket(i);
        if (PositionSelectByTicket(ticket))
        {
            if (PositionGetInteger(POSITION_MAGIC) == magic)
            {
                count++;
            }
        }
    }
    return count;
}

//+------------------------------------------------------------------+
//| Profit Locking Logic                                             |
//+------------------------------------------------------------------+
void LockProfits()
{
    for (int i = PositionsTotal() - 1; i >= 0; i--)
    {
        ulong ticket = PositionGetTicket(i);
        if (PositionSelectByTicket(ticket))
        {
            double entryPrice = PositionGetDouble(POSITION_PRICE_OPEN);
            double currentProfit = PositionGetDouble(POSITION_PROFIT);
            double currentPrice = PositionGetDouble(POSITION_PRICE_CURRENT);
            
            // Convert profit to points
            double profitPoints = MathAbs(currentProfit / _Point);

            // Check if profit has exceeded 100 points
            if (profitPoints >= 100)
            {
                double newStopLoss;
                
                if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
                {
                    newStopLoss = entryPrice + profitLockerPoints * _Point; // 20 points above entry for buys
                }
                else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
                {
                    newStopLoss = entryPrice - profitLockerPoints * _Point; // 20 points below entry for sells
                }
                else
                {
                    continue; // Skip if not a buy or sell position
                }

                // Modify stop loss only if the new stop loss is more protective
                double currentStopLoss = PositionGetDouble(POSITION_SL);
                if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
                {
                    if (currentStopLoss < newStopLoss || currentStopLoss == 0)
                    {
                        if (trade.PositionModify(ticket, newStopLoss, PositionGetDouble(POSITION_TP)))
                        {
                            Print("Profit locking for buy position: Stop Loss moved to ", newStopLoss);
                        }
                    }
                }
                else // POSITION_TYPE_SELL
                {
                    if (currentStopLoss > newStopLoss || currentStopLoss == 0)
                    {
                        if (trade.PositionModify(ticket, newStopLoss, PositionGetDouble(POSITION_TP)))
                        {
                            Print("Profit locking for sell position: Stop Loss moved to ", newStopLoss);
                        }
                    }
                }
            }
        }
    }
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    if (UseTrendFollowingStrategy)
        CheckTrendFollowing();
    if (UseBreakoutStrategy)
        CheckBreakoutTrading();
    if (UseDivergenceStrategy)
        CheckDivergenceTrading();
    if(UseGoldenDeathCrossStrategy)
        CheckGoldenDeathCross();

}


Test- und Optimierungsergebnisse

Starten des Trend Constraint EA.

Der Trend Constraint Experte: Hinzufügen zum Chart mit Standardeinstellungen

Visualisierung der Strategie

Visualisierung des Goldenen und des Todeskreuzes als Teil anderer Strategien im Strategietester


Schlussfolgerung

Es ist zwar möglich, unseren EA-Code ständig zu erweitern, aber dadurch wird er immer komplexer und ressourcenintensiver in der Verarbeitung. Dies unterstreicht die Notwendigkeit, unsere Techniken der Ressourcenverwaltung zu verbessern. Die Integration von KI-Modellen in diese Konzepte ist besonders vorteilhaft, da sie diese Komplexität effektiv bewältigen können. In diesem Projekt haben wir erfolgreich eine der beliebtesten Strategien für das Management von Umkehrchancen - die neue Strategie des Goldenen und des Todeskreuzes - in den Trend Constraint Expert Advisor integriert.

Das Fundament, das wir von Teil (1) bis jetzt behandelt haben, legten den Grundstein für diesen EA. Um jedoch optimale Ergebnisse zu erzielen, muss der EA durch die Optimierung verschiedener Einstellungen und die Änderung bestimmter struktureller Merkmale verfeinert werden. Dieser Ansatz macht es zu einem wertvollen pädagogischen und experimentellen Instrument. Bitte beachten Sie, dass dieser EA keine Gewinne garantiert; er ist ausschließlich für Bildungs- und Forschungszwecke gedacht.

In den kommenden Teilen plane ich, die bewährten Strategien weiter zu verfeinern und Techniken des maschinellen Lernens einzuführen, um die Fähigkeiten und die Leistung des EA zu verbessern.

Zurück zur Einleitung

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

Beigefügte Dateien |
Die Übertragung der Trading-Signale in einem universalen Expert Advisor. Die Übertragung der Trading-Signale in einem universalen Expert Advisor.
In diesem Artikel wurden die verschiedenen Möglichkeiten beschrieben, um die Trading-Signale von einem Signalmodul des universalen EAs zum Steuermodul der Positionen und Orders zu übertragen. Es wurden die seriellen und parallelen Interfaces betrachtet.
Automatisieren von Handelsstrategien in MQL5 (Teil 3): Das Zone Recovery RSI System für ein dynamisches Handelsmanagement Automatisieren von Handelsstrategien in MQL5 (Teil 3): Das Zone Recovery RSI System für ein dynamisches Handelsmanagement
In diesem Artikel erstellen wir ein Zone Recovery RSI EA System in MQL5, das RSI-Signale verwendet, um Handelsgeschäfte auszulösen und eine Recovery-Strategie, um auf Verluste zu reagieren. Wir implementieren die Klasse „ZoneRecovery“ zur Automatisierung von Handelseinträgen, Erholungslogik und Positionsmanagement. Der Artikel schließt mit Erkenntnissen zu den Backtests, um die Leistung zu optimieren und die Effektivität des EA zu erhöhen.
Eine alternative Log-datei mit der Verwendung der HTML und CSS Eine alternative Log-datei mit der Verwendung der HTML und CSS
In diesem Artikel werden wir eine sehr einfache, aber leistungsfähige Bibliothek zur Erstellung der HTML-Dateien schreiben, dabei lernen wir auch, wie man eine ihre Darstellung einstellen kann (nach seinem Geschmack) und sehen wir, wie man es leicht in seinem Expert Advisor oder Skript hinzufügen oder verwenden kann.
Klassische Strategien neu interpretieren (Teil 13): Minimale Verzögerung des Kreuzens von gleitenden Durchschnitten Klassische Strategien neu interpretieren (Teil 13): Minimale Verzögerung des Kreuzens von gleitenden Durchschnitten
Der gleitende Durchschnitt ist bei den Händlern in unserer Gemeinschaft weithin bekannt, und doch hat sich der Kern der Strategie seit ihrer Einführung nur wenig verändert. In dieser Diskussion werden wir Ihnen eine leichte Anpassung der ursprünglichen Strategie vorstellen, die darauf abzielt, den in der Handelsstrategie vorhandenen Verzögerung zu minimieren. Alle Fans der ursprünglichen Strategie könnten in Erwägung ziehen, die Strategie entsprechend den Erkenntnissen, die wir heute diskutieren werden, zu überarbeiten. Durch die Verwendung von 2 gleitenden Durchschnitten mit der gleichen Periodenlänge wird die Verzögerung in der Handelsstrategie erheblich reduziert, ohne dass die Grundprinzipien der Strategie verletzt werden.