English
preview
Verwendung des MQL5-Wirtschaftskalenders zur Nachrichtenfilterung (Teil 2): Verwaltung von Stopps offener Positionen während Nachrichtenereignissen

Verwendung des MQL5-Wirtschaftskalenders zur Nachrichtenfilterung (Teil 2): Verwaltung von Stopps offener Positionen während Nachrichtenereignissen

MetaTrader 5Handel |
23 2
Solomon Anietie Sunday
Solomon Anietie Sunday

Einführung

In Teil 1 haben wir einen Nachrichtenfilter vorgestellt, der bei Nachrichtenereignissen mit großer Auswirkung neue Handelspositionen blockiert. Diese Ebene verringert die Exponierung neuer Einstiege gegenüber abnormaler Volatilität, löst jedoch das verbleibende Problem nicht: Bei Positionen, die vor dem Nachrichtenfenster eröffnet wurden, kommt es weiterhin zu erweiterten Spreads, vorübergehenden Kurssprüngen und temporären Verzerrungen, die SL-/TP-Werte vorzeitig auslösen können. Es ist oft nicht sinnvoll, vor jedem Nachrichtenereignis alle Positionen zu schließen – dies zerstört die Handelsstruktur, verzerrt die Statistiken und steht im Widerspruch zur längerfristigen Logik.

Dieser Artikel befasst sich mit genau diesem technischen Problem: Wie lässt sich eine kontrollierte, reversible Stop-Management-Ebene einrichten, die Stop-Loss- und Take-Profit-Werte für bereits offene Positionen während des eingeschränkten Nachrichtenfensters vorübergehend aussetzt und sie anschließend deterministisch wiederherstellt? Die Erfolgskriterien sind eindeutig: Aktionen dürfen nur einmal pro Nachrichtenfenster erfolgen (keine wiederholten Änderungen), die ursprünglichen SL-/TP-Werte müssen beibehalten und, sofern technisch möglich, wiederhergestellt werden, die Mindestabstandsregeln des Brokers für Stopps müssen eingehalten werden (keine ungültigen Platzierungen), und der Mechanismus muss sich per MagicNumber auf die Trades dieses EAs eingrenzen lassen (das Verhalten bei Ein-Symbol-EAs ist dokumentiert). Das Ziel ist die Vermeidung vorzeitiger Stop-outs – nicht die Vorhersage der Marktrichtung.


Lösung, Zielsetzung und Grundsätze

Das Ziel von Teil 2 ist klar definiert: Stop-Loss- und Take-Profit-Werte sollen während des Sperrfensters rund um Nachrichten vorübergehend ausgesetzt und nach Ablauf dieses Nachrichtenfensters sicher wiederhergestellt werden.

Dieser Ansatz versucht nicht, die Marktrichtung auf Basis der Nachrichten zu interpretieren. Er verhindert lediglich vorzeitige Stop-outs, die durch außergewöhnliche Marktbedingungen verursacht werden.

Grundsätze der Stop-Wiederherstellung

Die Wiederherstellungslogik ist deterministisch:

  • Wenn der Kurs das ursprünglich gespeicherte Stop-Loss- oder Take-Profit-Niveau nicht überschritten hat, wird der Stop genau auf seinen ursprünglichen Wert wiederhergestellt.
  • Wenn der Kurs das ursprüngliche Stop-Loss-Niveau bereits überschritten hat, wird der Stop auf das nächstgelegene gültige Niveau unmittelbar vor dem aktuellen Kurs wiederhergestellt.
  • Die gleiche Logik gilt auch für Take-Profit-Niveaus.

Dies gewährleistet:

  • keine ungültige Stop-Platzierung,
  • keine Ablehnung durch den Broker aufgrund bereits überschrittener Preisniveaus,
  • keine Wiederherstellung logisch unmöglicher Werte und
  • Beibehaltung der ursprünglichen Handelsstruktur, soweit dies technisch machbar ist.

Der Mechanismus basiert weiterhin auf Regeln.

Technische Anforderungen

Da bei diesem Ansatz aktive Positionen geändert werden, muss die Implementierung direkt oder indirekt mehrere nicht triviale Fälle berücksichtigen:

  • Mehrere offene Positionen über verschiedene Symbole hinweg,
  • Mindestanforderungen der Broker an den Stop-Abstand sowie
  • Der Kurs liegt zum Zeitpunkt der Wiederherstellung bereits jenseits des ursprünglichen Stop-Loss oder Take-Profit.

Um robust zu bleiben, muss das System:

  • die ursprünglichen SL/TP-Werte vor dem Entfernen sicher abspeichern,
  • verfolgen, welche Trades sich derzeit im ausgesetzten Status befinden,
  • wiederholte oder unnötige Änderungsversuche vermeiden und
  • die Wiederherstellung nur einmal pro Ereigniszyklus ausführen.

Die Aufrechterhaltung der Strategie und die Logik der kontrollierten Anpassung sind daher zentrale Bestandteile dieses Teils.

Lösungsübersicht und Gegenstand des Artikels

Die in diesem Artikel vorgestellte Lösung fügt eine Stop-Management-Ebene hinzu, die nur dann aktiviert wird, wenn das eingeschränkte Nachrichtenfenster aktiv ist.

Der Arbeitsablauf ist wie folgt:

  1. Erkennen des aktiven Nachrichtenfensters [aus Teil 1]
  2. Speichern der Originalwerte für SL/TP
  3. vorübergehendes Entfernen der SL-/TP-Werte
  4. Nachverfolgung des Aussetzungsstatus
  5. Erkennen des Endes des Fensters
  6. deterministisches Wiederherstellen von SL/TP
  7. sicheres Zurücksetzen des Zustands

Diese Struktur ermöglicht es der Handelsstrategie, unmittelbar nach Ablauf des Nachrichtenfensters wieder die volle Kontrolle zu übernehmen, ohne die beabsichtigte Struktur des Handels dauerhaft zu verändern.

Einschränkungen des Ansatzes Stop-Aussetzung

Dieser Ansatz ist zwar wirksam, hat jedoch auch seine Grenzen.

  1. Risiko ohne festen Schutz: Während des eingeschränkten Zeitfensters verfügen die Positionen vorübergehend über keinen Stop-Loss-Schutz. Extreme oder anhaltende Kursbewegungen in eine bestimmte Richtung können den schwebenden Drawdown erhöhen. Es wird empfohlen, die Dauer des Nachrichtenfensters kurz zu halten, z. B. 3–10 Minuten.
  2. Kurslückenrisiko: Sollte es während der Aussetzungsfrist zu einer erheblichen Kurslücke kommen, kann die Wiederherstellung auf einem ungünstigeren Niveau erfolgen.
  3. Kein System zur Vorhersage der Volatilität: Dieser Mechanismus sagt weder die Reaktion des Marktes noch dessen Richtung voraus. Er verhindert lediglich vorzeitige Stop-Outs, die durch ungewöhnliche Spreads oder vorübergehende Kurssprünge verursacht werden.
  4. Einschränkungen bei der Orderausführung durch den Broker: Die Wiederherstellung von Stopps muss den Vorschriften des Brokers zum Mindestabstand sowie den symbolspezifischen Einschränkungen entsprechen.
  5. Strategiekompatibilität: Dieser Ansatz ist möglicherweise nicht für extrem kurzfristige Scalping-Systeme geeignet, bei denen ein sofortiger Stop-Loss zwingend erforderlich ist.

Der Zweck dieser Ebene besteht nicht darin, Risiken auszuschließen, sondern eine bestimmte strukturelle Schwachstelle im automatisierten Handel bei Ereignissen mit erheblichen Auswirkungen zu beheben.


Umsetzung

Bevor wir mit den Implementierungsschritten beginnen, müssen wir zunächst die Struktur des Arbeitsablaufs skizzieren.

Struktur des Prozessablaufs

Erkennungsphase:

  • Anstehende Nachrichtenereignisse identifizieren [dies wird bereits in Teil 1 des Artikels behandelt und in Teil 2 darauf zurückgegriffen] und
  • Prüfen, ob die aktuelle Zeit in das Nachrichtenfenster fällt [mehr zu Nachrichtenfenstern in Teil 1].

Aussetzungsphase:

  • Offene Positionen durchlaufen,
  • Ursprüngliche SL/TP in einem Speicherarray speichern,
  • SL/TP entfernen und
  • Die Position als ausgesetzt markieren.

Überwachungsphase:

  • doppelte Änderungen vermeiden, und
  • den Aussetzungszustand bis zum Wiederherstellungszeitpunkt beibehalten.

Wiederherstellungsphase:

  • Für jeden ausgesetzten Trade gilt: Wenn der Kurs die ursprünglichen SL/TP-Werte noch nicht überschritten hat, werden die genauen Werte wiederhergestellt; hat der Kurs die ursprünglichen SL/TP-Werte jedoch bereits überschritten, erfolgt die Wiederherstellung auf dem nächstgelegenen gültigen Niveau vor dem aktuellen Kurs, und
  • Den Aussetzungsstatus zurücksetzen

Diagramm zur Prozess-Architektur

Grafische Darstellung

Schritt 1: Entwurf des Stop-State-Containers

Bevor wir irgendetwas entfernen oder speichern können, muss das System eine einfache Frage beantworten: Wo werden wir die ursprünglichen SL- und TP-Werte speichern, sobald wir sie entfernt haben?

Wenn wir Stopps entfernen, ohne sie sicher zu speichern, ist eine Wiederherstellung unmöglich.

Warum eine Nachverfolgungsstruktur notwendig ist

Zu Beginn des Nachrichtenfensters sind möglicherweise bereits mehrere Trades mit unterschiedlichen Tickets, unterschiedlichen Stop-Loss-Niveaus und unterschiedlichen Take-Profit-Niveaus offen. Jeder Trade muss seine ursprüngliche Konfiguration beibehalten. Wir definieren daher einen Zustandscontainer zur Speicherung

  • der Ticketnummer,
  • des ursprünglichen Stop-Loss und
  • des ursprünglichen Take-Profit.

Dadurch wird sichergestellt, dass die Wiederherstellung für jeden Trade präzise und nicht nur annähernd erfolgt.

Stop-Zustandsstruktur

Wir definieren eine Struktur, die als Container für jeden ausgesetzten Trade dient.

Erforderlicher Code:

//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+

//--- Structure to store removed stop information
struct SavedStops
  {
  ulong             ticket;       // Trade ticket number
  double            sl;           // Original stop loss
  double            tp;           // Original take profit
  };

Das Speicherarray

Da möglicherweise mehrere offene Positionen bestehen, verwenden wir ein Array dieser Struktur:

SavedStops savedStops[];     // Each element of this array represents one suspended trade

Das Aussetzungszustands-Flag

Neben der Speicherung der Stoppwerte müssen wir auch verfolgen, ob sich das System derzeit in einem Aussetzungszyklus befindet. Dadurch wird Folgendes verhindert:

  • wiederholtes Entfernen von Stopps
  • wiederholte Wiederherstellungsversuche und
  • unnötige Positionsänderung.

Wir führen ein boolesches Status-Flag ein:

bool     newsSuspended = false;        // When true stops are currently removed, when false stops are active

Warum dieses Design wichtig ist:

Diese kleine Grundlage gewährleistet eine deterministische Wiederherstellung, eine Nachverfolgung auf Ticket-Ebene, keine Verwechslungen zwischen verschiedenen Trades sowie eine Trennung zwischen Erkennungs- und Änderungslogik.

Zum jetzigen Zeitpunkt wurde noch nichts entfernt. Wir entwickeln lediglich das Speichersystem, auf das sich die EA stützen wird.

Alle globalen Variablen sollten vor der Definition der Funktion OnInit() stehen, etwa wie folgt:

//+------------------------------------------------------------------+
//|                                       News integration part2.mq5 |
//|                                                    soloharbinger |
//|                      https://www.mql5.com/en/users/soloharbinger |
//+------------------------------------------------------------------+
#property copyright "soloharbinger"
#property link      "https://www.mql5.com/en/users/soloharbinger"
#property version   "1.00"

#include <Trade/Trade.mqh>

//+------------------------------------------------------------------+
//| GLOBAL VARIABLES                                                 |
//+------------------------------------------------------------------+
CTrade trade;

//--- Structure to store removed stop information
struct SavedStops
  {
  ulong ticket;        // Trade ticket number
  double sl;           // Original stop loss
  double tp;           // Original take profit
  };

SavedStops savedStops[];

bool newsSuspended = false;         // when true stops are currently removed, and when false stops are active


//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
  return(INIT_SUCCEEDED);
  }

Schritt 2: Aussetzungsphase – Entfernen der Stops während des Nachrichtenfensters

Da wir nun über eine Struktur zum Speichern der Stoppdaten verfügen, können wir die eigentliche Entfernungsphase umsetzen.

Wenn das Nachrichtenfenster aktiv wird,

  • Offene Positionen durchlaufen,
  • Ursprünglichen SL-/TP-Werte speichern,
  • SL/TP beim Broker entfernen und
  • Das System als ausgesetzt markieren

Vermeidung einer doppelten Aussetzung

Wenn wir während das Nachrichtenfenster aktiv ist, bei jedem Tick Stop-Orders entfernen würden, würden wir die gespeicherten Werte wiederholt überschreiben, wiederholte Änderungen vornehmen, eine Ablehnung durch den Broker riskieren und die gespeicherten ursprünglichen Kursstände beschädigen. Daher darf die Aussetzungslogik nur einmal pro Nachrichtenzyklus ausgeführt werden.

Wir verwenden:

//--- Already in the desired state, prevent duplicate execution
if (newsSuspended)
  {
  return;
  }

Die Funktion SuspendStops():

//+------------------------------------------------------------------+
//| Suspend Stops During News                                        |
//+------------------------------------------------------------------+
void SuspendStops(bool suspend)
{
    if (suspend == newsSuspended)
      return;
    newsSuspended = suspend;

    if(suspend)
    {
        ArrayResize(savedStops, 0); // Clear previous list
        for(int i = PositionsTotal() - 1; i >= 0; i--)
        {
            ulong ticket = PositionGetTicket(i);
            
            //--- If needed, filter by magic number here
            if(PositionSelectByTicket(ticket)) 
            {
                // Save current SL/TP
                int idx = ArraySize(savedStops);
                ArrayResize(savedStops, idx + 1);
                savedStops[idx].ticket = ticket;
                savedStops[idx].sl = PositionGetDouble(POSITION_SL);
                savedStops[idx].tp = PositionGetDouble(POSITION_TP);


                // Remove stops from broker side
                if(trade.PositionModify(ticket, 0.0, 0.0))
                {
                    PrintFormat("Frozen trade #%I64u: SL/TP removed for news.", ticket);
                }
            }
        }
    }
    else // Unsuspended using the RestoreStops() function then reset array
    {
        for(int k = 0; k < ArraySize(savedStops); k++)
        {
            RestoreStops(savedStops[k].ticket,
                         savedStops[k].sl,
                         savedStops[k].tp);
        }
        ArrayResize(savedStops, 0); 
    }
}

In dieser Phase sind die Positionen noch offen, und es sind keine Stopps aktiv. Die ursprünglichen Werte werden im Speicher abgelegt.

Schritt 3: Wiederherstellungsphase – Deterministische Stop-Wiederherstellung

Wenn das Nachrichtenfenster endet, müssen wir die Stopps sicher wiederherstellen. Aber die Wiederherstellung macht nicht einfach nur

trade.PositionModify(ticket, originalSL, originalTP);

da sich der Preis möglicherweise geändert hat.

Wenn der Kurs das ursprüngliche Stop-Niveau überschritten hat, wird der Broker den Auftrag ablehnen – oder schlimmer noch: Wir würden einen ungültigen logischen Zustand wiederherstellen. Die Wiederherstellung muss also kursabhängig und brokerkonform sein.

Grundsätze der Wiederherstellungslogik

Für jeden ausgesetzten Handel:

  1. Wählen Sie die Position anhand des Tickets aus.
  2. Aktuellen Marktpreis abrufen.
  3. Vergleiche den Kurs mit den gespeicherten SL/TP-Werten.
  4. Falls der ursprüngliche Stand noch gültig ist, stellen Sie ihn exakt wieder her.
  5. Wenn der Kurs das ursprüngliche Niveau bereits überschritten hat, erfolgt die Wiederherstellung auf dem nächstgelegenen gültigen Niveau.
  6. Halten Sie die Vorschriften zum Mindestabstand zum Broker ein.

Die Wiederherstellungsfunktion:

//+------------------------------------------------------------------+
//| Restore Stops After News                                         |
//+------------------------------------------------------------------+
bool RestoreStops(ulong ticket, double sl, double tp)
{
    if (!PositionSelectByTicket(ticket))
      return(false);
    
    ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
    double price = (type == POSITION_TYPE_BUY) ?
        SymbolInfoDouble(_Symbol, SYMBOL_BID) :
        SymbolInfoDouble(_Symbol, SYMBOL_ASK);
        
    double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
    
    double minStopDist = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL) * point;

    // Safety check: If price has moved past the saved SL/TP, adjust to a valid level
    if(type == POSITION_TYPE_BUY)
    {
        if(sl != 0 && price <= sl)
            sl = price - minStopDist;
        if(tp != 0 && price >= tp)
            tp = price + minStopDist;
    }
    else // SELL
    {
        if(sl != 0 && price >= sl)
            sl = price + minStopDist;
        if(tp != 0 && price <= tp)
            tp = price - minStopDist;
    }

    // Full restore of stops 
    if(trade.PositionModify(ticket, sl, tp))
    {
        PrintFormat("Restored SL/TP for #%I64u | SL=%.5f, TP=%.5f", ticket, sl, tp);
        return true;
    }
    else
    {
        PrintFormat("Failed to restore SL/TP for #%I64u | Error=%d", ticket, GetLastError());
        return false;
    }
}

Was das bewirkt:

Für jeden ausgesetzten Trade:

  • werden die ursprünglichen SL/TP wieder hergestellt, sofern diese noch gültig sind,
  • erfolgt eine Anpassung an das nächstgelegene Niveau, wenn der Kurs das ursprüngliche Niveau bereits überschritten hat, und
  • beachtet den vom Broker festgelegten Mindestabstands der Stopps.


Abschnitt Integration – Teil 2 als Ergänzung zu Teil 1

Wir werden:

  1. die Eingabeparameter für die Stop-Aussetzung hinzufügen,
  2. die Zustandsvariablen hinzufügen,
  3. die Funktionen SuspendStops() und RestoreStops() ergänzen,
  4. In OnTick() mithilfe der Zustandsübergangslogik integrieren.

Verwendung des Codes aus Teil 1 als Referenz.

Hinzufügen der neuen Eingabe für die Stop-Suspendierung zu den vorhandenen Eingaben:

input bool   SuspendStopsDuringNews = false;         // Temporarily remove and later restore SL/TP during the news window
//EXISTING INPUTS

input bool   EnableNewsFilter = false;                           // Enable Economic News Filter
input int    NewsMinutesBefore = 5;                              // Minutes before news to restrict
input int    NewsMinutesAfter = 5;                               // Minutes after news to restrict 
input bool   RestrictNewTradesDuringNews = true;                 // Block new trades during news window
input bool   CloseOpenTradesBeforeHighImpactNews = false;        // Close all trades before news
input string SymbolCurrencyOverride = "";                        // Manual currency override e.g. "USD,JPY"
enum ENUM_NEWS_IMPORTANCE_MODE
  {
   NEWS_HIGH_ONLY = 0,
   NEWS_MODERATE_ONLY,
   NEWS_HIGH_AND_MODERATE
  };
input ENUM_NEWS_IMPORTANCE_MODE NewsImportanceMode = NEWS_HIGH_ONLY; // Which importance levels to consider
// Cache reload interval
input int CacheReloadHours = 6;                                      // How often to reload calendar cache (hours)

Hinzufügen der zuvor definierten Struktur- und globalen Variablen:

// EXISTING GLOBALS
MqlCalendarValue TodayEvents[];    // Calendar cache
datetime lastCalendarLoad = 0;
CTrade  trade;                     // CTrade instance for order management

// NEWLY ADDED [part 2]
// Structure to store removed stop information
struct SavedStops
{
   ulong ticket;        // Trade ticket number
   double sl;           // Original stop loss
   double tp;           // Original take profit
};
SavedStops savedStops[];

bool     newsSuspended = false;

Einfügen der Funktionen Suspend und Restore aus dem vorherigen Abschnitt

Die Funktionen Suspend und Restore werden unterhalb der Funktionen aus Teil 1 eingefügt

4. In OnTick integrieren

Warum OnTick umstrukturiert werden muss:

Teil 1 verwendet derzeit die Variable bool isNews, eine Sperre für das Schließen von Trades sowie einen Reset, wenn das Nachrichtenfenster endet. Das funktioniert zwar beim Schließen von Trades, aber in Teil 2 wird etwas Fortgeschritteneres vorgestellt: Wir müssen nun genau erkennen, wann das Nachrichtenfenster beginnt und wann es endet. Das liegt daran, dass die Stop-Order-Entfernung einmal zu Beginn des Nachrichtenfensters und einmal am Ende des Nachrichtenfensters erfolgen muss.

Wir führen zwei Variablen ein:

currentNewsState // Was das System gerade sieht

lastNewsState // Was das System beim vorherigen Tick erfasst hat

Wenn diese beiden Werte voneinander abweichen, hat ein Übergang stattgefunden. Bei diesem Übergang handelt es sich entweder um ein Nachrichtenfenster, das gerade begonnen hat oder gerade zu Ende gegangen ist.

Endgültige OnTick-Funktion

Im Folgenden finden Sie eine Integration, die Teil 1 des Nachrichtenblockbereichs ersetzt. Dadurch bleiben Teil 1 und Teil 2 einheitlich.

//+------------------------------------------------------------------+
//| OnTick                                                           |
//+------------------------------------------------------------------+
void OnTick()
  {
// Main News Logic
   if(EnableNewsFilter)
     {
      // Track previous state of the news window
      static bool lastNewsState = false;

      bool currentNewsState = (EnableNewsFilter && IsNewsTime(_Symbol));

      // Detect state transition
      if(currentNewsState != lastNewsState)
        {
         if(currentNewsState) // News window has just started
           {
            Print("--- NEWS WINDOW STARTED ---");

            // Part 1 Feature: Close trades if enabled
            if(CloseOpenTradesBeforeHighImpactNews)
              {
               Print("Closing all trades due to high impact news setting.");
               CloseAllTradesForSymbol(_Symbol);
              }

            // Part 2 Feature: Suspend SL/TP if enabled
            if(SuspendStopsDuringNews)
              {
               Print("Freezing trade management (SL/TP).");
               SuspendStops(true);
              }
           }
         else // News window has just ended
           {
            Print("--- NEWS WINDOW ENDED ---");

            // Part 2 Feature: Restore SL/TP
            if(SuspendStopsDuringNews)
              {
               Print("Restoring normal trade management.");
               SuspendStops(false);
              }
           }

         // Update last state after handling transition
         lastNewsState = currentNewsState;
        }
     }
  }

Wir haben die Sperrvariable tradesClosedForThisNewsWindow entfernt, die Überprüfung des Schlusskurses pro Tick abgeschafft und durch ein Zustandsübergangsmodell ersetzt, bei dem pro Fensterbeginn oder -ende jeweils eine Ausführung erfolgt.

Neues Systemverhalten

Wenn das Nachrichtenfenster beginnt, werden optional Positionen geschlossen und optional SL/TP entfernt. Wenn das Nachrichtenfenster endet, werden einfach SL/TP wiederhergestellt.

Unten sehen Sie eine Abbildung, die die Konfiguration des Nachrichtenfilters zeigt.

Konfiguration zur Änderung von Stopps

Einstellungen für den Nachrichtenfilter

Print-Ausgaben während eines Nachrichtenfensters

Beispiel für die Ausgabe einer Print-Anweisung während des Betriebs des Nachrichtenfensters

Wichtiger Hinweis

  • Rufen Sie zu Beginn Ihrer Einstiegslogik oder Ihrer Handelsabwicklungslogik Folgendes auf:

if(!CanOpenNewTrade(_Symbol))
    return;

  • Legen Sie eine MagicNumber fest, damit alle Implementierungen nur die von diesem EA ausgeführten Trades betreffen.

input int magicNumber = 12345;

//--- in SuspendStops and CloseAllTradesForSymbol, filter by magic:

if (PositionSelectByTicket(ticket) &&
   PositionGetInteger(POSITION_MAGIC) == magicNumber)
  • Diese Implementierung ist für EAs mit einem einzigen Symbol ausgelegt. Bei EAs mit mehreren Symbolen [die mehrere Symbole gleichzeitig handeln] funktioniert dies nicht ordnungsgemäß, da die Wiederherstellung der Stopps vom aktuellen Symbol des Charts abhängt.


Schlussfolgerung

Wir haben die technische Lücke zwischen dem Blockieren neuer Einstiege und der sicheren Verwaltung bestehender Positionen im Zusammenhang mit Nachrichten geschlossen. Das vorgestellte Design ist deterministisch und integrationsbereit: ein SavedStops-Container pro Ticket zur Speicherung der ursprünglichen SL/TP-Werte im Speicher, ein Aussetzungs-Flag und ein Zustandsübergangsmodell, das eine einmalige Ausführung zu Beginn bzw. am Ende des Nachrichtenfensters gewährleistet, SuspendStops() zum einmaligen Entfernen von SL/TP sowie RestoreStops() zum kurssensitiven Wiederherstellen der Stopps unter Einhaltung der Mindestabstände des Brokers. Der Mechanismus behält die ursprüngliche Handelsstruktur bei, wann immer dies möglich ist, und weicht vorhersehbar auf das nächstgelegene gültige Niveau aus, sobald der Kurs die gespeicherte Stufe überschreitet.

Die praktischen Einschränkungen sind klar definiert: Verwenden Sie eine MagicNumber, um den Geltungsbereich einzuschränken, gehen Sie davon aus, dass die Operation wie implementiert mit einem einzigen Symbol erfolgt, und akzeptieren Sie eine vorübergehende ungeschützte Marktexponierung während des Aussetzungszeitraums. Diese Ebene dient nicht zur Vorhersage der Volatilität – es handelt sich vielmehr um eine eng gefasste, regelbasierte Schutzmaßnahme, die durch Spreads und Kurssprünge verursachte falsche Stop-outs verhindert und gleichzeitig die statistische Integrität des EAs gewährleistet. Im nächsten Teil werden wir einen persistenten Speicher hinzufügen, damit ausgesetzte Stopps auch nach einem Neustart des Terminals oder des EAs erhalten bleiben.

Nachfolgend finden Sie eine Abbildung, die die print-Anweisungen während eines aktiven Nachrichtenfensters zeigt

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

Letzte Kommentare | Zur Diskussion im Händlerforum (2)
Retail Trading Realities LTD
Philip Kym Sang Nelson | 7 Apr. 2026 in 15:16

So möchte ich diese Funktionen nutzen:

Ich beabsichtige, den Artikel „Teil 1 – Verhindern der Eröffnung neuer Trades oder des Schließens bestehender Trades während des eingeschränkten Nachrichtenfensters“ auf alle meine EAs anzuwenden, die ich bei Prop-Firmen laufen habe.

Teil 2 und Teil 3 – das Entfernen von SL/TP und das anschließende Ersetzen von SL/TP vor bzw. nach dem eingeschränkten Nachrichtenfenster – möchte ich jedoch in einem separaten EA verwenden. Da dieser Code alle offenen Positionen des Kontos durchläuft, habe ich möglicherweise mehr als ein Chart geöffnet und möchte diesen Vorgang nicht öfter als nötig ausführen. Ich werde die Symbolauswahl manuell auf „USD, GBP, EUR“ festlegen, da dies die einzigen Nachrichten im roten Ordner sind, von denen ich aus Erfahrung weiß, dass ich sie bereits herausfiltern muss (bei dir wird das anders sein).

Daher habe ich eine einzeilige Änderung an der Funktion „RestoreStops()“ vorgenommen.

Die Funktion „SuspendStops()“ musste nicht geändert werden.

So wie es aussieht, muss ich an Teil 3 nichts ändern, da ich lediglich die Ticketnummer, SL und TP benötige.

Vielen Dank, @Solomon Anietie Sunday

Ich werde es live auf dem Demokonto testen!

// I won't need this if statement, in the 2nd EA, as the 2nd EA only modifies trades, 
// only need this is statement in the first EA (that opens trades)

if(!CanOpenNewTrade(_Symbol))
    return;
 
//+------------------------------------------------------------------+
//| Wiederaufnahme der Sendepausen nach den Nachrichten (bearbeiteter Artikel – siehe Original)      |
//+------------------------------------------------------------------+
bool RestoreStops(ulong ticket, double sl, double tp)
{
    if (!PositionSelectByTicket(ticket))
      return(false);
    string   symbol= PositionGetString(POSITION_SYMBOL);  // Die ursprüngliche Variable „_Symbol“ wurde durch „symbol“ ersetzt
    ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
    double price = (type == POSITION_TYPE_BUY) ?
        SymbolInfoDouble(symbol, SYMBOL_BID) :  //z. B. „_Symbol“ heißt nun „symbol“
        SymbolInfoDouble(symbol, SYMBOL_ASK);
        
    double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
    
    double minStopDist = SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL) * point;

    // Sicherheitsprüfung: Wenn der Kurs die gespeicherten SL/TP-Werte überschritten hat, passe sie auf ein gültiges Niveau an
    if(type == POSITION_TYPE_BUY)
    {
        if(sl != 0 && price <= sl)
            sl = price - minStopDist;
        if(tp != 0 && price >= tp)
            tp = price + minStopDist;
    }
    else // VERKAUFEN
    {
        if(sl != 0 && price >= sl)
            sl = price + minStopDist;
        if(tp != 0 && price <= tp)
            tp = price - minStopDist;
    }

    // Vollständige Wiederherstellung der Register 
    if(trade.PositionModify(ticket, sl, tp))
    {
        PrintFormat("Restored SL/TP for #%I64u | SL=%.5f, TP=%.5f", ticket, sl, tp);
        return true;
    }
    else
    {
        PrintFormat("Failed to restore SL/TP for #%I64u | Error=%d", ticket, GetLastError());
        return false;
    }
}
Solomon Anietie Sunday
Solomon Anietie Sunday | 19 Apr. 2026 in 21:27
Ja!, das ist ein sehr effektiver Ansatz. Sie können auch eine „magische Zahl“ verwenden, um bestimmte EAs zu blockieren. Sich jedoch auf die drei wichtigsten Instrumente zu konzentrieren, mit denen Sie handeln – insbesondere auf diejenigen mit der höchsten Volatilität –, kann eine wirksame Methode sein, um Ihr gesamtes Portfolio zu schützen.
Die Umsetzung in dieser Artikelserie kann bei korrekter Durchführung sehr flexibel und individuell anpassbar sein.
Das Testen kann anhand historischer Daten (Backtest) erfolgen, ist jedoch knifflig und erfordert einigen Aufwand. Ich werde versuchen, dies in einem kommenden Artikel für diejenigen bereitzustellen, die Backtests mit Nachrichtenereignissen durchführen möchten.

Gern geschehen, Philip. Ich stehe dir jederzeit zur Verfügung, wenn du etwas zum Thema algorithmischer Handel besprechen möchtest.

Meine Antwort kommt etwas verspätet, ich bin manchmal sehr beschäftigt … entschuldige bitte.
MQL5-Handelswerkzeuge (Teil 22): Grafische Darstellung des Histogramms und der Wahrscheinlichkeitsfunktion (PMF) von der Binomialverteilung MQL5-Handelswerkzeuge (Teil 22): Grafische Darstellung des Histogramms und der Wahrscheinlichkeitsfunktion (PMF) von der Binomialverteilung
In diesem Artikel wird ein interaktives MQL5-Diagramm zur Binomialverteilung erstellt, das ein Histogramm der simulierten Ergebnisse mit der theoretischen Wahrscheinlichkeitsfunktion (PMF) kombiniert. Es bietet Funktionen für Mittelwert, Standardabweichung, Schiefe, Kurtosis, Perzentile und Konfidenzintervalle, sowie konfigurierbare Farbschemata und Beschriftungen und unterstützt das Ziehen, die Größenänderung und Live-Parameteränderungen. Nutzen Sie es, um bei der Validierung von Handelsstrategien erwartete Gewinn-Trades, wahrscheinliche Drawdown-Phasen und Konfidenzbereiche zu bewerten.
Larry Williams’ Marktgeheimnisse (Teil 13): Automatisierung von Hidden-Smash-Day-Umkehrmustern Larry Williams’ Marktgeheimnisse (Teil 13): Automatisierung von Hidden-Smash-Day-Umkehrmustern
Der Artikel beschreibt die Erstellung eines transparenten MQL5-Expert-Advisors für die Hidden-Smash-Day-Reversals von Larry Williams. Signale werden nur bei neuen Bars generiert: Eine Setup-Bar wird validiert und anschließend bestätigt, wenn die nächste Sitzung jenseits des Extremums schließt. Das Risiko wird über ATR oder strukturelle Stopps mit einem festgelegten Risiko-Ertrags-Verhältnis gesteuert; die Positionsgröße kann fest oder vom Kontostand abhängig sein, und Richtungsfilter sowie eine Ein-Positions-Regel gewährleisten reproduzierbare Tests.
Trading-Disziplin im Code verankern (Teil 3): Durchsetzung symbolbezogener Handelsgrenzen mit einer Whitelist in MQL5 Trading-Disziplin im Code verankern (Teil 3): Durchsetzung symbolbezogener Handelsgrenzen mit einer Whitelist in MQL5
In diesem Artikel wird ein MQL5-Framework beschrieben, das den Handel auf eine genehmigte Auswahl von Symbolen beschränkt. Die Lösung kombiniert eine gemeinsam genutzte Bibliothek, ein Konfigurations-Dashboard und einen Expert Advisor zur Durchsetzung, der jeden Handel anhand einer Whitelist überprüft und blockierte Versuche protokolliert. Sie enthält voll funktionsfähige Code-Beispiele, eine klare Erläuterung der strukturellen Entwurfsentscheidungen sowie Validierungstests, die eine zuverlässige Symbolfilterung, eine kontrollierte Marktpräsenz und eine transparente Überwachung der Regelumsetzung bestätigen.
Entwicklung eines Toolkits zur Price-Action-Analyse (Teil 62): Entwicklung eines adaptiven Systems in MQL5 zur Erkennung paralleler Kanäle und den Ausbrüchen. Entwicklung eines Toolkits zur Price-Action-Analyse (Teil 62): Entwicklung eines adaptiven Systems in MQL5 zur Erkennung paralleler Kanäle und den Ausbrüchen.
Dieser Artikel stellt ein adaptives System zur Erkennung paralleler Kanäle und den Ausbrüchen daraus in MQL5 vor. Darin wird erläutert, wie Swing-Punkte ermittelt, Kanäle konstruiert und dynamisch neu berechnet werden und wie Ausbrüche durch persistente Signale bestätigt und visualisiert werden. Das Framework vereint Trendliniengeometrie, ATR-basierte Filterung und Retest-Validierung, um eine zuverlässige Kursanalyse in Echtzeit für professionelle Chartanalysen und Handelsentscheidungen zu ermöglichen.