English Русский
preview
Larry Williams’ Marktgeheimnisse (Teil 15): Handel mit Hidden-Smash Day-Umkehrungen unter Berücksichtigung des Marktkontexts

Larry Williams’ Marktgeheimnisse (Teil 15): Handel mit Hidden-Smash Day-Umkehrungen unter Berücksichtigung des Marktkontexts

MetaTrader 5Handelssysteme |
23 0
Chacha Ian Maroa
Chacha Ian Maroa

Einführung

Im vorherigen Artikel dieser Reihe wurde ein benutzerdefinierter Indikator entwickelt, um die von Larry Williams beschriebenen Hidden-Smash-Day-Umkehrmuster zu erkennen. Der Indikator identifiziert Hidden-Smash-Bars im Chart und markiert sie visuell, sodass das Muster objektiv und ohne manuelle Interpretation erkannt werden kann.

Das Erkennen des Musters ist jedoch nur der erste Schritt. Ein umfassender Handelsansatz erfordert zusätzliche Regeln, die festlegen, wann ein erkanntes Setup gehandelt und wann es ignoriert werden sollte. Diese Regeln können Faktoren wie die Handelsrichtung, den vorherrschenden Trend oder wochentagsabhängige Einschränkungen berücksichtigen. Ohne klar definierte Bedingungen wird es schwierig, das Muster systematisch zu bewerten.

In diesem Artikel geht es darum, diese zusätzlichen Bedingungen in ein strukturiertes Handelssystem umzusetzen. Es richtet sich an algorithmische Trader, die Hidden-Smash-Day-Setups mit eindeutigen, überprüfbaren Regeln automatisieren möchten.

Aufbauend auf dem zuvor vorgestellten Indikator implementieren wir einen Expert Advisor, der Hidden-Smash-Signale auswertet und vor der Ausführung von Trades konfigurierbare Kontextfilter anwendet. Zu diesen Filtern gehören die Trendausrichtung mithilfe eines Supertrend-Indikators, optionale Einschränkungen hinsichtlich der Handelstage sowie ein diszipliniertes Risikomanagement durch Stop-Loss- und Positionsgrößenregeln.

Das Ergebnis ist ein objektives Framework für die Analyse und den Handel mit Hidden-Smash-Day-Setups, das sich am Kontext orientiert und nicht ausschließlich auf die Erkennung von Mustern setzt.


Das Hidden-Smash-Day-Muster und die Signalbestätigung

Vor der Implementierung des Handelssystems ist es sinnvoll, noch einmal kurz auf die Struktur des von Larry Williams beschriebenen Hidden-Smash-Day-Musters einzugehen und zu erläutern, wie ein gültiges Handelssignal entsteht.

Eine Hidden-Smash-Day-Bar lässt sich anhand der Position ihres Schlusskurses innerhalb ihrer eigenen Spanne erkennen. Bei einem bullischen Hidden-Smash-Setup schließt die Bar im unteren Bereich ihrer Spanne, liegt aber dennoch über dem Schlusskurs der vorherigen Bar. Diese Konstellation deutet darauf hin, dass die Sitzung zwar höher als die vorherige schloss, der Schlusskurs jedoch nahe dem unteren Ende der Tagesbandbreite lag, was auf eine mögliche Schwäche hindeutet.

Bei einem bärischen Hidden-Smash-Setup ist die Logik umgekehrt. Der Kurs schließt im oberen Bereich seiner Spanne, liegt jedoch weiterhin unter dem Schlusskurs der vorherigen Bar. In diesem Fall wirkt der Markt im Vergleich zur vorangegangenen Sitzung schwach, doch der Schlusskurs liegt nahe dem oberen Ende der Spanne der Bar, was auf eine mögliche latente Stärke hindeutet.

Die Hidden-Smash-Bar selbst ist jedoch kein Handelssignal. Das Setup wird erst dann handelbar, wenn die Bestätigung auf der folgenden Bar erfolgt. In dieser Implementierung wird die Bestätigung ausschließlich anhand abgeschlossener Bars ausgewertet, um Störungen innerhalb einer Bar zu vermeiden und ein reproduzierbares Verhalten während der Tests zu gewährleisten.

Ein gültiges Kaufsignal verläuft nach folgendem Ablauf:

  1. Bei Bar-Index 2 wird eine bullische Hidden-Smash-Bar erkannt.
  2. Die nächste Bar schließt über dem Hoch dieser Hidden-Smash-Bar.
  3. Bei Eröffnung der neuen Bar darf das System eine Long-Position eröffnen.

Buy-Setup

Ein gültiges Verkaufssignal spiegelt diese Struktur wider:

  1. Bei Bar-Index 2 wird eine bärische Hidden-Smash-Bar erkannt.
  2. Die nächste Bar schließt unterhalb des Tiefststands dieser Hidden-Smash-Bar.
  3. Bei Eröffnung der neuen Bar darf das System eine Short-Position eröffnen.

Sell-Setup

Um die Implementierung zu vereinfachen, erkennt der Expert Advisor das Muster nicht direkt. Stattdessen liest er bestätigte Hidden-Smash-Signale aus dem benutzerdefinierten Indikator aus, der im vorherigen Artikel dieser Reihe entwickelt wurde. Dieser Indikator markiert erkannte Muster in speziellen Puffern. Wenn am Index 2 eine Hidden-Smash-Bar vorhanden ist, enthält der Indikatorpuffer einen Wert ungleich EMPTY_VALUE. Dieser Wert dient dem Expert Advisor als zuverlässiger Bezugspunkt für die Bewertung der Bestätigung und die Generierung von Handelssignalen.


Entwurf des Expert Advisors und der Regeln für die Handelsausführung

Der in diesem Artikel entwickelte Expert Advisor baut direkt auf dem Hidden-Smash-Day-Indikator auf, der bereits dieser Reihe vorgestellt wurde. Anstatt das Muster intern zu erkennen, liest das System die Signale dieses Indikators aus und wertet anschließend zusätzliche Regeln aus, bevor es einen Trade ausführt. Dieses Design trennt die Zuständigkeiten für die Mustererkennung und das Handelsmanagement klar voneinander. Der Indikator erkennt Hidden-Smash-Setups, während sich der Expert Advisor auf die Filterung, die Risikokontrolle und die Orderausführung konzentriert.

Alle Handelsentscheidungen werden ausschließlich zu Beginn jeder neuen Bar ausgewertet. Dadurch wird sichergestellt, dass sowohl die Hidden-Smash-Bar als auch die Bestätigungsbar vollständig abgeschlossen sind, bevor ein Signal verarbeitet wird. Indem das System auf abgeschlossene Bars wartet, vermeidet es Schwankungen innerhalb der Bars und sorgt so für ein konsistentes Verhalten im Backtest.

Signalverarbeitung

Der Expert Advisor liest die Werte aus dem Indikatorpuffer aus, um festzustellen, ob ein Hidden-Smash-Muster erkannt wurde. Der Indikator markiert erkannte Muster mithilfe von Pfeilpuffern. Wenn der Indikatorpuffer am Bar-Index 2 einen Wert ungleich EMPTY_VALUE enthält, interpretiert das System dies als erkannte Hidden-Smash-Konstellation.

Sobald bei Index 2 ein Setup vorliegt, prüft der Expert Advisor, ob ein gültiges Signal bestätigt wurde. Ein bullisches Signal kann ausgeführt werden, wenn die Bestätigungsbar über dem Höchststand der Hidden-Smash-Bar geschlossen hat. Ein bärisches Signal folgt der umgekehrten Logik und gilt als bestätigt, wenn die Bestätigungsbar unterhalb des Tiefststands der Hidden-Smash-Bar schließt. Erst nach diesem Bestätigungsschritt erlaubt das System die Eröffnung einer Position.

Handelsrichtungskontrolle

Der Expert Advisor ermöglicht eine flexible Steuerung darüber, welche Handelsrichtungen zulässig sind. Über den Parameter für den Handelsmodus kann das System so konfiguriert werden, dass es ausschließlich Kaufgeschäfte, ausschließlich Verkaufsgeschäfte oder Geschäfte in beide Richtungen ausführt. Diese Option ermöglicht es, das Verhalten von Hidden-Smash-Setups unter verschiedenen Annahmen hinsichtlich der Richtung zu untersuchen.

Trendkontextfilter

Über den Supertrend-Indikator steht ein optionaler Trendfilter zur Verfügung. Wenn dieser Filter aktiviert ist, sind Long-Positionen nur dann zulässig, wenn sich der Markt derzeit in einem bullischen Supertrend-Zustand befindet. Ebenso sind Short-Positionen nur dann zulässig, wenn der Supertrend-Indikator einen bärischen Trend signalisiert. Wenn der Filter deaktiviert ist, werden die Trades ohne jegliche Trendbeschränkung ausgewertet.

Handelstag-Filter

Der Expert Advisor verfügt außerdem über einen Handelstag-Filter, der den Handel auf bestimmte Wochentage beschränkt. Es stehen zwei Betriebsmodi zur Verfügung. Im ersten Modus ist der Handel an allen Tagen ohne Einschränkungen erlaubt. Im zweiten Modus kann jeder Wochentag einzeln ein- oder ausgeschaltet werden. Mit dieser Funktion lässt sich das Verhalten der Strategie unter verschiedenen Wochentagsbedingungen untersuchen.

Stop-Loss-Modelle

Es werden zwei Stop-Loss-Modelle implementiert. Das erste Modell basiert auf der Struktur der Hidden-Smash-Bar. In diesem Modus wird der Stop-Loss für eine Long-Position auf das Tief der Hidden-Smash-Bar gesetzt, während der Stop-Loss für eine Short-Position auf das Hoch dieser Bar gesetzt wird.

Das zweite Modell verwendet die Volatilität, gemessen anhand des Average True Range-Indikators. Wenn diese Option ausgewählt ist, wird die Stop-Loss-Distanz berechnet, indem der ATR-Wert mit einem konfigurierbaren Multiplikator multipliziert wird. Dieser Ansatz ermöglicht es, den Schutzstopp an die sich ändernde Marktvolatilität anzupassen.

Berechnung des Take-Profits

Die Take-Profit-Niveaus werden anhand eines konfigurierbaren Risiko-Ertrags-Verhältnisses berechnet. Sobald die Stop-Loss-Distanz festgelegt wurde, wird die Gewinn-Distanz aus dem gewählten Verhältnis abgeleitet und bei Long-Positionen zum Einstiegskurs addiert bzw. bei Short-Positionen vom Einstiegskurs abgezogen. Dadurch wird sichergestellt, dass jede Position einer einheitlichen Risiko-Ertrags-Struktur folgt.

Positionsgröße

Der Expert Advisor unterstützt sowohl die manuelle als auch die automatische Positionsgrößenbestimmung. Im manuellen Modus wird bei jedem Trade eine vom Benutzer festgelegte feste Positionsgröße angewendet. Im Automatikmodus wird die Positionsgröße als Prozentsatz des Kontostands berechnet, den der Trader zu riskieren bereit ist.

Die automatische Methode berechnet den potenziellen Verlust für ein einzelnes Lot mithilfe der Funktion OrderCalcProfit. Die Positionsgröße wird dann so angepasst, dass sie dem konfigurierten Risikoprozentsatz entspricht. Broker-Beschränkungen wie Mindestvolumen, Höchstvolumen und Volumenschritte werden berücksichtigt, um sicherzustellen, dass die berechnete Positionsgröße gültig bleibt.

Verwaltung von Positionen

Um ein einheitliches Handelsmanagement zu gewährleisten, lässt der Expert Advisor jeweils nur eine aktive Position zu. Bevor ein neuer Trade eröffnet wird, prüft das System, ob bereits eine bestehende Kauf- oder Verkaufsposition mit derselben Magic Number aktiv ist. Ist bereits eine Position vorhanden, wird das neue Signal ignoriert.

Zusammen bilden diese Komponenten einen strukturierten Handelsrahmen, der Mustererkennung, kontextbezogene Filter und ein diszipliniertes Risikomanagement vereint. Der daraus resultierende Expert Advisor bietet eine flexible Umgebung, um zu untersuchen, wie sich Hidden-Smash-Day-Setups verhalten, wenn sie unter verschiedenen kontextbezogenen Bedingungen gehandelt werden.


Ablauf der Strategieumsetzung am Hidden-Smash-Day

Bevor wir uns mit der Implementierung befassen, lässt sich die gesamte Handelslogik des Expert Advisors in einer strukturierten Abfolge zusammenfassen. Diese Übersicht stellt einen Zusammenhang zwischen den zuvor erörterten konzeptionellen Regeln und der Programmlogik her, die im Quellcode zum Ausdruck kommt.

Dieser Ablauf stellt sicher, dass der Handelsprozess einer klaren und disziplinierten Struktur folgt.

wenn ein neuer Balken eröffnet wurde

 aktualisiere die Puffer des „Hidden Smash“-Indikators
 aktualisiere die Werte des „Supertrend“-Indikators
 aktualisiere die ATR-Werte

 wenn keine offene Position besteht

  prüfe, ob ein Hidden Smash-Buy-Setup bei Index zwei vorliegt

  wenn ein Setup vorliegt

   prüfe ob Kaufen gemäß der Einstellung zur Handelsrichtung zulässig ist

   wenn der Supertrend-Filter aktiviert iat

    prüfe, ob sich derzeit der Markt in einem bullischen Trend befindet

   wenn Handelstagseinschränkungen aktiv sind

    prüfe, ob am aktuellen Tag der Handel erlaubt ist

   wenn alle Bedingungen erfüllt sind

    berechne das Stop-Loss-Niveau
    berechne das Take-profit-Niveau
    bestimme die Positionsgröße
    eröffne eine Kauforder

  prüfe auf ein Hidden-Smash-Sell-Setup bei Index zwei

  wenn in Setup vorliegt

   prüfe, ob Verkaufstransaktionen gemäß der Einstellung zur Handelsrichtung zulässig sind

   wenn der Supertrend-Filter aktiviert ist

    prüfe, ob sich derzeit der Markt in einem bärischen Trend befindet


   wenn Handelstagseinschränkungen aktiv sind

    prüfe, ob der Handel am aktuellen Tag erlaubt ist

   wenn alle Bedingungen erfüllt sind

    berechne das Stop-Loss-Niveau
    berechne das Take-profit-Niveau
    bestimme die Positionsgröße
    eröffne eine Verkaufsorder

Die Signalerkennung erfolgt getrennt von der Handelsausführung, da das Muster selbst vom Hidden-Smash-Indikator erkannt wird. Alle Auswertungen werden erst nach Beginn einer neuen Bar durchgeführt, wodurch sichergestellt wird, dass die Smash-Bar und die bestätigende Bar vollständig abgeschlossen sind, bevor irgendwelche Maßnahmen ergriffen werden. Die Schutzniveaus und die Positionsgröße werden vor dem Absenden einer Order berechnet, um sicherzustellen, dass jeder Trade mit festgelegten Risikoparametern eröffnet wird. Schließlich wendet das System die Eine-Position-Regel an, sodass zu jedem Zeitpunkt nur eine Position bestehen kann.


Einrichtung der Entwicklungsumgebung und der Projektgrundlage

Vor der Implementierung des Expert Advisors müssen mehrere Komponenten vorbereitet werden. Das in diesem Artikel beschriebene Handelssystem stützt sich auf zwei benutzerdefinierte Indikatoren, die bereits zu einem früheren Zeitpunkt in dieser Reihe vorgestellt wurden. Diese Indikatoren liefern die Signale und den Marktkontext, die für das Funktionieren der Strategie erforderlich sind.

Die erste Komponente ist der Supertrend-Indikator. Dieser Indikator ist ein optionaler Trendfilter, der es dem Expert Advisor ermöglicht, Trades nur dann zu eröffnen, wenn die Marktrichtung mit der gewählten Trendrichtung übereinstimmt. Die Entwicklung dieses Indikators wurde in einem früheren Artikel derselben Reihe erläutert. Leser, die verstehen möchten, wie der Indikator selbst entwickelt wurde, finden in diesem Artikel eine ausführliche Erläuterung seiner internen Logik.

Die Quelldatei für den in diesem Projekt verwendeten Indikator ist dem Artikel als supertrend.mq5 beigefügt. Der Indikator kann auf zwei verschiedene Arten für den Einsatz vorbereitet werden.

Die erste Methode besteht darin, die bereitgestellte Quelldatei herunterzuladen und sie im Verzeichnis Indicators des MQL5-Hauptordners abzulegen. Dies lässt sich anhand der folgenden Schritte bewerkstelligen.

  1. Öffnen Sie die MetaTrader 5-Plattform.
  2. Wählen Sie im Hauptmenü die Option aus, mit der sich der Datenordner öffnet.
  3. Wechseln Sie in das Verzeichnis MQL5.
  4. Öffnen Sie den Ordner Indicators.
  5. Kopieren Sie die Datei supertrend.mq5 in dieses Verzeichnis.
  6. Kehren Sie zur MetaEditor-Entwicklungsumgebung zurück und kompilieren Sie den Indikator.

Nach der Kompilierung steht der Indikator anderen Programmen, einschließlich Expert Advisors, zur Verfügung.

Die zweite Methode besteht darin, die Indikator-Quelldatei manuell zu erstellen. Bei diesem Ansatz wird im Verzeichnis Indicators eine neue Indikator-Datei mit dem Namen supertrend.mq5 erstellt. Der Quellcode aus der angehängten Datei kann dann kopiert und in die neue Datei eingefügt werden, bevor diese im MetaEditor kompiliert wird.

Der gleiche Vorbereitungsprozess gilt auch für den Indikator Hidden-Smash-Day, der im vorherigen Artikel dieser Reihe vorgestellt wurde. Die Quelldatei lwHiddenSmashDayIndicator.mq5 ist diesem Artikel ebenfalls beigefügt. Es sollte im Verzeichnis Indicators abgelegt und auf dieselbe Weise kompiliert werden.

In diesem Artikel wird davon ausgegangen, dass sich beide Indikatoren im Verzeichnis Indicators im Stammordner von MQL5 befinden. Nach der Kompilierung kann der Expert Advisor über Indikator-Handles direkt darauf zugreifen.

Bevor wir fortfahren, müssen einige Voraussetzungen erfüllt sein, um den Implementierungsprozess effektiv durchführen zu können. Zunächst sind Kenntnisse der Syntax und der grundlegenden Konstrukte der Programmiersprache MQL5 erforderlich. Begriffe wie Variablen, Funktionen, bedingte Anweisungen, Schleifen, Enumerationen und Standardbibliotheken sollten bereits verstanden sein. Falls Ihnen diese Themen noch nicht geläufig sind, bietet die offizielle MQL5-Dokumentation einen zuverlässigen Einstieg in das Erlernen der Sprache.

Zweitens sind Vorkenntnisse im Umgang mit der Handelsplattform MetaTrader 5 wichtig. Die Navigation auf der Plattformoberfläche sollte vertraut sein, einschließlich des Öffnens von Charts, des Hinzufügens von Programmen und des Startens des Strategietesters. Diese Vorgänge sind Teil des normalen Arbeitsablaufs bei der Entwicklung algorithmischer Handelssysteme.

Drittens sollte man auch mit der Entwicklungsumgebung MetaEditor vertraut sein. Diese Umgebung dient dazu, Quelldateien zu erstellen, Code zu schreiben, Programme zu kompilieren und mögliche Fehler während der Entwicklung zu überprüfen.

Im Verlauf der Implementierung wird dringend empfohlen, parallel zum Tutorial zu programmieren. Programmierkonzepte werden verständlicher, wenn man sie direkt in der Praxis anwendet, anstatt sie nur passiv zu betrachten. Um diesen Vorgang zu unterstützen, wurde der fertige Quellcode des Expert Advisors diesem Artikel in der Datei lwHiddenSmashDayContextExpert.mq5 beigefügt. Wenn Sie diese Datei in einem separaten Editor-Tab geöffnet lassen, kann sie Ihnen beim schrittweisen Aufbau des Systems als hilfreiche Referenz dienen.

Sobald die Umgebung vorbereitet ist, kann der Entwicklungsprozess beginnen. Öffnen Sie den MetaEditor und erstellen Sie eine neue Quelldatei für einen Expert Advisor. Der Dateiname kann frei gewählt werden, allerdings heißt die in diesem Artikel entwickelte Version lwHiddenSmashDayContextExpert.mq5. Sobald die leere Datei erstellt ist, legt der folgende Code den Grundstein für den Rest des Systems.

//+------------------------------------------------------------------+
//|                                lwHiddenSmashDayContextExpert.mq5 |
//|          Copyright 2026, MetaQuotes Ltd. Developer is Chacha Ian |
//|                          https://www.mql5.com/en/users/chachaian |
//+------------------------------------------------------------------+

#property copyright "Copyright 2026, MetaQuotes Ltd. Developer is Chacha Ian"
#property link      "https://www.mql5.com/en/users/chachaian"
#property version   "1.00"
#resource "\\Indicators\\lwHiddenSmashDayIndicator.ex5"
#resource "\\Indicators\\supertrend.ex5"

//+------------------------------------------------------------------+
//| Custom Enumerations                                              |
//+------------------------------------------------------------------+
enum ENUM_TDW_MODE
{
   TDW_ALL_DAYS,     
   TDW_SELECTED_DAYS
};

enum ENUM_SMASH_TRADE_MODE
{
   SMASH_TRADE_BUY_ONLY,
   SMASH_TRADE_SELL_ONLY,
   SMASH_TRADE_BOTH
};

enum ENUM_STOP_LOSS_MODE
{
   SL_ATR_BASED,            
   SL_SMASH_BAR_STRUCTURE
};

enum ENUM_LOT_SIZE_INPUT_MODE 
{ 
   MODE_MANUAL, 
   MODE_AUTO 
};

//+------------------------------------------------------------------+
//| Standard Libraries                                               |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>

//+------------------------------------------------------------------+
//| User input variables                                             |
//+------------------------------------------------------------------+
input group "Information"
input ulong magicNumber          = 254700680002;                 
input ENUM_TIMEFRAMES timeframe  = PERIOD_CURRENT;

input group "Supertrend configuration parameters"
input bool useSupertrendFilter            = false;
input ENUM_TIMEFRAMES supertrendTimeframe = PERIOD_CURRENT;
input int32_t supertrendAtrPeriod         = 10;
input double  supertrendAtrMultiplier     = 1.5;

input group "TDW filters"
input ENUM_TDW_MODE tradeDayMode = TDW_SELECTED_DAYS;
input bool tradeSunday           = false;
input bool tradeMonday           = true;
input bool tradeTuesday          = false;
input bool tradeWednesday        = false;
input bool tradeThursday         = false;
input bool tradeFriday           = false;
input bool tradeSaturday         = false;

input group "Trade and Risk Management"
input ENUM_STOP_LOSS_MODE smashStopLossMode = SL_SMASH_BAR_STRUCTURE;
input int32_t atrPeriod                     = 14;
input double  atrMultiplier                 = 2.0;
input ENUM_SMASH_TRADE_MODE smashTradeMode  = SMASH_TRADE_BOTH;
input ENUM_LOT_SIZE_INPUT_MODE lotSizeMode  = MODE_AUTO;
input double riskPerTradePercent            = 1.0;
input double positionSize                   = 0.1;
input double riskRewardRatio                = 3.0;

//+------------------------------------------------------------------+
//| Global Variables                                                 |
//+------------------------------------------------------------------+
//--- Create a CTrade object to handle trading operations
CTrade Trade;

//--- To help track current market prices for Buying (Ask) and Selling (Bid)
double askPrice;
double bidPrice;

//--- To store current time
datetime currentTime;

//--- To help track new bar open
datetime lastBarOpenTime;

//--- Hidden Smash bar indicator handle and values
int hiddenSmashDayIndicatorHandle;
double buySmashArrowBuffer[];
double sellSmashArrowBuffer[];

//--- Supertrend indicator handle and values 
int    supertrendIndicatorHandle;
double upperBandValues[];
double lowerBandValues[];

//--- ATR Values
int atrHandle;
double atrValues [];

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(){

   //---  Assign a unique magic number to identify trades opened by this EA
   Trade.SetExpertMagicNumber(magicNumber);
   
   //--- Initialize global variables
   lastBarOpenTime = 0;
   
   //--- Initialize the hidden smash day indicator
   hiddenSmashDayIndicatorHandle    = iCustom(_Symbol, timeframe, "::Indicators\\lwHiddenSmashDayIndicator.ex5");
   if(hiddenSmashDayIndicatorHandle == INVALID_HANDLE){
      Print("Error while initializing The Hidden Smash Day Indicator: ", GetLastError());
      return(INIT_FAILED);
   }
   
   // Initialize the Supertrend Indicator
   supertrendIndicatorHandle = iCustom(_Symbol, supertrendTimeframe, "::Indicators\\supertrend.ex5", supertrendAtrPeriod, supertrendAtrMultiplier);
   if(supertrendIndicatorHandle == INVALID_HANDLE){
      Print("Error while initializing the Supertrend indicator: ", GetLastError());
      return(INIT_FAILED);
   }
   
   //--- Initialize the ATR indicator
   atrHandle = iATR(_Symbol, timeframe, atrPeriod);
   if(atrHandle == INVALID_HANDLE){
      Print("Error while initializing the ATR indicator ", GetLastError());
      return(INIT_FAILED);
   }
   
   //--- Set arrays as series
   ArraySetAsSeries(buySmashArrowBuffer, true);
   ArraySetAsSeries(sellSmashArrowBuffer, true);
   ArraySetAsSeries(upperBandValues, true);
   ArraySetAsSeries(lowerBandValues, true);
   ArraySetAsSeries(atrValues, true);

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){

   //--- Release Supertrend
   if(hiddenSmashDayIndicatorHandle != INVALID_HANDLE){
      IndicatorRelease(hiddenSmashDayIndicatorHandle);
   }

   //--- Release Supertrend
   if(supertrendIndicatorHandle != INVALID_HANDLE){
      IndicatorRelease(supertrendIndicatorHandle);
   }
   
   //--- Release ATR
   if(atrHandle != INVALID_HANDLE){
      if(IndicatorRelease(atrHandle)){
         Print("The computer memory tracking ATR has been freed.");
      }
   }

   //--- Notify why the program stopped running
   Print("Program terminated! Reason code: ", reason);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(){

   //--- Retrieve current market prices for trade execution
   askPrice    = SymbolInfoDouble (_Symbol, SYMBOL_ASK);
   bidPrice    = SymbolInfoDouble (_Symbol, SYMBOL_BID);
   currentTime = TimeCurrent();   
}
 
//+------------------------------------------------------------------+

Dieser erste Code legt das strukturelle Framework des Expert Advisors fest. Es definiert Programmeigenschaften, deklariert Konfigurationsparameter, initialisiert globale Variablen und implementiert grundlegende Programmfunktionen, die die Initialisierung, Ausführung und Beendigung steuern.

Die Eigenschaftsdeklarationen am Anfang der Datei definieren Metadaten für das Programm.

//+------------------------------------------------------------------+
//|                                lwHiddenSmashDayContextExpert.mq5 |
//|          Copyright 2026, MetaQuotes Ltd. Developer is Chacha Ian |
//|                          https://www.mql5.com/en/users/chachaian |
//+------------------------------------------------------------------+

#property copyright "Copyright 2026, MetaQuotes Ltd. Developer is Chacha Ian"
#property link      "https://www.mql5.com/en/users/chachaian"
#property version   "1.00"
#resource "\\Indicators\\lwHiddenSmashDayIndicator.ex5"
#resource "\\Indicators\\supertrend.ex5"

Diese Werte geben den Autor an, enthalten einen Referenzlink und geben die Version des Expert Advisors an. In diesem Abschnitt sind auch die Ressourcendeklarationen aufgeführt. Sie ermöglichen es, die kompilierten Indikator-Dateien zusammen mit dem Expert Advisor zu bündeln, sodass während der Ausführung direkt darauf zugegriffen werden kann.

Im Anschluss an die Eigenschaftsdefinitionen werden mehrere benutzerdefinierte Enumerationen deklariert.

//+------------------------------------------------------------------+
//| Custom Enumerations                                              |
//+------------------------------------------------------------------+
enum ENUM_TDW_MODE
{
   TDW_ALL_DAYS,     
   TDW_SELECTED_DAYS
};

enum ENUM_SMASH_TRADE_MODE
{
   SMASH_TRADE_BUY_ONLY,
   SMASH_TRADE_SELL_ONLY,
   SMASH_TRADE_BOTH
};

enum ENUM_STOP_LOSS_MODE
{
   SL_ATR_BASED,            
   SL_SMASH_BAR_STRUCTURE
};

enum ENUM_LOT_SIZE_INPUT_MODE 
{ 
   MODE_MANUAL, 
   MODE_AUTO 
};

Diese Enumerationen beschreiben die auswählbaren Modi, die die Funktionsweise der Strategie steuern. Die Enumerationen definieren die verfügbaren Handelstagfilter, Einstellungen zur Handelsrichtung, Methoden zur Stop-Loss-Berechnung und Modi zur Positionsgrößenbestimmung. Die Verwendung von Enumerationen verbessert die Lesbarkeit und stellt sicher, dass die Konfigurationsoptionen klar definiert bleiben.

Der nächste Abschnitt enthält die Standard-Handelsbibliothek.

//+------------------------------------------------------------------+
//| Standard Libraries                                               |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>

Diese Bibliothek stellt die Klasse CTrade bereit, die das Senden von Handelsaufträgen an den Handelsserver vereinfacht. Anstatt Order-Strukturen auf niedriger Ebene manuell zu erstellen, ermöglicht das CTrade-Objekt das Eröffnen von Orders durch einfache Methodenaufrufe.

Nach dem Einbinden der Bibliothek werden die vom Benutzer eingegebenen Parameter deklariert.

//+------------------------------------------------------------------+
//| User input variables                                             |
//+------------------------------------------------------------------+
input group "Information"
input ulong magicNumber          = 254700680002;                 
input ENUM_TIMEFRAMES timeframe  = PERIOD_CURRENT;

input group "Supertrend configuration parameters"
input bool useSupertrendFilter            = false;
input ENUM_TIMEFRAMES supertrendTimeframe = PERIOD_CURRENT;
input int32_t supertrendAtrPeriod         = 10;
input double  supertrendAtrMultiplier     = 1.5;

input group "TDW filters"
input ENUM_TDW_MODE tradeDayMode = TDW_SELECTED_DAYS;
input bool tradeSunday           = false;
input bool tradeMonday           = true;
input bool tradeTuesday          = false;
input bool tradeWednesday        = false;
input bool tradeThursday         = false;
input bool tradeFriday           = false;
input bool tradeSaturday         = false;

input group "Trade and Risk Management"
input ENUM_STOP_LOSS_MODE smashStopLossMode = SL_SMASH_BAR_STRUCTURE;
input int32_t atrPeriod                     = 14;
input double  atrMultiplier                 = 2.0;
input ENUM_SMASH_TRADE_MODE smashTradeMode  = SMASH_TRADE_BOTH;
input ENUM_LOT_SIZE_INPUT_MODE lotSizeMode  = MODE_AUTO;
input double riskPerTradePercent            = 1.0;
input double positionSize                   = 0.1;
input double riskRewardRatio                = 3.0;

Mit diesen Parametern lassen sich wichtige Aspekte der Strategie direkt über die Handelsplattform konfigurieren. Die Parameter legen den Zeitrahmen, die Supertrend-Einstellungen, die Beschränkungen für Handelstage und die Konfiguration des Risikomanagements fest.

Globale Variablen werden nach den Eingabeparametern deklariert.

//+------------------------------------------------------------------+
//| Global Variables                                                 |
//+------------------------------------------------------------------+
//--- Create a CTrade object to handle trading operations
CTrade Trade;

//--- To hep track current market prices for Buying (Ask) and Selling (Bid)
double askPrice;
double bidPrice;

//--- To store current time
datetime currentTime;

//--- To help track new bar open
datetime lastBarOpenTime;

//--- Hidden Smash bar indicator handle and values
int hiddenSmashDayIndicatorHandle;
double buySmashArrowBuffer[];
double sellSmashArrowBuffer[];

//--- Supertrend indicator handle and values 
int    supertrendIndicatorHandle;
double upperBandValues[];
double lowerBandValues[];

//--- ATR Values
int atrHandle;
double atrValues [];

Diese Variablen speichern Werte, auf die während des gesamten Programms zugegriffen werden kann. Beispiele hierfür sind die aktuellen Marktpreise, Indikator-Handles und Arrays, in denen später Indikator-Daten gespeichert werden. Diese Variablen stellen den für die Kommunikation zwischen verschiedenen Teilen des Expert Advisors erforderlichen Speicherplatz bereit.

Als Nächstes folgt die Initialisierungsfunktion.

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(){

   //---  Assign a unique magic number to identify trades opened by this EA
   Trade.SetExpertMagicNumber(magicNumber);
   
   //--- Initialize global variables
   lastBarOpenTime = 0;
   
   //--- Initialize the hidden smash day indicator
   hiddenSmashDayIndicatorHandle    = iCustom(_Symbol, timeframe, "::Indicators\\lwHiddenSmashDayIndicator.ex5");
   if(hiddenSmashDayIndicatorHandle == INVALID_HANDLE){
      Print("Error while initializing The Hidden Smash Day Indicator: ", GetLastError());
      return(INIT_FAILED);
   }
   
   // Initialize the Supertrend Indicator
   supertrendIndicatorHandle = iCustom(_Symbol, supertrendTimeframe, "::Indicators\\supertrend.ex5", supertrendAtrPeriod, supertrendAtrMultiplier);
   if(supertrendIndicatorHandle == INVALID_HANDLE){
      Print("Error while initializing the Supertrend indicator", GetLastError());
      return(INIT_FAILED);
   }
   
   //--- Initialize the ATR indicator
   atrHandle = iATR(_Symbol, timeframe, atrPeriod);
   if(atrHandle == INVALID_HANDLE){
      Print("Error while initializing the ATR indicator ", GetLastError());
      return(INIT_FAILED);
   }
   
   //--- Set arrays as series
   ArraySetAsSeries(buySmashArrowBuffer, true);
   ArraySetAsSeries(sellSmashArrowBuffer, true);
   ArraySetAsSeries(upperBandValues, true);
   ArraySetAsSeries(lowerBandValues, true);
   ArraySetAsSeries(atrValues, true);

   return(INIT_SUCCEEDED);
}

Die Funktion bereitet das Programm vor, wenn es zum ersten Mal an ein Chart angehängt wird. Bei der Initialisierung weist der Expert Advisor seine eindeutige MagicNumber zu, erstellt Indikator-Handles und bereitet die Arrays vor, in denen die Indikatorwerte gespeichert werden. Sollte einer dieser Initialisierungsschritte fehlschlagen, wird das Programm vorzeitig beendet, um eine fehlerhafte Ausführung zu verhindern.

Die Deinitialisierungsfunktion ist dafür zuständig, Ressourcen freizugeben, wenn das Programm beendet wird.

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){

   //--- Release Supertrend
   if(hiddenSmashDayIndicatorHandle != INVALID_HANDLE){
      IndicatorRelease(hiddenSmashDayIndicatorHandle);
   }

   //--- Release Supertrend
   if(supertrendIndicatorHandle != INVALID_HANDLE){
      IndicatorRelease(supertrendIndicatorHandle);
   }
   
   //--- Release ATR
   if(atrHandle != INVALID_HANDLE){
      if(IndicatorRelease(atrHandle)){
         Print("The computer memory tracking ATR has been freed.");
      }
   }

   //--- Notify why the program stopped running
   Print("Program terminated! Reason code: ", reason);
}

Bei der Initialisierung erstellte Indikator-Handles werden ordnungsgemäß freigegeben, wodurch Systemspeicher freigegeben wird.

Abschließend wird die Funktion zur Verarbeitung von Ticks vorgestellt.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(){

   //--- Retrieve current market prices for trade execution
   askPrice    = SymbolInfoDouble (_Symbol, SYMBOL_ASK);
   bidPrice    = SymbolInfoDouble (_Symbol, SYMBOL_BID);
   currentTime = TimeCurrent();   
}

Diese Funktion wird immer dann ausgeführt, wenn der Markt eine neue Kursaktualisierung erhält. In dieser frühen Phase ruft die Funktion die aktuellen Ask- und Bid-Kurse ab und speichert den aktuellen Zeitpunkt. Diese Werte werden später bei der Implementierung der Handelslogik verwendet.

Damit ist die strukturelle Grundlage des Expert Advisors fertiggestellt. Das Programm verfügt nun über die notwendigen Grundstrukturen, um die Handelslogik zu unterstützen, die in den folgenden Abschnitten entwickelt wird.


Implementierung von Signalerfassung, Kontextfiltern und Handelsausführung

Nachdem die strukturelle Grundlage des Expert Advisors bereits geschaffen ist, besteht der nächste Schritt darin, die Logik zu implementieren, die das Handelssystem steuert. In dieser Phase werden mehrere kleine Funktionen vorgestellt, die zusammenwirken, um Handelssignale zu erkennen, den Marktkontext zu bewerten, Risikoparameter zu berechnen und Trades auszuführen.

Jede Funktion erfüllt eine klar abgegrenzte Aufgabe. Dieser modulare Ansatz sorgt für mehr Übersichtlichkeit und gewährleistet, dass jede Komponente der Strategie leicht verständlich und wartbar bleibt. Zunächst suchen wir nach neuen Bars.

Erkennen des Öffnens einer neuen Bar

Die Strategie wertet die Handelsbedingungen erst aus, nachdem sich eine Bar vollständig geschlossen hat. Dadurch wird sichergestellt, dass die Signale auf vollständigen Marktdaten basieren und nicht auf noch nicht vollständig ausgebildeten Bars. Um dieses Ereignis zu erkennen, definieren wir die folgende Hilfsfunktion.

//+------------------------------------------------------------------+
//| Function to check if there's a new bar on a given chart timeframe|
//+------------------------------------------------------------------+
bool IsNewBar(string symbol, ENUM_TIMEFRAMES tf, datetime &lastTm){

   datetime currentTm = iTime(symbol, tf, 0);
   if(currentTm != lastTm){
      lastTm       = currentTm;
      return true;
   }  
   return false;   
}

Diese Funktion gibt die Eröffnungszeit der letzten Bar zurück. Wenn dieser Zeitpunkt vom zuvor erfassten Wert abweicht, hat sich eine neue Bar gebildet. Die Funktion aktualisiert daraufhin die gespeicherte Zeit und gibt true zurück. Dieser einfache Mechanismus stellt sicher, dass das Programm das Signal genau einmal pro Bar auswertet.

Aktualisierung der Daten des Hidden-Smash-Indikators

Der Hidden-Smash-Indikator, der bereits zu Beginn dieser Serie vorgestellt wurde, identifiziert das zugrunde liegende Kursmuster. Der Expert Advisor liest die Indikatorpuffer aus, um festzustellen, ob ein Muster vorliegt. Zur Speicherung dieser Werte werden zwei Arrays verwendet. Das eine speichert bullische Signale, das andere bärische Signale. Die folgenden Funktionen aktualisieren diese Arrays mit den aktuellsten Indikatorwerten.

//+------------------------------------------------------------------+
//| Updates the buySmashArrowBuffer with latest buy arrow values     |
//+------------------------------------------------------------------+
void UpdateBuySmashArrowBuffer()
{
   int copied = CopyBuffer(hiddenSmashDayIndicatorHandle,
                           0,          // Buy buffer index
                           0,          // Start from most recent bar
                           5,          // Number of values to copy
                           buySmashArrowBuffer);

   if(copied <= 0)
   {
      Print("Failed to copy buy smash arrow buffer. Error: ", GetLastError());
   }
}

Diese Funktion kopiert die letzten Werte aus dem Indikatorpuffer, der bullische Smash-Muster markiert.

//+------------------------------------------------------------------+
//| Updates the sellSmashArrowBuffer with latest sell arrow values   |
//+------------------------------------------------------------------+
void UpdateSellSmashArrowBuffer()
{
   int copied = CopyBuffer(hiddenSmashDayIndicatorHandle,
                           1,          // Sell buffer index
                           0,          // Start from most recent bar
                           5,          // Number of values to copy
                           sellSmashArrowBuffer);

   if(copied <= 0)
   {
      Print("Failed to copy sell smash arrow buffer. Error: ", GetLastError());
   }
}

Diese zweite Funktion führt denselben Vorgang für bärische Signale durch. Diese Funktionen werden jedes Mal ausgeführt, wenn eine neue Bar erscheint.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(){

   ...
   
   if(IsNewBar(_Symbol, timeframe, lastBarOpenTime)){
      UpdateBuySmashArrowBuffer ();
      UpdateSellSmashArrowBuffer();
   }
}

Dadurch wird sichergestellt, dass die Arrays stets aktuelle Daten enthalten, bevor die Signalauswertung beginnt.

Erkennung gültiger Hidden-Smash-Signale

Nach der Aktualisierung der Indikatorpuffer kann das Programm feststellen, ob ein Handelssignal vorliegt. Diese Aufgabe wird von zwei Funktionen übernommen. Erstens,

//+------------------------------------------------------------------+
//| Returns true if a bullish Hidden Smash signal exists at index    |
//+------------------------------------------------------------------+
bool IsBullishHiddenSmashSignal(int index)
{
   if(index < 0)
      return false;

   if(buySmashArrowBuffer[index] != EMPTY_VALUE)
      return true;

   return false;
}

Diese Funktion überprüft den Kaufpuffer am angegebenen Index. Ist der Wert nicht leer, hat der Indikator ein bullisches Smash-Muster erkannt. Zweitens,

//+------------------------------------------------------------------+
//| Returns true if a bearish Hidden Smash signal exists at index    |
//+------------------------------------------------------------------+
bool IsBearishHiddenSmashSignal(int index)
{
   if(index < 0)
      return false;

   if(sellSmashArrowBuffer[index] != EMPTY_VALUE)
      return true;

   return false;
}

Die zweite Funktion führt dieselbe Auswertung für bärische Signale durch. Diese Funktionen ermöglichen es dem Expert Advisor, nur dann zu reagieren, wenn ein gültiges Muster vorliegt.

Aktualisierung der Supertrend-Kontextdaten

Die Strategie kann optional Trades anhand der vom Supertrend-Indikator angegebenen Trendrichtung filtern. Um diese Informationen nutzen zu können, muss das Programm zunächst die Indikatorwerte abrufen.

//+------------------------------------------------------------------+
//| Fetches recent Supertrend upper and lower band values            |
//+------------------------------------------------------------------+
void UpdateSupertrendBandValues(){

   //--- Get a few Supertrend upper band values
   int copiedUpper = CopyBuffer(supertrendIndicatorHandle, 5, 0, 5, upperBandValues);
   if(copiedUpper == -1)
   {
      Print("Error while copying Supertrend upper band values: ", GetLastError());
      return;
   }

   //--- Get a few Supertrend lower band values
   int copiedLower = CopyBuffer(supertrendIndicatorHandle, 6, 0, 5, lowerBandValues);
   if(copiedLower == -1)
   {
      Print("Error while copying Supertrend lower band values: ", GetLastError());
      return;
   }
   
   if(copiedUpper < 5 || copiedLower < 5){
      Print("Insufficient Supertrend indicator data!");
      return;
   }   
}

Diese Funktion ruft die aktuellen Supertrend-Bandwerte ab und speichert sie zur späteren Analyse in Arrays. Sie wird außerdem immer dann aufgerufen, wenn eine neue Bar erscheint.

Ermittlung des aktuellen Trendzustands

Der Supertrend-Indikator kann nur zwei Zustände annehmen: bullisch oder bärisch. Zwei kleine Funktionen bestimmen die aktuelle Trendrichtung.

//+------------------------------------------------------------------+
//| Returns true if Supertrend is currently in a bullish trend state |
//+------------------------------------------------------------------+
bool IsSupertrendCurrentlyBullish(){

   if(lowerBandValues[1] != EMPTY_VALUE){
      return true;
   }

   return false;
}

Diese Funktion gibt true zurück, wenn der Indikator auf eine bullische Marktlage hindeutet.

//+------------------------------------------------------------------+
//| Returns true if Supertrend is currently in a bearish trend state |
//+------------------------------------------------------------------+
bool IsSupertrendCurrentlyBearish(){

   if(upperBandValues[1] != EMPTY_VALUE){
      return true;
   }

   return false;
}

Diese Funktion gibt true zurück, wenn bärische Bedingungen vorliegen. Diese Funktionen ermöglichen es dem Expert Advisor, bei aktiviertem Filter Trades ausschließlich in Richtung des vorherrschenden Trends zu eröffnen.

Aktualisierung der ATR-Werte für volatilitätsbasierte Stopps

Die Strategie unterstützt einen volatilitätsbasierten Stop-Loss-Modus, der den Average True Range-Indikator nutzt. Um ATR-Werte zu erhalten, definieren wir die folgende Funktion.

//+------------------------------------------------------------------+
//| To update ATR values                                             |
//+------------------------------------------------------------------+
void UpdateATRValues(){
   
   //--- Get some ATR Values
   int numberOfCopiedATRValues = CopyBuffer(atrHandle, 0, 0, 5, atrValues);
   if(numberOfCopiedATRValues == -1){
      Print("Error while copying ATR values: ", GetLastError());
   }
}

Diese Funktion aktualisiert das ATR-Array, damit das Programm später Stop-Loss-Niveaus auf der Grundlage der aktuellen Marktvolatilität berechnen kann.

Implementierung des Trade-Day-Filters

Manche Trader ziehen es vor, den Handel auf bestimmte Wochentage zu beschränken. Der Expert Advisor verfügt zu diesem Zweck über einen konfigurierbaren Filter. Die folgende Hilfsfunktion ermittelt den Wochentag.

//+------------------------------------------------------------------+
//| Returns the day of the week (0 = Sunday, 6 = Saturday) for the given datetime value|                               
//+------------------------------------------------------------------+
int TimeDayOfWeek(datetime time){
   MqlDateTime timeStruct = {};
   if(!TimeToStruct(time, timeStruct)){
      Print("TimeDayOfWeek: TimeToStruct failed");
      return -1;
   }      
   return timeStruct.day_of_week;
}

Anhand dieses Werts kann das Programm prüfen, ob der Handel zulässig ist.

//+------------------------------------------------------------------+
//| Determines whether trading is permitted for the given datetime based on the selected trade-day mode |                               
//+------------------------------------------------------------------+
bool IsTradingDayAllowed(datetime time)
{
   // Baseline mode: no filtering
   if(tradeDayMode == TDW_ALL_DAYS){
      return true;
   }

   int day = TimeDayOfWeek(time);

   switch(day)
   {
      case 0: return tradeSunday;
      case 1: return tradeMonday;
      case 2: return tradeTuesday;
      case 3: return tradeWednesday;
      case 4: return tradeThursday;
      case 5: return tradeFriday;
      case 6: return tradeSaturday;
   }

   return false;
}

Diese Funktion liest die Benutzerkonfiguration ein und ermittelt, ob am aktuellen Tag gehandelt werden darf.

Prüfung auf bereits vorhandene Positionen

Das System lässt jeweils nur eine offene Position zu. Bevor ein Trade eröffnet wird, muss das Programm sicherstellen, dass keine anderen Positionen bestehen. Die folgende Funktion prüft, ob aktive Kaufpositionen vorhanden sind.

//+------------------------------------------------------------------+
//| To verify whether this EA currently has an active buy position.  |                                 |
//+------------------------------------------------------------------+
bool IsThereAnActiveBuyPosition(ulong magic){
   
   for(int i = PositionsTotal() - 1; i >= 0; i--){
      ulong ticket = PositionGetTicket(i);
      if(ticket == 0){
         Print("Error while fetching position ticket ", _LastError);
         continue;
      }else{
         if(PositionGetInteger(POSITION_MAGIC) == magic && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){
            return true;
         }
      }
   }
   
   return false;
}

Die nächste Funktion führt dieselbe Überprüfung für Verkaufspositionen durch.

//+------------------------------------------------------------------+
//| To verify whether this EA currently has an active sell position. |                                 |
//+------------------------------------------------------------------+
bool IsThereAnActiveSellPosition(ulong magic){
   
   for(int i = PositionsTotal() - 1; i >= 0; i--){
      ulong ticket = PositionGetTicket(i);
      if(ticket == 0){
         Print("Error while fetching position ticket ", _LastError);
         continue;
      }else{
         if(PositionGetInteger(POSITION_MAGIC) == magic && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL){
            return true;
         }
      }
   }
   
   return false;
}

Diese Funktionen sorgen dafür, dass die Eine-Position-Regel der Strategie eingehalten wird.

Berechnung der risikobasierten Positionsgröße

Das Risikomanagement wird optional durch eine dynamische Positionsgrößenanpassung umgesetzt.

//+------------------------------------------------------------------+
//| Calculates position size using OrderCalcProfit for accuracy      |
//+------------------------------------------------------------------+
double CalculatePositionSizeByRisk(ENUM_ORDER_TYPE orderType, double entryPrice, double stopLossPrice){

   //--- Amount willing to risk
   double amountAtRisk = (riskPerTradePercent / 100.0) *
                         AccountInfoDouble(ACCOUNT_BALANCE);

   //--- Calculate loss for 1 lot
   double lossPerLot = 0.0;

   if(!OrderCalcProfit(orderType,
                       _Symbol,
                       1.0,              // 1 lot
                       entryPrice,
                       stopLossPrice,
                       lossPerLot))
   {
      Print("OrderCalcProfit failed: ", GetLastError());
      return 0.0;
   }

   // Loss will be negative for losing scenario
   lossPerLot = MathAbs(lossPerLot);

   if(lossPerLot <= 0.0)
      return 0.0;

   //--- Raw volume
   double volume = amountAtRisk / lossPerLot;

   //--- Apply broker constraints
   double minLot   = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double maxLot   = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
   double lotStep  = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);

   // Normalize to step
   volume = MathFloor(volume / lotStep) * lotStep;

   if(volume < minLot)
      volume = minLot;

   if(volume > maxLot)
      volume = maxLot;

   return NormalizeDouble(volume, 2);
}

Diese Funktion ermittelt das maximale Handelsvolumen, das gehandelt werden kann, ohne mehr als den festgelegten Prozentsatz des Kontoguthabens zu riskieren. Mithilfe der Funktion OrderCalcProfit wird der potenzielle Verlust pro Lot geschätzt und anschließend das Volumen entsprechend angepasst. Das Ergebnis wird so angepasst, dass es den Mindest- und Höchstgrenzen des Brokers für die Lotgröße entspricht.

Berechnung von Stop-Loss- und Take-Profit-Niveaus

Zwei Funktionen berechnen die Stop-Loss-Werte auf der Grundlage des gewählten Stop-Loss-Modus. In einem Modus befindet sich der Extrempunkt am äußersten Ende der Smash-Bar. Im anderen Modus wird der Stopp auf der Grundlage der ATR-Volatilität gesetzt.

//+--------------------------------------------------------------------------+
//| Computes the bullish stop loss level based on the index of the smash bar |
//+--------------------------------------------------------------------------+
double GetBuyStopLoss(int index){

   if(smashStopLossMode == SL_ATR_BASED){
      double atrValue = atrValues[1] * atrMultiplier;
      double slLevel  = askPrice - atrValue;
      return NormalizeDouble(slLevel, Digits());
   }else{
      return NormalizeDouble(iLow(_Symbol, timeframe, index), Digits());
   }   
}

Diese Funktion gibt das Stop-Loss-Niveau für Kaufpositionen zurück.

//+--------------------------------------------------------------------------+
//| Computes the bearish stop loss level based on the index of the smash bar |
//+--------------------------------------------------------------------------+
double GetSellStopLoss(int index){

   if(smashStopLossMode == SL_ATR_BASED){
      double atrValue = atrValues[1] * atrMultiplier;
      double slLevel  = bidPrice + atrValue;
      return NormalizeDouble(slLevel, Digits());
   }else{
      return NormalizeDouble(iHigh(_Symbol, timeframe, index), Digits());
   }   
}

Diese Funktion führt dieselbe Berechnung für Verkaufsgeschäfte durch.

Die Take-Profit-Niveaus werden anhand der festgelegten Risikodistanz abgeleitet.

//+--------------------------------------------------------------------------------------------------+
//| Computes the bullish take profit level based on entry price, stop loss, and risk to reward ratio |
//+--------------------------------------------------------------------------------------------------+
double GetBuyTakeProfit(double entryPrice, double stopLoss){
   double riskDistance = entryPrice - stopLoss;
   double rewardDistance = riskDistance * riskRewardRatio;
   rewardDistance = MathAbs(rewardDistance);
   return NormalizeDouble((entryPrice + rewardDistance), Digits());
}

und

//+--------------------------------------------------------------------------------------------------+
//| Computes the bearish take profit level based on entry price, stop loss, and risk to reward ratio |
//+--------------------------------------------------------------------------------------------------+
double GetSellTakeProfit(double entryPrice, double stopLoss){
   double riskDistance = stopLoss - entryPrice;
   double rewardDistance = riskDistance * riskRewardRatio;
   rewardDistance = MathAbs(rewardDistance);
   return NormalizeDouble((entryPrice - rewardDistance), Digits());
}

Diese Funktionen wenden das konfigurierte Risiko-Ertrags-Verhältnis an.

Versand von Handelsaufträgen

Sobald alle Bedingungen erfüllt sind, sendet der Expert Advisor den Auftrag an den Handelsserver.

//+------------------------------------------------------------------+
//| Function to open a market buy position                           |
//+------------------------------------------------------------------+
bool OpenBuy(double entryPrice, double stopLoss, double takeProfit, double lotSize){
   
   if(lotSizeMode == MODE_AUTO){
      lotSize = CalculatePositionSizeByRisk(ORDER_TYPE_BUY, entryPrice, stopLoss);
   }
   
   if(!Trade.Buy(lotSize, _Symbol, entryPrice, stopLoss, takeProfit)){
      Print("Error while executing a market buy order: ", GetLastError());
      Print(Trade.ResultRetcode());
      Print(Trade.ResultComment());
      return false;
   }
   return true;
}

Diese Funktion eröffnet eine Marktkaufposition.

//+------------------------------------------------------------------+
//| Function to open a market sell position                          |
//+------------------------------------------------------------------+
bool OpenSell(double entryPrice, double stopLoss, double takeProfit, double lotSize){
   
   if(lotSizeMode == MODE_AUTO){
      lotSize = CalculatePositionSizeByRisk(ORDER_TYPE_SELL, entryPrice, stopLoss);
   }
   
   if(!Trade.Sell(lotSize, _Symbol, entryPrice, stopLoss, takeProfit)){
      Print("Error while executing a market sell order: ", GetLastError());
      Print(Trade.ResultRetcode());
      Print(Trade.ResultComment());
      return false;
   }
   return true;
}

Diese Funktion eröffnet eine Verkaufsposition am Markt. Beide Funktionen berechnen zudem die automatische Positionsgröße, wenn der Automatikmodus aktiviert ist.

Die Handelslogik zusammenführen

Nachdem nun alle Hilfsfunktionen implementiert sind, besteht der letzte Schritt darin, die gesamte Handelslogik innerhalb der OnTick-Funktion zusammenzufügen.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(){

   ...
   
   if(IsNewBar(_Symbol, timeframe, lastBarOpenTime)){
      
      ...
      
      double stopLossLevel   = 0.000000;
      double takeProfitLevel = 0.000000;
      
      //--- Act on a bullish signal
      if(IsBullishHiddenSmashSignal(2)){
      
         stopLossLevel   = GetBuyStopLoss(2);
         takeProfitLevel = GetBuyTakeProfit(askPrice, stopLossLevel);
         if(!IsThereAnActiveBuyPosition(magicNumber) && !IsThereAnActiveSellPosition(magicNumber)){
            if(smashTradeMode == SMASH_TRADE_BUY_ONLY || smashTradeMode == SMASH_TRADE_BOTH){
               if(useSupertrendFilter){
                  if(IsSupertrendCurrentlyBullish()){
                     //---
                     if(tradeDayMode == TDW_SELECTED_DAYS){
                        if(IsTradingDayAllowed(currentTime)){
                           OpenBuy(askPrice, stopLossLevel, takeProfitLevel, positionSize);
                        }
                     }else{
                        OpenBuy(askPrice, stopLossLevel, takeProfitLevel, positionSize);
                     }
                  }
               }else{
                  //---
                  if(tradeDayMode == TDW_SELECTED_DAYS){
                     if(IsTradingDayAllowed(currentTime)){
                        OpenBuy(askPrice, stopLossLevel, takeProfitLevel, positionSize);
                     }
                  }else{
                     OpenBuy(askPrice, stopLossLevel, takeProfitLevel, positionSize);
                  }
               }
            }
         }
      }
      
      //--- Act on a bearish signal
      if(IsBearishHiddenSmashSignal(2)){
         stopLossLevel   = GetSellStopLoss(2);
         takeProfitLevel = GetSellTakeProfit(bidPrice, stopLossLevel);
         if(!IsThereAnActiveBuyPosition(magicNumber) && !IsThereAnActiveSellPosition(magicNumber)){
            if(smashTradeMode == SMASH_TRADE_SELL_ONLY || smashTradeMode == SMASH_TRADE_BOTH){
               if(useSupertrendFilter){
                  if(IsSupertrendCurrentlyBearish()){
                     //---
                     if(tradeDayMode == TDW_SELECTED_DAYS){
                        if(IsTradingDayAllowed(currentTime)){
                           OpenSell(bidPrice, stopLossLevel, takeProfitLevel, positionSize);
                        }
                     }else{
                        OpenSell(bidPrice, stopLossLevel, takeProfitLevel, positionSize);
                     }
                  }
               }else{
                  //---
                  if(tradeDayMode == TDW_SELECTED_DAYS){
                     if(IsTradingDayAllowed(currentTime)){
                        OpenSell(bidPrice, stopLossLevel, takeProfitLevel, positionSize);
                     }
                  }else{
                     OpenSell(bidPrice, stopLossLevel, takeProfitLevel, positionSize);
                  }
               }
            }
         }
      }
   }
}

Diese Funktion wertet Signale aus, sobald eine neue Bar erscheint, überprüft alle Kontextfilter, berechnet Risikoparameter und führt Trades nur dann aus, wenn alle Bedingungen erfüllt sind.

Die daraus resultierende Struktur gewährleistet, dass Signale validiert, Risiken berechnet und Trades einheitlich und kontrolliert ausgeführt werden.

Verbesserung der Chart-Darstellung während des Testens

Bevor man mit dem Testen von Strategien beginnt, ist es sinnvoll, die Darstellung des Charts so anzupassen, dass die Übersichtlichkeit verbessert wird. Die folgende Funktion dient zur Anpassung der Chartfarben und Anzeigeeinstellungen.

//+------------------------------------------------------------------+
//| This function configures the chart's appearance.                 |
//+------------------------------------------------------------------+
bool ConfigureChartAppearance()
{
   if(!ChartSetInteger(0, CHART_COLOR_BACKGROUND, clrWhite)){
      Print("Error while setting chart background, ", GetLastError());
      return false;
   }
   
   if(!ChartSetInteger(0, CHART_SHOW_GRID, false)){
      Print("Error while setting chart grid, ", GetLastError());
      return false;
   }
   
   if(!ChartSetInteger(0, CHART_MODE, CHART_CANDLES)){
      Print("Error while setting chart mode, ", GetLastError());
      return false;
   }

   if(!ChartSetInteger(0, CHART_COLOR_FOREGROUND, clrBlack)){
      Print("Error while setting chart foreground, ", GetLastError());
      return false;
   }

   if(!ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, clrSeaGreen)){
      Print("Error while setting bullish candles color, ", GetLastError());
      return false;
   }
      
   if(!ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, clrBlack)){
      Print("Error while setting bearish candles color, ", GetLastError());
      return false;
   }
   
   if(!ChartSetInteger(0, CHART_COLOR_CHART_UP, clrSeaGreen)){
      Print("Error while setting bearish candles color, ", GetLastError());
      return false;
   }
   
   if(!ChartSetInteger(0, CHART_COLOR_CHART_DOWN, clrBlack)){
      Print("Error while setting bearish candles color, ", GetLastError());
      return false;
   }
   
   return true;
}

Diese Funktion entfernt die Gitterlinien und legt klare Barfarben fest, wodurch Signale und Kursbewegungen während des Tests leichter zu erkennen sind.

Die Funktion wird bereits in der Initialisierungsphase aufgerufen.

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(){

   ...   
   
   //--- To configure the chart's appearance
   if(!ConfigureChartAppearance()){
      Print("Error while configuring chart appearance", GetLastError());
      return INIT_FAILED;
   }

   return(INIT_SUCCEEDED);
}

Kompilieren des Expert Advisors

Zum jetzigen Zeitpunkt ist die Kernimplementierung des Expert Advisors abgeschlossen. Der Quellcode kann nun in MetaEditor kompiliert werden. Wenn die Entwicklungsschritte korrekt befolgt wurden, sollte das Programm fehlerfrei kompiliert werden können.

Sollten beim Kompilieren Probleme auftreten, kann die beigefügte Quelldatei lwHiddenSmashDayContextExpert.mq5 als Referenz zur Überprüfung der Implementierung herangezogen werden.

Im nächsten Abschnitt dieses Artikels geht es von der Entwicklung zum Testen und zur Bewertung der Strategie des Handelssystems über. 


Testen der Hidden-Smash-Day-Kontext-Strategie

Bevor wir die langfristige Performance bewerten, wollen wir zunächst sicherstellen, dass der Expert Advisor Trades gemäß dem zuvor in diesem Artikel beschriebenen Hidden-Smash-Day-Muster ausführt.

Daher werden zunächst zwei Screenshots gezeigt. Ein Bild zeigt eine aktive Long-Position.

Long-Position

Der andere Screenshot zeigt eine aktive Short-Position.

Short-Position

Diese Beispiele zeigen, dass das System Hidden-Smash-Day-Konstellationen korrekt erkennt und Trades erst ausführt, nachdem eine gültige Bestätigungsbar erscheint.

Im Beispiel für eine Long-Position schließt die Smash-Bar im unteren Bereich ihrer Spanne und gleichzeitig über dem Schlusskurs der vorherigen Bar. Die folgende Bar schließt über dem Höchststand der Smash-Bar, wodurch ein gültiges Kaufsignal ausgelöst wird. Bei der Eröffnung der nächsten Bar eröffnet der Expert Advisor gemäß den festgelegten Regeln eine Long-Position.

Im Beispiel für eine Short-Position schließt die Smash Bar im oberen Bereich ihrer Spanne und gleichzeitig unterhalb des Schlusskurses der vorherigen Bar. Die nächste Bar schließt unterhalb des Tiefststands der Smash-Bar, was ein bestätigtes Verkaufssignal erzeugt. Der Expert Advisor eröffnet dann bei der Eröffnung der nächsten Bar eine Short-Position.

Diese Beispiele belegen, dass sich die zuvor implementierte Signalerkennungslogik genau wie beabsichtigt verhält. Nachdem diese Überprüfung abgeschlossen ist, besteht der nächste Schritt darin, zu untersuchen, wie sich das System bei der Anwendung auf historische Daten verhält.

Experiment 1: Handel mit allen Hidden-Smash-Signalen

Im ersten Experiment wird die Strategie ohne Trendfilterung bewertet. In dieser Konfiguration darf der Expert Advisor jedes gültige Hidden-Smash-Day-Muster handeln. Es wurden die folgenden Umgebungseinstellungen verwendet.

Zeitrahmen:

Täglich D1

Testzeitraum: 

1. Januar 2025 bis 28. Februar 2026

Sowohl Kauf- als auch Verkaufs-Smash-Setups wurden aktiviert, damit das System alle gültigen Signale erfassen konnte. Die Positionsgröße wurde automatisch anhand der AUTO_MODE-Konfiguration festgelegt, und das Risiko pro Trade wurde auf 1 % des Kontostands begrenzt.

Damit diese Ergebnisse reproduziert werden können, sind dem Artikel zwei Dateien beigefügt.

  • configurations_exp1.ini, die die Umgebungseinstellungen für den Strategy Tester enthält
  • parameters_exp1.set, das die genauen Eingabeparameter des Expert Advisors enthält, die bei diesem Test verwendet wurden

Das Experiment begann mit einem Kontostand von 10.000 Dollar. Am Ende des Testzeitraums erzielte die Strategie einen Nettogewinn von insgesamt 1058,18 Dollar, was einer Rendite von etwas mehr als zehn Prozent entspricht.

Testerbericht

Die Gewinnrate lag bei diesem Test bei 100 %. Die zugehörige Kapitalkurve zeigt einen gleichmäßigen Anstieg ohne ausgeprägten Drawdown.

Kapitalkurve exp1

Dies deutet darauf hin, dass das Hidden-Smash-Day-Muster während des ausgewählten Testzeitraums eine Reihe klarer Signale für Gold erzeugt hat.

Experiment 2: Supertrend-Marktkontext hinzufügen

Im zweiten Experiment wird dieselbe Strategie bewertet, wobei der Marktkontext mithilfe des Supertrend-Filters einbezogen wird.

In dieser Konfiguration eröffnet der Expert Advisor nur dann Positionen, wenn das Signal mit der Richtung des Supertrend-Indikators übereinstimmt, der auf dem wöchentlichen Zeitrahmen berechnet wird. Dadurch wird eine Trendbedingung aus einem höheren Zeitrahmen in den Entscheidungsprozess einbezogen.

Die Testumgebung blieb gegenüber dem ersten Experiment unverändert.

Zeitrahmen

Täglich D1

Testphase

1. Januar 2025 bis 28. Februar 2026

Sowohl die Smash-Setups für Kauf als auch für Verkauf blieben aktiviert, und bei der Positionsgrößenbestimmung wurde weiterhin der AUTO_MODE mit einem Risiko von 1 % pro Trade verwendet. Die zur Wiederholung dieses Experiments erforderlichen Dateien sind ebenfalls beigefügt.

  • configurations_exp2.ini, in der die Umgebungseinstellungen des Strategy Testers gespeichert sind
  • parameters_exp2.set, in dem die Parameterkonfiguration des Expert Advisors gespeichert ist

Ausgehend von einem Kontostand von 10.000 Dollar erzielte die Strategie während des Testzeitraums einen Nettogewinn von insgesamt 1.862,62 Dollar.

Testbericht für Exp2

Dies entspricht einer Kapitalrendite von etwas über 18 %. Auch die Gewinnquote lag während dieses Experiments bei 100 %.

Beobachtungen aus den Experimenten

Aus diesen beiden Tests lassen sich mehrere Schlussfolgerungen ziehen.

Das erste Experiment zeigt, dass Hidden-Smash-Day-Umkehrbewegungen profitable Trades generieren können, wenn sie mechanisch und unter Einhaltung eines kontrollierten Risikomanagements ausgeführt werden.

Das zweite Experiment zeigt, dass die Einbeziehung des Marktkontexts durch einen Trendfilter mit höherem Zeitrahmen die Ergebnisse erheblich beeinflussen kann. In diesem Fall hat der Supertrend-Filter unnötige Trades reduziert und die Gesamtperformance verbessert.

Man sollte bedenken, dass diese Ergebnisse ausschließlich den spezifischen Markt und den Testzeitraum widerspiegeln, die in dieser Studie herangezogen wurden. Unterschiedliche Instrumente, Datenquellen oder Zeiträume können zu unterschiedlichen Ergebnissen führen.

Systemeinschränkungen

Obwohl der Expert Advisor das Hidden-Smash-Day-Konzept eindeutig umsetzt, ist er bewusst einfach gehalten. Einige Funktionen sind im aktuellen Entwurf nicht enthalten.

  • Kein Handelsfilter nach Tageszeit
  • Keine Spread-Kontrolle oder Ausführungsfilter
  • Kein Schutz vor aktuellen Nachrichtenereignissen

Diese Faktoren können das Verhalten automatisierter Systeme beeinflussen und könnten Gegenstand zukünftiger Forschungsarbeiten sein.

Der in diesem Artikel entwickelte Expert Advisor wurde bewusst mit flexiblen Eingabeparametern konzipiert. Der Stop-Loss-Modus, die Handelsrichtung, die Trendfilterung und die Risikomanagement-Einstellungen lassen sich alle ganz einfach über das Eingabefeld anpassen. Aufgrund dieser Flexibilität kann das System eher als Forschungs-Framework denn als festgelegte Handelslösung dienen.

Weitere Experimente über verschiedene Märkte, Zeiträume und Parameterkombinationen hinweg könnten zusätzliche Erkenntnisse über das Konzept des Hidden-Smash-Day liefern.

Die Leser sind dazu aufgerufen, eigene Tests durchzuführen und ihre Ergebnisse im Kommentarbereich des Artikels mitzuteilen. Das Feedback der Community trägt oft dazu bei, neue Ideen und Verbesserungsmöglichkeiten aufzudecken, die dem gesamten Forschungsprozess zugutekommen.



Schlussfolgerung

In diesem Artikel ging es darum, das Konzept der Hidden-Smash-Day-Umkehrung in ein strukturiertes Handelssystem umzusetzen, das automatisch ausgeführt werden kann.

Auf der Grundlage des zuvor in dieser Reihe entwickelten Indikators wurde ein vollständiger Expert Advisor erstellt, der Hidden-Smash-Signale auswertet, die Marktbedingungen beurteilt, Risikoparameter berechnet und Trades nach klar definierten Regeln ausführt.

Im Laufe der Entwicklung wurden mehrere praktische Komponenten implementiert.

  • Erkennung bestätigter Hidden-Smash-Day-Signale
  • Optionale Trendfilterung mithilfe eines Supertrend-Indikators
  • Filterung nach Handelstagen zur Steuerung, wann gehandelt werden darf
  • Zwei Stop-Loss-Modi, basierend auf Struktur oder Volatilität
  • Automatische Positionsgrößenbestimmung auf Basis des Kontorisikos
  • Ausführungslogik, die sich überschneidende Trades verhindert

Wenn der Leser die in diesem Artikel beschriebenen Schritte befolgt, verfügt er nun über einen voll funktionsfähigen Expert Advisor, der direkt in MetaTrader kompiliert und getestet werden kann.

Das System bietet zudem ein flexibles Framework für weitere Forschungsarbeiten. Da jede Komponente modular aufgebaut ist, lassen sich zusätzliche Filter, Risikomodelle oder Kontextbedingungen integrieren, ohne dass das gesamte Programm neu geschrieben werden muss.

Vor allem zeigt diese Arbeit, wie sich eine Handelsidee von einem auf Charts basierenden Konzept in einen reproduzierbaren Algorithmus umsetzen lässt. Wenn Regeln im Code klar formuliert sind, lassen sie sich anhand historischer Daten objektiv testen und durch Experimente verfeinern.

Im Folgenden finden Sie eine Beschreibung aller zu diesem Artikel angehängten Dateien:

Dateiname Beschreibung
lwHiddenSmashDayContextExpert.mq5 
Die fertige Quelldatei des in diesem Artikel entwickelten Expert Advisors
configurations_exp1.ini
Konfigurationsdatei des Strategietesters mit den für Experiment 1 verwendeten Umgebungseinstellungen
parameters_exp1.set 
Für Experiment 1 verwendete Eingabeparameter
configurations_exp2.ini
Konfigurationsdatei des Strategietesters mit den für Experiment 2 verwendeten Umgebungseinstellungen
parameters_exp2.set
Für Experiment 2 verwendete Eingabeparameter

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

Entwicklung eines dynamischen Multi-Pair-EA (Teil 7): Paarübergreifende Korrelationsabbildung für die Handelsfilterung in Echtzeit Entwicklung eines dynamischen Multi-Pair-EA (Teil 7): Paarübergreifende Korrelationsabbildung für die Handelsfilterung in Echtzeit
In diesem Abschnitt werden wir eine Echtzeit-Korrelationsmatrix in einen Expert Advisor für mehrere Symbole integrieren, um redundante oder risikobehaftete Trades zu vermeiden. Durch die dynamische Messung der Wechselbeziehungen zwischen Symbolen filtert der EA Einstiegssignale heraus, die im Widerspruch zur bestehenden Exposition stehen, wodurch die Ausgewogenheit des Portfolios verbessert, das systemische Risiko verringert und die Qualität der Trades insgesamt verbessert wird.
MQL5-Handelswerkzeuge (Teil 24): Verbesserte Tiefenwahrnehmung mit 3D-Kurven, Pan-Modus und ViewCube-Navigation MQL5-Handelswerkzeuge (Teil 24): Verbesserte Tiefenwahrnehmung mit 3D-Kurven, Pan-Modus und ViewCube-Navigation
In diesem Artikel erweitern wir das Tool zur grafischen Darstellung der 3D-Binomialverteilung in MQL5, indem wir eine segmentierte 3D-Kurve für eine bessere Tiefenwahrnehmung der Wahrscheinlichkeitsmassenfunktion (Probability Mass Function, PMF) hinzufügen, einen Pan-Modus zur Verschiebung des Betrachtungsfokus integrieren und einen interaktiven ViewCube (Ansichtswürfel) mit Hover-Zonen und Animationen für schnelle Orientierungswechsel implementieren. Wir integrieren anklickbare Unterbereiche für Flächen, Kanten und Ecken in den ViewCube, um Kameraübergänge zu Standardansichten zu animieren, wobei umschaltbare 2D-/3D-Modi, Echtzeit-Aktualisierungen und anpassbare Parameter für eine immersive probabilistische Analyse im Handel beibehalten werden.
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.
PD-Arrays meistern: Optimierung des Handels mit Ungleichgewichten in PD-Arrays PD-Arrays meistern: Optimierung des Handels mit Ungleichgewichten in PD-Arrays
Dieser Artikel befasst sich mit einem spezialisierten, trendfolgenden EA, der deutlich machen soll, wie sich Setups, die sich aus Ungleichgewichten in Premium-/Discount-Bereichen (PD-Arrays) ergeben, definieren und nutzen lassen. In diesem Artikel wird ein EA ausführlich vorgestellt, der speziell für Trader entwickelt wurde, die PD-Arrays und Ungleichgewichte als Einstiegskriterien für ihre Trades und Handelsentscheidungen optimieren und nutzen möchten. Außerdem wird untersucht, wie sich Premium- und Discount-Zonen korrekt ermitteln und charakterisieren lassen und wie man sie jeweils validieren und nutzen kann, wenn sie unter den entsprechenden Marktbedingungen auftreten, um so die sich aus solchen Szenarien ergebenden Chancen bestmöglich zu nutzen.