
Entwicklung des Price Action Analysis Toolkit (Teil 25): Dual EMA Fractal Breaker
Inhalt
Einführung
In diesem Artikel wird die Entwicklung eines Instruments vorgestellt, das bei der Preisaktionsanalyse helfen soll, indem es eine tiefere und aufschlussreichere Bewertung unter Verwendung des ursprünglich von Bill Williams entwickelten Fraktal-Indikators ermöglicht.
Bill M. Williams (1932–2019) war ein einflussreicher amerikanischer Händler und Autor, der für seine Beiträge zur Handelspsychologie, zur technischen Analyse und zur Chaostheorie auf den Finanzmärkten bekannt ist. Im Laufe seiner Karriere untersuchte Williams die Aktien-, Rohstoff- und Devisenmärkte und entwickelte eine Reihe innovativer technischer Analysetools, um Trends und potenzielle Umkehrpunkte zu erkennen. Zu seinen bekanntesten Indikatoren gehören der Accelerator/Decelerator Oszillator, der Alligator-Indikator, der Awesome Oszillator, der Fractals-Indikator, der Gator Oszillator und der Market Facilitation Index. Heute werden diese Indikatoren aufgrund ihrer Effektivität bei der Analyse des Marktverhaltens auf den Devisen-, Aktien- und anderen Finanzmärkten weithin eingesetzt.
Der Fractals-Indikator, eine Schlüsselkomponente der Williams-Methode, wird in unserem Ansatz mit den Exponential Moving Averages (EMAs) mit Periodenlängen von 14 und 200 kombiniert. Durch die Integration der fraktalen Muster mit diesen dynamischen Trendfiltern ist unser Expert Advisor (EA) in der Lage, potenzielle Marktumkehrungen genau zu erkennen und gleichzeitig die Ausrichtung auf die allgemeine Trendrichtung zu gewährleisten. Diese kombinierte Strategie verbessert die Entscheidungsfindung beim Handel, indem sie die frühzeitige Erkennung von Umkehrsignalen und die Bestätigung der Trendstärke ermöglicht, was letztlich zu zuverlässigeren und wahrscheinlicheren Einstiegspunkten führt. Die Synergie zwischen Fraktalanalyse und gleitenden Durchschnitten bietet Händlern ein leistungsfähiges Instrument zur tieferen Interpretation von Kursbewegungen und hilft, das Timing zu optimieren und die Handelsergebnisse zu verbessern.
Die Strategie verstehen
Unser Expert Advisor (EA) verwendet drei technische Schlüsselindikatoren: den Fractal-Indikator, den EMA 14 und den EMA 200. Der von Bill Williams entwickelte Fraktal-Indikator ist ein beliebtes Instrument der technischen Analyse, um potenzielle Trendumkehrungen zu erkennen. Es erkennt bestimmte Preismuster, so genannte Fraktale, die als lokale Höchst- oder Tiefststände erscheinen und mögliche Wendepunkte auf dem Markt signalisieren. Diese Fraktale dienen als Unterstützungs- oder Widerstandsniveaus und bieten Händlern visuelle Anhaltspunkte, um Ein- und Ausstiegszeitpunkte genauer zu bestimmen.
Der Exponentielle Gleitende Durchschnitt (EMA) unterscheidet sich grundlegend vom Einfachen Gleitenden Durchschnitt (SMA), da er den jüngsten Kursdaten ein größeres Gewicht beimisst, was zu einem reaktionsschnelleren Indikator führt. Diese Gewichtung wird durch einen Glättungsfaktor erreicht, der die jüngsten Kurse exponentiell hervorhebt, sodass der EMA rascher auf Marktveränderungen reagieren kann. Folglich sind EMAs sehr effektiv, um sich abzeichnende Trends zu erfassen und frühzeitige Signale für Trendwechsel zu liefern, insbesondere über kürzere Zeiträume.
Der EMA 14 spiegelt in unserem Setup die kurzfristige Marktdynamik wider und reagiert schnell auf die jüngsten Kursbewegungen, sodass er sich für einen rechtzeitigen Handelseinstieg eignet. Umgekehrt ist der EMA 200 ein langfristiger Trendindikator, der kurzfristiges Rauschen glättet und die allgemeine Marktrichtung erkennen lässt. Wenn der Kurs über dem EMA 200 notiert, deutet dies auf einen langfristigen Aufwärtstrend hin; liegt er darunter, wird ein Abwärtstrend angedeutet. Darüber hinaus fungiert der EMA 200 häufig als dynamisches Unterstützungs- oder Widerstandsniveau, das Händlern hilft, falsche Signale herauszufiltern und die Gültigkeit des Trends zu bestätigen.
Kaufsignal (Aufwärtsausbruch):
Ein Kaufsignal wird ausgelöst, wenn mehrere Bedingungen gleichzeitig erfüllt sind, die auf eine starke Aufwärtsbewegung hindeuten. Zunächst überwacht der EA das jüngste fraktale Tief (das Unterstützungsniveau). Er sucht nach einem Szenario, in dem der aktuelle Marktpreis diese fraktale Unterstützungsebene überschreitet, was einen potenziellen Ausbruch signalisiert. Um zu bestätigen, dass sich der Markt in einem Aufwärtstrend befindet, prüft der EA, ob der aktuelle Kurs sowohl über dem EMA 14 als auch über dem EMA 200 liegt, wobei der EMA 14 über dem EMA 200 liegt, was auf einen Aufwärtstrend hinweist. Wenn diese Bedingungen zusammentreffen, wird ein Kaufsignal generiert. Visuelle Hinweise wie ein Aufwärtspfeil und eine Beschriftung werden auf dem Chart platziert, und ein Alarm kann ausgelöst werden, um den Händler zu benachrichtigen.
- Der Kurs kreuzt über der letzten fraktalen Unterstützungsmarke.
- Der aktuelle Kurs liegt über dem EMA 14 und dem EMA 200.
- Der EMA 14 liegt über dem EMA 200, was einen Aufwärtstrend bestätigt.
Abb. 1. Aufwärtsausbruch
Verkaufssignal (Abwärtsausbruch):
Umgekehrt wird ein Verkaufssignal ausgelöst, wenn der Kurs ein signifikantes fraktales Hoch (Widerstandsniveau) unterschreitet, was auf eine mögliche Abwärtsbewegung hinweist. Der EA beobachtet das jüngste fraktale Hoch und wartet darauf, dass der Marktpreis unter dieses Niveau bricht. Um zu überprüfen, ob der Markt abwärts tendiert, wird bestätigt, dass der aktuelle Kurs unter beiden EMAs liegt, wobei der EMA 14 unter dem EMA 200 liegt, was auf einen Abwärtstrend hinweist. Wenn diese Kriterien erfüllt sind, d. h. wenn der Kurs unter das fraktale Widerstandsniveau fällt und der Trend weiterhin rückläufig ist, wird ein Verkaufssignal ausgegeben. Ähnliche visuelle Markierungen wie Abwärtspfeile und Beschriftungen werden eingezeichnet, und es können Warnmeldungen aktiviert werden.
- Der Kurs kreuzt unter dem jüngsten fraktalen Widerstandsniveau.
- Der aktuelle Kurs liegt unter dem EMA 14 und dem EMA 200.
- Der EMA 14 liegt unter dem EMA 200, was einen Abwärtstrend bestätigt.
Abb. 2. Abwärtsausbruch
Aufschlüsselung der Code-Komponenten
Dieser EA integriert die Fraktalanalyse mit gleitenden Durchschnittstrendfiltern, um potenzielle Ausbruchspunkte im Markt zu identifizieren und zu visualisieren. Durch das Einzeichnen von horizontalen Ebenen an den jüngsten fraktalen Hochs und Tiefs werden kritische Unterstützungs- und Widerstandszonen markiert. Wenn der Kurs diese Niveaus in der durch den EMA-Trend bestätigten Richtung durchbricht, erzeugt der EA visuelle Signale (Pfeile und Etiketten) und akustische Warnungen, die den Entscheidungsprozess des Händlers vereinfachen. Der modulare Aufbau mit Funktionen für Zeichnung, Signalisierung und Datenverwaltung ermöglicht die Anpassung an verschiedene Handelsstile und -präferenzen. Darüber hinaus sorgt der Schwerpunkt auf Ressourcenmanagement und Sanierung für Stabilität und Klarheit während des Betriebs. Insgesamt bietet diese ausgeklügelte Kombination von Indikatoren und visuellen Hinweisen ein umfassendes Instrument für Händler, die fraktale Ausbruchschancen in einem Trendumfeld nutzen möchten.Header und Metadaten
Der erste Abschnitt des Codes enthält Metadaten, die die Autorenschaft, die Version und die Lizenzinformationen des Skripts beschreiben. Die Kommentare innerhalb von //+------------------------------------------------------------------+ dienen dazu, den Zweck des Skripts zu kennzeichnen und eine Zuordnung vorzunehmen. Die Direktiven #property geben den Urheberrechtsinhaber, einen Hyperlink zum Profil des Autors in der MetaTrader-Community und die Versionsnummer an und setzen strenge Kompilierungsregeln durch. Die Direktive #property strict ist besonders wichtig, da sie den Compiler anweist, strengere Codierungsstandards einzuhalten und potenzielle Fehler wie nicht deklarierte Variablen oder Typinkongruenzen zu erkennen. Diese Metadaten und Direktiven haben keinen Einfluss auf die Laufzeitlogik, sondern dienen der Dokumentation und sichern die Codequalität während der Kompilierung.
//+------------------------------------------------------------------+ //| Fractal Breakout, EMA 14 and EMA 200| //| Copyright 2025, MetaQuotes Ltd.| //| https://www.mql5.com/en/users/lynnchris| //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com/en/users/lynnchris" #property version "1.0" #property strict
Eingabe-Parameter
In diesem Abschnitt werden alle konfigurierbaren Parameter definiert, die ein Nutzer ändern kann, ohne den Kerncode zu verändern. Diese Eingaben umfassen den Zeitrahmen für die Analyse (InpTimeframe), die Anzahl der zu untersuchenden Balken (InpHistoryBars) und die Perioden für die beiden EMAs, die als Trendfilter dienen (InpEMA14Period und InpEMA200Period).
Die Farbparameter (InpBullColor und InpBearColor) ermöglichen die visuelle Anpassung der Pfeile und Linien, die Ausbrüche anzeigen. Textbeschriftungen (InpBullText und InpBearText) liefern beschreibende Anmerkungen zu den Signalen und verbessern die Übersichtlichkeit des Charts. Der Pfeilabstand (InpArrowOffset) und die Schriftgröße (InpArrowFontSize) ermöglichen eine weitere Kontrolle über die visuelle Darstellung, sodass der Händler die Beschriftungen bequem positionieren kann.
Das Warnsystem wird durch InpAlertsEnabled, das Pop-up-Benachrichtigungen ein- und ausschaltet, und InpAlertSoundFile, das die bei Erkennung abgespielte Sounddatei angibt, gesteuert. Diese Parameter machen den EA flexibel und anpassungsfähig an verschiedene Handelsstile und visuelle Vorlieben, sodass die Nutzer ihn an ihre spezifischen Bedürfnisse anpassen können.
input ENUM_TIMEFRAMES InpTimeframe = PERIOD_CURRENT; // chart TF input int InpHistoryBars = 200; // bars back to scan input int InpEMA14Period = 14; // fast EMA input int InpEMA200Period = 200; // slow EMA input color InpBullColor = clrLime; // bullish arrow color input color InpBearColor = clrRed; // bearish arrow color input string InpBullText = "BULL Break"; // bullish label input string InpBearText = "BEAR Break"; // bearish label input int InpArrowOffset = 20; // offset in points for label input int InpArrowFontSize = 12; // size of the arrow glyph input bool InpAlertsEnabled = true; // show pop-up alerts input string InpAlertSoundFile = "alert.wav"; // sound file in /Sounds/
Globale Variablen und Indikatorhandles
Die außerhalb von Funktionen deklarierten Variablen dienen als Speicher für Indikator-Handles und fraktale Datenarrays. Die Handles (hFractals, hEMA14, hEMA200) sind Verweise auf die Indikatorinstanzen, die während der Initialisierung erstellt wurden. Sie sind unverzichtbar, da sie es dem EA ermöglichen, mit den Puffern der Indikatoren zu interagieren, indem er Echtzeit- und historische Daten abruft. Die Arrays fractalUp[] und fractalDown[] sind dynamisch zugewiesene Puffer, die die Hoch- bzw. Tiefpunkte des Fraktals enthalten. Die Verwaltung dieser Variablen als globale Variablen stellt sicher, dass im gesamten Skript auf sie zugegriffen werden kann, insbesondere während der Verarbeitung in OnTick, bei der eine Echtzeitanalyse erfolgt.
int hFractals, hEMA14, hEMA200; double fractalUp[], fractalDown[];
Initialisierung (OnInit)
Während des Starts wird die Funktion OnInit aufgerufen, um die erforderlichen Ressourcen einzurichten. Es erstellt Indikator-Handles für Fraktale und EMAs mit Funktionen wie iFractals und iMA unter Angabe von Symbol und Zeitrahmen. Die erfolgreiche Erstellung dieser Handles ist von entscheidender Bedeutung; wenn ein Handle ungültig ist (z. B. aufgrund falscher Parameter oder nicht verfügbarer Daten), schlägt die Initialisierung fehl, wodurch der EA nicht ordnungsgemäß ausgeführt werden kann.
Der Code konfiguriert dann die fraktalen Datenfelder so, dass sie als Serien funktionieren, was bedeutet, dass die neuesten Daten bei Index 0 stehen, was die Rückwärtsanalyse vereinfacht. Durch die Anpassung der Größe dieser Arrays an die angegebene Anzahl der Balken wird sichergestellt, dass die Datenpuffer für eine effiziente Verarbeitung angemessen dimensioniert sind. Insgesamt schafft dieser Schritt die Grundlage für einen zuverlässigen Datenabruf, der für eine genaue Ausbruchserkennung unerlässlich ist.
int OnInit() { hFractals = iFractals(_Symbol, InpTimeframe); hEMA14 = iMA(_Symbol, InpTimeframe, InpEMA14Period, 0, MODE_EMA, PRICE_CLOSE); hEMA200 = iMA(_Symbol, InpTimeframe, InpEMA200Period,0, MODE_EMA, PRICE_CLOSE); if(hFractals==INVALID_HANDLE || hEMA14==INVALID_HANDLE || hEMA200==INVALID_HANDLE) return(INIT_FAILED); ArraySetAsSeries(fractalUp, true); ArraySetAsSeries(fractalDown, true); ArrayResize(fractalUp, InpHistoryBars); ArrayResize(fractalDown, InpHistoryBars); return(INIT_SUCCEEDED); }
Deinitialisierung (OnDeinit)
Wenn der EA aus dem Chart entfernt oder das Terminal geschlossen wird, wird OnDeinit ausgeführt, um die Ressourcen aufzuräumen. Es gibt die Indikator-Handles mit IndicatorRelease frei, gibt den zugehörigen Speicher frei und verhindert Lecks. Außerdem werden alle Objekte im Chart durchlaufen, identifiziert und die Objekte mit dem Präfix „FB_“, d. h. die visuellen Signale (Pfeile, Beschriftungen, Linien) gelöscht, die während der Ausführung erzeugt werden. Durch diese Bereinigung wird sichergestellt, dass nach der Deaktivierung des EA keine Objekte im Chart verbleiben, sodass eine saubere Chartumgebung erhalten bleibt und mögliche Konflikte oder Verwirrung bei nachfolgenden Analysen vermieden werden.
void OnDeinit(const int reason) { if(hFractals!=INVALID_HANDLE) IndicatorRelease(hFractals); if(hEMA14 !=INVALID_HANDLE) IndicatorRelease(hEMA14); if(hEMA200 !=INVALID_HANDLE) IndicatorRelease(hEMA200); for(int i=ObjectsTotal(0)-1; i>=0; i--) { string n = ObjectName(0,i); if(StringFind(n,"FB_")>=0) ObjectDelete(0,n); } }
Hauptverarbeitung (OnTick)
Die Kernlogik befindet sich in der Funktion OnTick, die jedes Mal ausgeführt wird, wenn ein neuer Markttick eintrifft. Zunächst werden die letzten Werte der beiden EMAs mit CopyBuffer abgerufen. Diese EMA-Werte dienen als Trendfilter: Ihre relative Position zeigt an, ob sich der Markt in einem Aufwärts- oder Abwärtstrend befindet, was die Ausbruchsentscheidung erleichtert. Wenn der Abruf der EMA-Daten fehlschlägt, wird die Funktion vorzeitig beendet, um fehlerhafte Signale zu vermeiden. Als Nächstes ruft die Funktion Fraktaldatenpuffer für die jüngsten hohen und niedrigen Fraktale ab, wiederum mit Fehlerprüfung. Der Code sucht dann rückwärts durch diese Puffer, um die letzten gültigen Fraktale zu finden, wobei alle Platzhalter mit EMPTY_VALUEs ignoriert werden. Durch die Identifizierung der letzten signifikanten fraktalen Punkte bestimmt der EA die kritischen Unterstützungs- oder Widerstandsniveaus, die Ausbrüche auslösen könnten. Anschließend werden mit Hilfe einer Hilfsfunktion horizontale Linien auf diesen Ebenen als visuelle Referenz gezeichnet. Die Debugging-Ausgabe des Terminals bietet Echtzeiteinblicke in die Niveaus, Preise und EMA-Zustände und hilft Händlern, die Logik zu überprüfen.
Schließlich prüft der EA auf Ausbruchsbedingungen: Ein Ausbruch nach unten liegt vor, wenn der vorherige Schlusskurs über dem Abwärtsniveau lag, der aktuelle Schlusskurs darunter kreuzt und der Kurs unter beiden EMAs in einem Abwärtstrend liegt. Umgekehrt wird ein Aufwärtsausbruch erkannt, wenn der vorherige Schlusskurs unter dem Aufwärtsniveau lag, das aktuelle Kreuz darüber liegt und der Kurs über beiden EMAs in einem Aufwärtstrend steht. Die Erkennung dieser Bedingungen löst die Signalisierungsfunktion aus.
void OnTick() { // 1) Read current EMAs double ema14Arr[1], ema200Arr[1]; if(CopyBuffer(hEMA14,0,0,1,ema14Arr)<=0 || CopyBuffer(hEMA200,0,0,1,ema200Arr)<=0) return; double ema14_now = ema14Arr[0]; double ema200_now = ema200Arr[0]; // 2) Read fractal history (skip current bar) if(CopyBuffer(hFractals,0,1,InpHistoryBars,fractalUp)<=0 || CopyBuffer(hFractals,1,1,InpHistoryBars,fractalDown)<=0) return; // 3) Find most recent valid fractals (ignore EMPTY_VALUE) int upShift=-1, downShift=-1; for(int i=1; i<InpHistoryBars; i++) { if(fractalUp[i] != EMPTY_VALUE && upShift<0) upShift = i+1; if(fractalDown[i] != EMPTY_VALUE && downShift<0) downShift = i+1; if(upShift>0 && downShift>0) break; } // 4) Levels double lvlUp = (upShift>0) ? fractalUp[upShift-1] : 0.0; double lvlDown = (downShift>0) ? fractalDown[downShift-1] : 0.0; // 5) Draw level lines DrawHLine("FB_LevelUp", lvlUp, InpBullColor); DrawHLine("FB_LevelDown", lvlDown, InpBearColor); // 6) DEBUG print double prevC = iClose(_Symbol,InpTimeframe,1); double currC = iClose(_Symbol,InpTimeframe,0); PrintFormat( "DBG lvlUp=%.5f lvlDown=%.5f prevC=%.5f currC=%.5f EMA14=%.5f EMA200=%.5f", lvlUp, lvlDown, prevC, currC, ema14_now, ema200_now ); // 7) Breakouts on the last closed candle (shift=1) // Bearish breakout detection if(lvlDown>0 && prevC>=lvlDown && currC<lvlDown && currC<ema14_now && currC<ema200_now && ema200_now>ema14_now) { Print(">>> Bear breakout triggered"); Signal(false, 1, lvlDown, ema14_now, ema200_now); } // Bullish breakout detection if(lvlUp>0 && prevC<=lvlUp && currC>lvlUp && currC>ema14_now && currC>ema200_now && ema14_now>ema200_now) { Print(">>> Bull breakout triggered"); Signal(true, 1, lvlUp, ema14_now, ema200_now); } }
Horizontale Linien zeichnen (DrawHLine)
Diese Utility-Funktion verwaltet die Erstellung und Aktualisierung von horizontalen Linien im Chart. Beim Aufruf wird geprüft, ob eine Linie mit dem angegebenen Namen existiert; falls nicht, wird eine neue gepunktete Linie auf dem angegebenen Preisniveau mit der angegebenen Farbe erstellt. Wenn die Zeile bereits existiert, wird ihre Position einfach aktualisiert. Dieser Ansatz verhindert, dass sich mehrere Linien überschneiden, und sorgt dafür, dass die visuellen Ebenen immer auf dem neuesten Stand der fraktalen Analyse sind. Der gepunktete Stil hilft, diese Linien von anderen Chartobjekten zu unterscheiden und ihre Rolle als Unterstützungs- oder Widerstandsniveaus zu betonen. Solche visuellen Anhaltspunkte sind für Händler von unschätzbarem Wert, da sie eine schnelle Erkennung von Ausbruchszonen ermöglichen und die manuelle oder automatische Entscheidungsfindung erleichtern.
void DrawHLine(string name, double price, color clr) { if(price<=0) return; if(ObjectFind(0,name)<0) { ObjectCreate(0,name,OBJ_HLINE,0,0,price); ObjectSetInteger(0,name,OBJPROP_COLOR,clr); ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DOT); ObjectSetInteger(0,name,OBJPROP_WIDTH,1); } else ObjectSetDouble(0,name,OBJPROP_PRICE,price); }
Signalisierung und Visualisierung (Signal)
Die Funktion Signal kapselt alle Aktionen im Zusammenhang mit der Signalisierung eines Breakout-Ereignisses. Zunächst wird der Zeitstempel des Balkens abgerufen, an dem das Signal aufgetreten ist, um eine genaue Platzierung der visuellen Objekte zu gewährleisten. Anschließend wird am Ausbruchsniveau ein Pfeilobjekt erstellt, das nach oben oder unten zeigt, je nachdem, ob es sich um eine Hausse oder Baisse handelt, wobei die Farbkodierung dem Trend entspricht. Das Erscheinungsbild des Pfeils wird zur besseren Übersichtlichkeit mit Parametern für Breite und Größe angepasst. Neben dem Pfeil wird eine Textbeschriftung leicht vertikal versetzt hinzugefügt, die eine beschreibende Nachricht wie „BULL Break“ oder „BEAR Break“ enthält und den visuellen Hinweis verstärkt.
Die Funktion protokolliert eine ausführliche Meldung auf der Registerkarte Experten, einschließlich der genauen Zeit, des Levels, des Schlusskurses und der EMA-Werte, und bietet so eine umfassende Aufzeichnung der Signale. Wenn Warnungen aktiviert sind, wird eine Pop-up-Meldung angezeigt und eine Tondatei abgespielt, um den Händler sofort zu informieren. Diese Kombination aus visuellen, akustischen und protokollbasierten Signalen stellt sicher, dass Händler umgehend über potenzielle Ausbruchschancen informiert werden und rechtzeitig handeln können.
void Signal(bool isBull, int shift, double level, double ema14, double ema200) { datetime t = iTime(_Symbol,InpTimeframe,shift); double price = level; string side = isBull ? "Bull" : "Bear"; // Arrow string arrowName = StringFormat("FB_%sArrow_%d", side, (int)t); ObjectCreate(0, arrowName, OBJ_ARROW, 0, t, price); ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, isBull?233:234); ObjectSetInteger(0, arrowName, OBJPROP_COLOR, isBull?InpBullColor:InpBearColor); ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, 2); ObjectSetInteger(0, arrowName, OBJPROP_FONTSIZE, InpArrowFontSize); // Label string lab = arrowName + "_L"; double offset = (isBull ? InpArrowOffset : -InpArrowOffset) * _Point; ObjectCreate(0, lab, OBJ_TEXT, 0, t, price + offset); ObjectSetString(0, lab, OBJPROP_TEXT, isBull?InpBullText:InpBearText); ObjectSetInteger(0, lab, OBJPROP_COLOR, isBull?InpBullColor:InpBearColor); ObjectSetInteger(0, lab, OBJPROP_FONTSIZE, 11); // Log message string msg = StringFormat( "%s breakout at %s | Level=%.5f | Close=%.5f | EMA14=%.5f | EMA200=%.5f", side, TimeToString(t, TIME_DATE|TIME_SECONDS), level, iClose(_Symbol,InpTimeframe,shift), ema14, ema200 ); Print(msg); // Alert and sound if(InpAlertsEnabled) { Alert(msg); if(StringLen(InpAlertSoundFile)>0) PlaySound(InpAlertSoundFile); } }
MQL5 Code
//+------------------------------------------------------------------+ //| Fractal Breakout, EMA 14 and EMA 200| //| Copyright 2025, MetaQuotes Ltd.| //| https://www.mql5.com/en/users/lynnchris| //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com/en/users/lynnchris" #property version "1.0" #property strict //---inputs input ENUM_TIMEFRAMES InpTimeframe = PERIOD_CURRENT; // chart TF input int InpHistoryBars = 200; // bars back to scan input int InpEMA14Period = 14; // fast EMA input int InpEMA200Period = 200; // slow EMA input color InpBullColor = clrLime; // bullish arrow color input color InpBearColor = clrRed; // bearish arrow color input string InpBullText = "BULL Break"; // bullish label input string InpBearText = "BEAR Break"; // bearish label input int InpArrowOffset = 20; // offset in points for label input int InpArrowFontSize = 12; // size of the arrow glyph input bool InpAlertsEnabled = true; // show pop-up alerts input string InpAlertSoundFile = "alert.wav"; // sound file in /Sounds/ //---indicator handles & buffers int hFractals, hEMA14, hEMA200; double fractalUp[], fractalDown[]; //+------------------------------------------------------------------+ //| Expert initialization | //+------------------------------------------------------------------+ int OnInit() { hFractals = iFractals(_Symbol, InpTimeframe); hEMA14 = iMA(_Symbol, InpTimeframe, InpEMA14Period, 0, MODE_EMA, PRICE_CLOSE); hEMA200 = iMA(_Symbol, InpTimeframe, InpEMA200Period,0, MODE_EMA, PRICE_CLOSE); if(hFractals==INVALID_HANDLE || hEMA14==INVALID_HANDLE || hEMA200==INVALID_HANDLE) return(INIT_FAILED); ArraySetAsSeries(fractalUp, true); ArraySetAsSeries(fractalDown, true); ArrayResize(fractalUp, InpHistoryBars); ArrayResize(fractalDown, InpHistoryBars); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if(hFractals!=INVALID_HANDLE) IndicatorRelease(hFractals); if(hEMA14 !=INVALID_HANDLE) IndicatorRelease(hEMA14); if(hEMA200 !=INVALID_HANDLE) IndicatorRelease(hEMA200); for(int i=ObjectsTotal(0)-1; i>=0; i--) { string n = ObjectName(0,i); if(StringFind(n,"FB_")>=0) ObjectDelete(0,n); } } //+------------------------------------------------------------------+ //| Tick handler | //+------------------------------------------------------------------+ void OnTick() { // 1) Read current EMAs double ema14Arr[1], ema200Arr[1]; if(CopyBuffer(hEMA14,0,0,1,ema14Arr)<=0 || CopyBuffer(hEMA200,0,0,1,ema200Arr)<=0) return; double ema14_now = ema14Arr[0]; double ema200_now = ema200Arr[0]; // 2) Read fractal history (skip current bar) if(CopyBuffer(hFractals,0,1,InpHistoryBars,fractalUp)<=0 || CopyBuffer(hFractals,1,1,InpHistoryBars,fractalDown)<=0) return; // 3) Find most recent valid fractals (ignore EMPTY_VALUE) int upShift=-1, downShift=-1; for(int i=1; i<InpHistoryBars; i++) { if(fractalUp[i] != EMPTY_VALUE && upShift<0) upShift = i+1; if(fractalDown[i] != EMPTY_VALUE && downShift<0) downShift = i+1; if(upShift>0 && downShift>0) break; } // 4) Levels double lvlUp = (upShift>0) ? fractalUp[upShift-1] : 0.0; double lvlDown = (downShift>0) ? fractalDown[downShift-1] : 0.0; // 5) Draw level lines DrawHLine("FB_LevelUp", lvlUp, InpBullColor); DrawHLine("FB_LevelDown", lvlDown, InpBearColor); // 6) DEBUG print double prevC = iClose(_Symbol,InpTimeframe,1); double currC = iClose(_Symbol,InpTimeframe,0); PrintFormat( "DBG lvlUp=%.5f lvlDown=%.5f prevC=%.5f currC=%.5f EMA14=%.5f EMA200=%.5f", lvlUp, lvlDown, prevC, currC, ema14_now, ema200_now ); // 7) Breakouts on the last closed candle (shift=1) // Bearish breakout if(lvlDown>0 && prevC>=lvlDown && currC<lvlDown && currC<ema14_now && currC<ema200_now && ema200_now>ema14_now) { Print(">>> Bear breakout triggered"); Signal(false, 1, lvlDown, ema14_now, ema200_now); } // Bullish breakout if(lvlUp>0 && prevC<=lvlUp && currC>lvlUp && currC>ema14_now && currC>ema200_now && ema14_now>ema200_now) { Print(">>> Bull breakout triggered"); Signal(true, 1, lvlUp, ema14_now, ema200_now); } } //+------------------------------------------------------------------+ //| Draw or update a dotted HLine | //+------------------------------------------------------------------+ void DrawHLine(string name, double price, color clr) { if(price<=0) return; if(ObjectFind(0,name)<0) { ObjectCreate(0,name,OBJ_HLINE,0,0,price); ObjectSetInteger(0,name,OBJPROP_COLOR,clr); ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DOT); ObjectSetInteger(0,name,OBJPROP_WIDTH,1); } else ObjectSetDouble(0,name,OBJPROP_PRICE,price); } //+------------------------------------------------------------------+ //| Plot arrow, label, log & alert | //+------------------------------------------------------------------+ void Signal(bool isBull, int shift, double level, double ema14, double ema200) { datetime t = iTime(_Symbol,InpTimeframe,shift); double price = level; string side = isBull ? "Bull" : "Bear"; // Arrow string arrowName = StringFormat("FB_%sArrow_%d", side, (int)t); ObjectCreate(0, arrowName, OBJ_ARROW, 0, t, price); ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, isBull?233:234); ObjectSetInteger(0, arrowName, OBJPROP_COLOR, isBull?InpBullColor:InpBearColor); ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, 2); ObjectSetInteger(0, arrowName, OBJPROP_FONTSIZE, InpArrowFontSize); // Label string lab = arrowName + "_L"; double offset = (isBull ? InpArrowOffset : -InpArrowOffset) * _Point; ObjectCreate(0, lab, OBJ_TEXT, 0, t, price + offset); ObjectSetString(0, lab, OBJPROP_TEXT, isBull?InpBullText:InpBearText); ObjectSetInteger(0, lab, OBJPROP_COLOR, isBull?InpBullColor:InpBearColor); ObjectSetInteger(0, lab, OBJPROP_FONTSIZE, 11); // Expert log string msg = StringFormat( "%s breakout at %s | Level=%.5f | Close=%.5f | EMA14=%.5f | EMA200=%.5f", side, TimeToString(t, TIME_DATE|TIME_SECONDS), level, iClose(_Symbol,InpTimeframe,shift), ema14, ema200 ); Print(msg); // Pop-up alert + optional sound if(InpAlertsEnabled) { Alert(msg); if(StringLen(InpAlertSoundFile)>0) PlaySound(InpAlertSoundFile); } } //+------------------------------------------------------------------+
Ergebnisse
Um den EA zu testen, kompilieren Sie zunächst den Code mit MetaEditor. Nach der Kompilierung können Sie ihn auf einem Chart in MetaTrader 5 laufen lassen, um ihn live zu testen, oder ihn direkt mit dem Strategy Tester für Backtest-Zwecke ausführen. Ich habe diesen EA sowohl unter Live-Marktbedingungen als auch in historischen Backtests getestet. Dieser Prozess ist wichtig für die Feinabstimmung der EA-Parameter, um das gewünschte Handelsverhalten zu erreichen und die Leistung zu optimieren.
Der Chart in der Abbildung unten zeigt, wie der EA eine signifikante Marktumkehr anhand von Fraktalen und EMA-Indikatoren erkennt. Konkret erkennt der EA einen Abwärtsausbruch des Fraktals an einem wichtigen Unterstützungsniveau, das auf dem Chart visuell markiert ist. Die anschließende Kursbewegung bestätigt die Umkehr, denn der Markt setzt seine Abwärtsbewegung fort und passt sich dabei dem EMA-Trend an, wobei der EMA 14 unter den EMA 200 kreuzt, was auf einen Abwärtstrend hinweist. Die visuellen Hinweise, wie z.B. der „BEAR Break“-Marker, unterstützen disziplinierte Ein- und Ausstiegsentscheidungen. Dieses Ergebnis veranschaulicht die Fähigkeit des EA, frühe Anzeichen einer Trendumkehr zu erkennen, was es Händlern ermöglicht, Chancen mit hoher Wahrscheinlichkeit zu nutzen und gleichzeitig falsche Signale zu vermeiden.
Abb. 3. Bear Break auf Step Index
Das folgende GIF zeigt die Echtzeit-Erkennung und Bestätigung einer Trendumkehr durch den EA. Sie zeigt, wie das Indikatorsystem eine fraktale Unterstützungs- oder Widerstandsstufe identifiziert und einen potenziellen Ausbruch signalisiert, der den Händler dazu veranlasst, eine Position in Betracht zu ziehen. Wenn sich der Markt in die vorhergesagte Richtung bewegt, werden die Signale des EA durch die Ausrichtung der EMAs bestätigt; der EMA 14 kreuzt unter dem EMA 200, was den Abwärtstrend bestätigt. Die visuellen Hinweise, wie z. B. Pfeile und Warnmeldungen, zeigen, wie der EA eine rechtzeitige Entscheidungsfindung erleichtert. Dieses Beispiel unterstreicht die Bedeutung einer frühzeitigen Erkennung in Verbindung mit einer Trendbestätigung, die das Vertrauen in den Handel stärkt und die Wahrscheinlichkeit von Fehleinstiegen verringert.
Abb. 4. Backtest auf V75 (1s)
Schlussfolgerung
Dieser Expert Advisor nutzt die Leistungsfähigkeit des Fraktal-Indikators von Bill Williams sowie kurz- und langfristige exponentielle gleitende Durchschnitte, um Einstiegspunkte mit hoher Wahrscheinlichkeit zu ermitteln. Durch die Kombination dieser Instrumente werden frühzeitige Umkehrsignale erfasst, die gegen den vorherrschenden Markttrend bestätigt werden, was die Präzision und Konsistenz der Handelsausführung verbessert. Rigorose Backtests und Live-Tests haben seine Flexibilität unter verschiedenen Marktbedingungen bewiesen, und bei einer Feinabstimmung können seine Parameter für eine optimale Performance angepasst werden. Mit intuitiven Pfeilen und Beschriftungen auf dem Chart sowie vollautomatischer Orderplatzierung bringt dieser EA Disziplin und Geschwindigkeit in Ihre Handelsroutine. Im Wesentlichen bietet es einen systematischen, regelbasierten Rahmen für die Preisaktionsanalyse, ideal für Händler, die technische Strenge mit Automatisierung verbinden möchten.
In der nachstehenden Tabelle finden Sie unsere vorgestellten Tools.
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/18297
Warnung: Alle Rechte sind von MetaQuotes Ltd. vorbehalten. Kopieren oder Vervielfältigen untersagt.
Dieser Artikel wurde von einem Nutzer der Website verfasst und gibt dessen persönliche Meinung wieder. MetaQuotes Ltd übernimmt keine Verantwortung für die Richtigkeit der dargestellten Informationen oder für Folgen, die sich aus der Anwendung der beschriebenen Lösungen, Strategien oder Empfehlungen ergeben.





- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Interessanter Artikel, und danke für den EA-Quellcode. Ich werde ihn ausprobieren und Feedback geben.