Entwicklung eines Toolkits zur Price-Action-Analyse (Teil 59): Einsatz geometrischer Asymmetrie zur Erkennung präziser Ausbrüche aus fraktalen Konsolidierungsphasen
Inhalt
- Einführung
- Strategieüberblick und Handelslogik
- MQL5-Implementierung und Codestruktur
- Tests und Ergebnisse
- Schlussfolgerung
Einführung
Echte Ausbruchschancen zählen zu den lukrativsten, aber auch am schwersten zu erkennenden Konstellationen im Price-Action-Trading. Märkte kommen oft mit überzeugendem Schwung aus einer Konsolidierungsphase heraus, um dann kurz darauf ins Stocken zu geraten oder eine Kehrtwende einzuleiten. In vielen Fällen sind diese Fehlschläge darauf zurückzuführen, dass dem Ausbruch eine ausreichende innere Kursstruktur oder anhaltender Richtungsdruck fehlt. Die eigentliche Herausforderung besteht daher nicht darin, Konsolidierungsspannen zu identifizieren, sondern darin, die Entstehung einer Richtungsneigung zu erkennen, noch bevor eine Begrenzung durchbrochen wird.
In Teil 58 wurde untersucht, wie sich interne Ungleichgewichte und Richtungstendenz im Kursverlauf vor einer Expansion entwickeln, wobei Ausbrüche als Ergebnis allmählicher struktureller Verschiebungen und nicht als isolierte oder zufällige Ereignisse betrachtet wurden. Auf dieser Grundlage stellt dieser Artikel das Geometric Asymmetry (GA) Breakout-Framework vor – eine systematische, regelbasierte Methodik zur Beurteilung, ob sich eine Konsolidierungsphase tatsächlich mit klarer Richtungsneigung auflöst. Der GA-Ansatz wertet das interne Kursverhalten anhand einer aus Fraktalen abgeleiteten Swing-Struktur und geometrischer Zusammenhänge aus, um die Vorbereitung auf eine tragfähige Trendentwicklung zu erkennen, bevor eine Grenze durchbrochen wird.
Durch die Fokussierung auf strukturelle Integrität, proportionale Ungleichgewichte und mehrschichtige Bestätigung zielt das Rahmenwerk darauf ab, Scheinexpansionen herauszufiltern und unter unterschiedlichen Marktbedingungen zuverlässigere Signale für Übergänge von der Range- in die Trendphase zu liefern.
Strategieüberblick und Handelslogik
Diese Strategie betrachtet die Erkennung von Ausbrüchen eher als ein strukturelles und geometrisches Problem denn als ein Volatilitätsereignis. Der Kurs wird als eine Abfolge von Schwankungen modelliert, die bestimmte Strukturen bilden, wobei Ungleichgewichte objektiv gemessen werden können, bevor es zu einer Ausweitung kommt. Die Breakout-Strategie auf Basis geometrischer Asymmetrie bewertet eine Konsolidierungsphase nicht nur anhand ihrer Grenzen, sondern auch anhand der proportionalen Beziehungen zwischen ihren internen Bewegungssegmenten. Eine Richtungstendenz wird aus messbaren Asymmetrien hinsichtlich Abstand, Steigung und Zeit abgeleitet, wodurch Ausbrüche anhand strukturbasierter Bestätigungen und nicht anhand reaktiver Signale antizipiert werden können.
Das Besondere an dieser Strategie ist ihr Fokus auf die interne Kursstruktur. Anstatt sich ausschließlich auf eine Zunahme der Volatilität oder das Durchbrechen von Handelsbereichen zu stützen, wird untersucht, wie sich der Kurs innerhalb der Konsolidierungsphase verhält, um festzustellen, welche Marktseite zunehmend die Kontrolle übernimmt.
Zugrunde liegende Marktmechanismen
Grundkonzept
Einer entscheidenden Kursausweitung geht häufig eine längere Konsolidierungsphase mit spezifischen geometrischen Merkmalen voraus. Wenn sich der Kurs in eine definierte Struktur einfügt – etwa in ein Rechteck oder eine sich verengende Formation – und die jüngste Kursschwankung unverhältnismäßig stark dominiert, deutet dies darauf hin, dass eine Seite des Marktes ihren Einfluss geltend macht. Dieses Ungleichgewicht gleicht sich in der Regel durch einen gerichteten Ausbruch aus.

Das obige Chart veranschaulicht eine Konsolidierungsphase, in der der Kurs innerhalb klar definierter Grenzen schwankt und so den strukturellen Kontext bildet, in dem sich vor einem Ausbruch ein internes Ungleichgewicht und eine Tendenz zur Kursrichtung entwickeln können.
Behandelte wichtige Marktentwicklungen
- Momentum-Akkumulation: Allmählicher Druckaufbau innerhalb festgelegter Kursgrenzen
- Volatilitätskompression: Geringere Swing-Breite der Kurse vor der Expansion
- Richtungsauflösung: Strukturelles Ungleichgewicht, das auf die wahrscheinlichste Ausbruchsrichtung hindeutet
Mehrschichtige Entscheidungslogik
Geometrische Asymmetrie (GA) beschreibt ein Ungleichgewicht im proportionalen Verlauf der Kursbewegung innerhalb einer Konsolidierungsspanne. Anstatt sich ausschließlich auf das Durchbrechen von Grenzen zu konzentrieren, bewertet GA die Kursentwicklung innerhalb der Konsolidierungsspanne, indem es die relative Länge, Steigung und Dauer aufeinanderfolgender Kursschwankungen vergleicht.
Wenn ein inneres Schwungsegment unverhältnismäßig stark dominiert, deutet dies auf einen ungleichmäßigen Richtungsdruck hin, der sich innerhalb der Konsolidierung unauffällig aufbaut. GA spiegelt daher einen gerichteten Bias vor dem Ausbruch wider, nicht die Bestätigung eines Trends, und wird erst bewertet, nachdem sich eine gültige Konsolidierungsspanne und eine objektive Schwungstruktur herausgebildet haben. Das folgende Chart veranschaulicht, wie der EA die Struktur innerhalb der Konsolidierungsspanne und geometrische Ungleichgewichte innerhalb eines qualifizierten Konsolidierungsbereichs bewertet, bevor er die Bestätigung eines Ausbruchs überwacht.

Swing-Punkte (HH, HL, LL) werden aus der fraktalen Erkennung nach Bill Williams abgeleitet und dienen als Eingabewerte für die geometrische Analyse. Eine ausführliche Erörterung der Fraktaltheorie und ihrer Umsetzung wurde bereits in einem früheren Artikel dieser Reihe erläutert und wird hier nicht wiederholt.
- Phase 1: Strukturelle Grundlagen (Fraktales Rahmenwerk)
Werden drei aufeinanderfolgende, sich abwechselnde Fraktale identifiziert, gilt die Struktur als gültig. Ist diese Bedingung nicht erfüllt, ignoriert das System die Sequenz und setzt die Überwachung auf neue fraktale Formationen fort.
In dieser Phase wird die strukturelle Grundlage der Strategie festgelegt. Durch die Vorgabe abwechselnder Wendepunkte (hoch–tief–hoch oder tief–hoch–tief) filtert das System kleinere Schwankungen heraus und identifiziert so aussagekräftige Trendumkehrungen. Dadurch wird sichergestellt, dass die nachfolgende Analyse auf aussagekräftigen Kursverläufen und nicht auf kurzfristigen Schwankungen basiert.
- Phase 2: Bereichsqualifizierung (Konsolidierungsvalidierung)
Diese Phase bestätigt, dass es sich bei der festgestellten Struktur um eine echte Konsolidierung und nicht um eine zufällige Verdichtung handelt. Die ATR-basierte Normalisierung ermöglicht es der Strategie, sich an wechselnde Volatilitätsbedingungen anzupassen und gleichzeitig einheitliche Standards durchzusetzen. Strukturen, die zu breit, oder zu kurz sind, oder vom Kurs nicht mehr berücksichtigt werden, werden ausgeschlossen.
- Phase 3: Geometrische Analyse (Erkennung der Richtungstendenz)
In dieser Phase wird der entscheidende Vorteil der Strategie vorgestellt: die Erkennung einer trendseitigen Dominanz, noch bevor der Ausbruch stattfindet.
Entfernungsbewertung:
Bewertung der Steigung:
Übersteigt die Steigung des letzten Schwungabschnitts die des vorherigen Abschnitts um das festgelegte Steigungsverhältnis, trägt dies mit einer Stimme zur Richtungstendenz bei.
Bewertung der Zeitkompression:
Wenn die letzte Schwungphase innerhalb des festgelegten Zeitkompressionsschwellenwerts in kürzerer Zeit abgeschlossen wird als die vorangegangene Phase, trägt sie mit einer Stimme zur Richtungstendenz bei.
Bestätigungsregel:
Durch die Verwendung mehrerer proportionaler Messgrößen wird vermieden, dass man sich auf einen einzelnen Faktor verlässt. Eine Richtungsneigung gilt erst dann als bestätigt, wenn mehrere unabhängige Merkmale übereinstimmen.
- Phase 4: Mustersperre (Bestätigung des Setups)
Sobald die geometrischen Bedingungen erfüllt sind, wechselt die Struktur in einen gesperrten Überwachungszustand.
Sperrkriterien
- Bestätigte Richtungstendenz
- Der letzte Schwung endet nahe der betreffenden Grenze
- Die Swing-Magnitude bleibt proportional zum Schwingungsbereich
- Keine widersprüchlichen aktiven Setups
Eigenschaften des gesperrten Musters
- Richtung: Bullisch bei Aufwärtsdominanz, bärisch bei Abwärtsdominanz
- Referenzwerte: Feste Konsolidierungsspanne (Höchst- und Tiefstwert)
- Überwachungsfenster: Begrenzt durch InpMaxLockBars
- Status: Wird aktiv beobachtet, um einen Ausbruch zu bestätigen
Durch die Sperrung der Struktur wird ein erneutes Zeichnen verhindert und die analytische Integrität gewahrt.
- Phase 5: Breakout-Erkennung (Signalerzeugung)

Das EA gibt erst dann ein KAUF-Signal aus, wenn eine gültige GA-Konsolidierungsspanne festgelegt wurde, die interne geometrische Asymmetrie die bullische Tendenz bestätigt und der Kurs über dem Höchstwert der GA-Konsolidierungsspanne schließt. Ein VERKAUF-Signal folgt derselben Logik und wird generiert, wenn der Kurs nach einer bestätigten bärischen internen Tendenz unterhalb des Tiefstwerts der GA-Spanne schließt.
Ausführungslogik
- Bullisches Setup
Ein KAUF-Signal wird generiert, wenn der Kurs deutlich über dem festgelegten Höchstwert der Konsolidierungsspanne schließt, angepasst um den Ausbruchspuffer.
- Bärisches Setup
Ein VERKAUF-Signal wird generiert, wenn der Kurs deutlich unterhalb des festgelegten Tiefstwerts der Konsolidierungsspanne schließt, angepasst um den Ausbruchspuffer.
Der Breakout-Puffer (InpBreakBufferPts) filtert geringfügige Grenzverletzungen bzw. kurze Überschreitungen heraus und ermöglicht gleichzeitig eine rechtzeitige Teilnahme an echten Expansionsbewegungen. Signale werden erst beim Schließen der Bar generiert, was die Konsistenz erhöht und Fehlauslösungen reduziert.
Risikokontrolle und Signaldisziplin
Selektivität ist ein zentrales Gestaltungsprinzip. Die Strategie vermeidet erzwungene Handelsgeschäfte, indem sie eine Übereinstimmung zwischen Struktur, Volatilität und Geometrie voraussetzt. Ein Mindestabstand zwischen den Signalen verhindert wiederholte Auslösungen im selben Bereich, insbesondere bei unruhigen Bedingungen. Dies fördert die Geduld und lenkt die Aufmerksamkeit auf vielversprechendere Chancen.
Kontextbezogene Interpretation
Signale dienen der Bestätigung, nicht der Vorhersage. Sie lassen sich am besten bewerten, wenn man sie im Zusammenhang mit einem breiteren Kontext betrachtet, wie beispielsweise der Struktur höherer Zeitrahmen, der Dynamik der Handelssitzung oder wichtiger Referenzniveaus. Das System dient als Rahmen zur Entscheidungsunterstützung, wobei die Ausführung und das Risikomanagement fest in der Hand des Traders bleiben.
Anpassungsfähigkeit über verschiedene Märkte und Zeiträume hinweg
Da die Logik auf proportionalen Beziehungen und nicht auf festen Werten basiert, lässt sich die Strategie gut auf verschiedene Instrumente und Zeiträume anpassen. Durch anpassbare Parameter lässt sich die Methode verfeinern, ohne die zugrunde liegende Methodik zu verändern. Dieses Gleichgewicht zwischen Beständigkeit und Flexibilität gewährleistet Beständigkeit unter unterschiedlichen Marktbedingungen. Indem jedes Signal anhand der Konsolidierungsqualität und des Richtungsungleichgewichts verankert wird, bietet die Strategie des Geometric Asymmetry Breakout einen disziplinierten Rahmen für die Identifizierung von Übergängen vom Gleichgewicht zur Expansion mit hoher Wahrscheinlichkeit.
In ihrer Gesamtheit ermöglichen diese Komponenten der Strategie, die Bedingungen für Kursausbrüche von der strukturellen Ursache bis hin zur Richtungswirkung zu bewerten.

MQL5-Implementierung und Codestruktur
Dieser Abschnitt bietet einen umfassenden Überblick darüber, wie die Strategie Geometric Asymmetry Breakout in MQL5 umgesetzt wird. Der Code basiert auf einer modularen Architektur, bei der Klarheit, Leistungseffizienz und umfangreiche Anpassungsmöglichkeiten im Vordergrund stehen. Jede Komponente deckt einen bestimmten Aspekt des Systems ab, wodurch ein gut strukturiertes Framework entsteht, das sich leicht navigieren, Fehler beheben und erweitern lässt. Das Design ermöglicht eine kontinuierliche Weiterentwicklung und Anpassung und eignet sich daher für Trader mit unterschiedlichen Handelsstilen und Vorlieben.
Architektonischer Überblick
Im Mittelpunkt dieser Umsetzung steht ein modularer Aufbau, bei dem verschiedene funktionale Aufgabenbereiche in eigenständige Segmente unterteilt werden. Diese Trennung gewährleistet, dass jedes Modul separat entwickelt, getestet und gewartet werden kann, was die Robustheit des Gesamtsystems erhöht. Zu den wichtigsten Modulen gehören die Fraktalerkennung, die Konsolidierungsbewertung, die Asymmetrieprüfung, die Einstiegssignale und das Mustermanagement. Eine derart klare Aufgabenteilung macht den Code übersichtlicher, insbesondere wenn das System als Reaktion auf sich verändernde Marktbedingungen optimiert oder erweitert wird.
Die Grundlage des Systems bilden vom Benutzer konfigurierbare Eingaben, die für die Flexibilität von entscheidender Bedeutung sind. Anhand dieser Parameter können Trader die Strategie an bestimmte Vermögenswerte, Zeitrahmen und individuelle Risikobereitschaft anpassen. Beispielsweise begrenzt InpMaxScanBars die Anzahl der ausgewerteten historischen Bars und optimiert so die Rechengeschwindigkeit. Andere Parameter, wie beispielsweise InpRangeATRMax und InpRangeATRMaxSoft, filtern potenzielle Zonen anhand ihrer Größe heraus, sodass nur signifikante Konsolidierungen berücksichtigt werden. Die Parameter zur Asymmetrieprüfung – InpLenRatioMin für den Abstand zur Kante, InpSlopeRatioMin für die Steilheit der Bewegung und InpTimeCompressionMax für die Geschwindigkeit der Bewegung – sind für das Erkennen eines echten Momentumaufbaus von entscheidender Bedeutung.
//====================== INPUTS ===================================== input int InpMaxScanBars = 900; input int InpATRPeriod = 14; input double InpRangeATRMax = 2.00; input int InpRangeMinBarsHard = 8; input bool InpEnableSoftRangeBars = true; input int InpRangeMinBarsSoft = 4; input double InpRangeATRMaxSoft = 1.60; input int InpRangeTestLookback = 50; input double InpRangeSideZonePct = 0.35; input double InpLenRatioMin = 1.35; input double InpSlopeRatioMin = 1.15; input double InpTimeCompressionMax = 0.95; input int InpMinGeometryVotes = 2; input double InpMaxLegVsRange = 1.50; input int InpMaxLegBars = 50; input double InpLegEndNearBoundaryPct = 0.50; input int InpBreakLookbackBars = 150; input double InpBreakBufferPts = 5.0; input int InpMaxLockBars = 30; input int InpArrowOffsetPoints = 15; input int InpArrowLabelOffset = 30; input int InpMinBarsBetweenSignals = 5; input bool InpShowSwings = true; input bool InpShowLegs = true; input bool InpShowTriangle = true; input bool InpShowLabels = true; input bool InpShowRangeLines = true; input bool InpShowCandidateRangeRect = true; input bool InpShowLockedRangeRects = true; input bool InpShowArrows = true; input bool InpShowDebug = true; // Arrow code and style input int InpArrowUpCode = 233; input int InpArrowDownCode = 234; input int InpArrowSize = 3; input color InpArrowColorUp = clrLime; input color InpArrowColorDown = clrRed; input bool InpShowArrowLabels = true; input int InpArrowLabelFontSize = 9; input string InpArrowLabelFont = "Arial"; // Alert settings input bool InpEnableAlerts = true; input bool InpAlertOnPatternLock = true; input bool InpAlertOnBreakout = true; input string InpAlertSoundPattern = "alert.wav"; input string InpAlertSoundBreakout = "alert2.wav"; input bool InpAlertPopup = true; input bool InpAlertNotification = true; input bool InpAlertEmail = false;
Zu den weiteren Optionen gehören Eröffnungspuffer (InpBreakBufferPts) zur Vermeidung von Fehlauslösungen durch geringfügige Kursschwankungen, maximale Sperrdauern (InpMaxLockBars) zur Vermeidung mehrerer Auslösungen bei ein und demselben Muster sowie eine Mindestanzahl von Bars zwischen den Signalen (InpMinBarsBetweenSignals) zur Vermeidung von übermäßigem Handel. Mithilfe von visuellen Schaltflächen zur Anzeige von Schwankungen, Beinen, Dreiecken, Konsolidierungsspanneen, Beschriftungen und Pfeilen können Trader die visuelle Darstellung der Signale individuell anpassen. Benachrichtigungsmodi können so konfiguriert werden, dass sie Töne, Popups, Push-Benachrichtigungen und E-Mails umfassen, sodass Trader unabhängig von ihrer Umgebung stets auf dem Laufenden bleiben.
Mustererkennung: Wendepunkte erkennen
Der Prozess beginnt mit der zuverlässigen Erkennung von Swing-Extremen, die die Grundlage für potenzielle Zonen bilden. Die Funktionen IsFractalHigh() und IsFractalLow() setzen die strenge Fünf-Bars-Regel von Bill Williams um: Ein Hoch (bzw. Tief) gilt nur dann als solches, wenn es die Höchststände (bzw. Tiefststände) der beiden benachbarten Bars übertrifft (bzw. unterschreitet). Dieser Filter filtert unbedeutende Schwankungen heraus und konzentriert sich ausschließlich auf strukturelle Umkehrungen mit Marktbedeutung. Durch die strikte Einhaltung dieser Regel vermeidet das System Fehlsignale, die durch Marktgeräusche verursacht werden.
// Check if the bar at index i is a fractal high based on Bill Williams' five-bar rule bool IsFractalHigh(int i) { if(i<3 || i+2>=BarsTotal()) return false; double h = iHigh(_Symbol, _Period, i); return h > iHigh(_Symbol, _Period, i-1) && h > iHigh(_Symbol, _Period, i+1) && h > iHigh(_Symbol, _Period, i-2) && h > iHigh(_Symbol, _Period, i+2); } // Check if the bar at index i is a fractal low bool IsFractalLow(int i) { if(i<3 || i+2>=BarsTotal()) return false; double l = iLow(_Symbol, _Period, i); return l < iLow(_Symbol, _Period, i-1) && l < iLow(_Symbol, _Period, i+1) && l < iLow(_Symbol, _Period, i-2) && l < iLow(_Symbol, _Period, i+2); }
Darauf aufbauend durchsucht die Funktion GetLast3AlternatingFractals() die aktuellen Daten effizient nach der neuesten Folge von drei gegenläufigen Fraktalen. Es konzentriert sich vorrangig auf die auffälligsten Abweichungen – also jene, die sich am stärksten von den umgebenden Bars unterscheiden –, um die Extremwerte dynamisch zu verfeinern. Dieser Prozess schafft eine verlässliche Grundlage für die anschließende Analyse und stellt sicher, dass die identifizierten Zonen auf aussagekräftigen Marktschwankungen beruhen und nicht auf geringfügigen Schwankungen.
// Retrieve the most recent sequence of three opposing fractals for pattern detection bool GetLast3AlternatingFractals( int &p0, double &pr0, bool &h0, int &p1, double &pr1, bool &h1, int &p2, double &pr2, bool &h2) { int n=0, idx[3]; double pr[3]; bool hi[3]; int maxBars = MathMin(InpMaxScanBars, BarsTotal() - 3); for(int i=3; i<maxBars; i++) { double price; bool isH; if(!GetFractalPoint(i, price, isH)) { // Additional check for prominent fractals if(i >= 4 && i+3 < BarsTotal()) { double hh = iHigh(_Symbol, _Period, i); double ll = iLow(_Symbol, _Period, i); if(hh >= iHigh(_Symbol, _Period, i-1) && hh >= iHigh(_Symbol, _Period, i+1) && hh >= iHigh(_Symbol, _Period, i-2) && hh >= iHigh(_Symbol, _Period, i+2)) { price = hh; isH = true; } else if(ll <= iLow(_Symbol, _Period, i-1) && ll <= iLow(_Symbol, _Period, i+1) && ll <= iLow(_Symbol, _Period, i-2) && ll <= iLow(_Symbol, _Period, i+2)) { price = ll; isH = false; } else continue; } else continue; } // Store the most recent opposing fractals if(n==0) { idx[0]=i; pr[0]=price; hi[0]=isH; n=1; } else if(hi[n-1]==isH) { // Update if current fractal is more extreme if(isH && price>pr[n-1]) { idx[n-1]=i; pr[n-1]=price; } if(!isH && price<pr[n-1]) { idx[n-1]=i; pr[n-1]=price; } } else if(n<3) { idx[n]=i; pr[n]=price; hi[n]=isH; n++; } if(n>=3) break; } if(n<3) return false; p0=idx[0]; pr0=pr[0]; h0=hi[0]; p1=idx[1]; pr1=pr[1]; h1=hi[1]; p2=idx[2]; pr2=pr[2]; h2=hi[2]; return true; }
Festlegung der Konsolidierungsgrenzen
Sobald die wichtigsten Fraktale identifiziert sind, analysieren die Funktionen CalcRangeHigh() und CalcRangeLow() die Bars zwischen diesen, um die tatsächlichen Ober- und Untergrenzen der potenziellen Konsolidierungszone zu ermitteln. Diese Grenzen sind entscheidend für die Bestimmung des Bereichs, in dem ein Ausbruch stattfinden könnte.
// Calculate the highest high between two bars double CalcRangeHigh(int leftBar, int rightBar) { int from = MathMin(leftBar, rightBar); int to = MathMax(leftBar, rightBar); int bars = to - from + 1; int idx = iHighest(_Symbol, _Period, MODE_HIGH, bars, from); return (idx >= 0) ? iHigh(_Symbol, _Period, idx) : iHigh(_Symbol, _Period, from); } // Calculate the lowest low between two bars double CalcRangeLow(int leftBar, int rightBar) { int from = MathMin(leftBar, rightBar); int to = MathMax(leftBar, rightBar); int bars = to - from + 1; int idx = iLowest(_Symbol, _Period, MODE_LOW, bars, from); return (idx >= 0) ? iLow(_Symbol, _Period, idx) : iLow(_Symbol, _Period, from); }
Rohdaten-Grenzen müssen jedoch validiert werden. Die Funktion RangeQualifies() wendet strenge Kriterien an: Die Zone muss eine Mindestdauer aufweisen (sowohl harte als auch weiche Schwellenwerte), ihre Höhe muss proportional zum ATR sein, und zur Validierung sind aktuelle Kursberührungen an den Rändern erforderlich. Zonen, die zu flach, zu kurzlebig oder vernachlässigt sind, werden verworfen. Durch diese Filterung wird der Fokus auf Marktumfelder mit echtem Ausbruchspotenzial geschärft, wodurch die Wahrscheinlichkeit von Fehlauslösungen aufgrund geringfügiger Marktschwankungen oder unbedeutender Konsolidierungen verringert wird.
// Check if the range qualifies based on duration, ATR, and proximity bool RangeQualifies(int p2, int p1, double hi, double lo, string &whyFail, bool &usedSoft) { whyFail=""; usedSoft=false; int barsSpan = MathAbs(p2 - p1); if(barsSpan < InpRangeMinBarsSoft) { whyFail="rangeBars"; return false; } double atr; if(!GetATR(atr)) { whyFail="atr"; return false; } double height = MathAbs(hi - lo); double atrCap = InpRangeATRMax; if(barsSpan < InpRangeMinBarsHard) { if(!InpEnableSoftRangeBars) { whyFail="rangeBars"; return false; } usedSoft=true; atrCap = InpRangeATRMaxSoft; } if(height > atr * atrCap) { whyFail= usedSoft ? "rangeATR_soft" : "rangeATR"; return false; } // Check proximity to recent high/low double zonePct = MathMax(0.08, MathMin(InpRangeSideZonePct, 0.70)); double zone = height * zonePct; bool nearHigh=false, nearLow=false; int look = MathMin(InpRangeTestLookback, BarsTotal() - 5); for(int i=1; i<=look; i++) { double h = iHigh(_Symbol, _Period, i); double l = iLow(_Symbol, _Period, i); if(h >= hi - zone) nearHigh=true; if(l <= lo + zone) nearLow=true; if(nearHigh || nearLow) break; } if(!nearHigh && !nearLow) { whyFail="sideZones"; return false; } return true; }
Erkennung eines Ungleichgewichts im Momentum: Geometrische Validierung
Zonen, die die ersten Filter passieren, werden einer geometrischen Validierung unterzogen. Die Funktion GeometryAsymmetryInsideRangeOK() führt eine detaillierte Analyse der jüngsten Kursbewegungen innerhalb der Zone durch. Es berechnet Kennzahlen wie LengthRatio für die Entfernungsdominanz, SlopeRatio für die Steilheit und TimeRatio für die Bewegungsgeschwindigkeit. Anhand dieser Kennzahlen lässt sich feststellen, ob die letzte Kursbewegung stark beschleunigt wurde – ein wichtiges Anzeichen für einen Momentaufbau.
// Validate the shape and acceleration of the move within the zone bool GeometryAsymmetryInsideRangeOK( int p0,double pr0,int p1,double pr1,int p2,double pr2, double rangeHigh,double rangeLow, double &lenRatio,double &slopeRatio,double &timeRatio,int &votes,int &dir, string &whyFail) { whyFail=""; votes=0; double lenPrev = MathAbs(pr1 - pr2); double lenLast = MathAbs(pr0 - pr1); dir = (pr0 > pr1 ? +1 : -1); double tol = (rangeHigh - rangeLow) * 0.10; if(pr0 > rangeHigh+tol || pr0 < rangeLow-tol || pr1 > rangeHigh+tol || pr1 < rangeLow-tol) { if(pr0 > rangeHigh+tol && pr1 > rangeHigh+tol) { whyFail="notInsideRange"; return false; } if(pr0 < rangeLow-tol && pr1 < rangeLow-tol) { whyFail="notInsideRange"; return false; } } datetime t0 = iTime(_Symbol, _Period, p0); datetime t1 = iTime(_Symbol, _Period, p1); datetime t2 = iTime(_Symbol, _Period, p2); long dtPrevL = (long)t1 - (long)t2; long dtLastL = (long)t0 - (long)t1; double dtPrev = MathAbs((double)dtPrevL); double dtLast = MathAbs((double)dtLastL); if(dtPrev <= 0 || dtLast <= 0) { whyFail="dt"; return false; } lenRatio = lenLast / MathMax(1e-10, lenPrev); slopeRatio = (lenLast / dtLast) / MathMax(1e-10, (lenPrev / dtPrev)); timeRatio = dtLast / MathMax(1e-10, dtPrev); // Voting on pattern strength if(lenRatio >= InpLenRatioMin) votes++; if(slopeRatio >= InpSlopeRatioMin) votes++; if(timeRatio <= InpTimeCompressionMax) votes++; if(votes < InpMinGeometryVotes) { if(lenRatio >= InpLenRatioMin * 1.2 || slopeRatio >= InpSlopeRatioMin * 1.2) votes = InpMinGeometryVotes; else { whyFail="votes"; return false; } } return true; }
Ein Abstimmungssystem namens InpMinGeometryVotes erfordert, dass mehrere Kriterien erfüllt sind, bevor das Muster bestätigt wird. Es werden zusätzliche Sicherheitsvorkehrungen wie die Endpunktnähe und die proportionale Skalierung zwischen den Abschnitten eingesetzt, um übermäßige oder isolierte Bewegungen auszuschließen, die keine echte Dynamikentwicklung widerspiegeln. Diese sorgfältige Prüfung unterscheidet aussagekräftigen Momentumaufbau von bloß symmetrischen oder unentschlossenen Bewegungen, die oft zu falschen Ausbrüchen führen. Dadurch wird die Zuverlässigkeit der erzeugten Signale deutlich erhöht.
Überwachung von Ausbrüchen und Einstiegssignalen
// Check recent candles for breakouts and trigger signals void CheckAllBreakouts() { double buffer = InpBreakBufferPts * _Point; for(int i=0; i<ArraySize(g_lockedPatterns); i++) { if(!g_lockedPatterns[i].active) continue; for(int bar=1; bar<=InpBreakLookbackBars; bar++) { datetime barTime = iTime(_Symbol, _Period, bar); if(barTime <= g_lockedPatterns[i].startTime) continue; double close = iClose(_Symbol, _Period, bar); double high = iHigh(_Symbol, _Period, bar); double low = iLow(_Symbol, _Period, bar); if(g_lockedPatterns[i].dir > 0) { if(close > g_lockedPatterns[i].high + buffer || high > g_lockedPatterns[i].high + buffer) { double breakoutPrice = MathMax(g_lockedPatterns[i].high + buffer, MathMin(close, high)); string uid = "BUY_" + g_lockedPatterns[i].key + "_" + Ts(barTime); CreatePermanentArrow(uid, barTime, breakoutPrice, true); if(InpShowDebug) Print("Buy breakout at ", DoubleToString(breakoutPrice,_Digits)); RemoveLockedPattern(i); g_lastSignalBar = barTime; break; } } else if(g_lockedPatterns[i].dir < 0) { if(close < g_lockedPatterns[i].low - buffer || low < g_lockedPatterns[i].low - buffer) { double breakoutPrice = MathMin(g_lockedPatterns[i].low - buffer, MathMax(close, low)); string uid = "SELL_" + g_lockedPatterns[i].key + "_" + Ts(barTime); CreatePermanentArrow(uid, barTime, breakoutPrice, false); if(InpShowDebug) Print("Sell breakout at ", DoubleToString(breakoutPrice,_Digits)); RemoveLockedPattern(i); g_lastSignalBar = barTime; break; } } } } }
Wenn ein Muster eine starke Asymmetrie aufweist, wechselt das System in die Ausbruchsüberwachung. Die Funktion CheckAllBreakouts() durchsucht die jüngsten Bars sorgfältig nach entscheidenden Durchbrüchen der festgelegten Grenzen der Konsolidierungsspanne und nutzt dabei einen Einstiegspuffer (InpBreakBufferPts), um Reaktionen auf geringfügige Ausschläge zu verhindern. Wenn ein bestätigter Ausbruch eintritt, platziert CreatePermanentArrow() dauerhafte visuelle Markierungen – Pfeile, Zonen, Beschriftungen – auf dem Chart und liefert so eine klare visuelle Bestätigung.
// Create an arrow marker on the chart for breakouts void CreatePermanentArrow(const string uid, const datetime t, const double price, const bool bullish) { if(!InpShowArrows) return; string name = PFX_AR + "PERM_" + uid + "_" + Ts(t); if(ObjectFind(0, name) >=0) return; // Already exists int anchor = bullish ? ANCHOR_BOTTOM : ANCHOR_TOP; double arrowPrice = bullish ? (price - InpArrowOffsetPoints * _Point) : (price + InpArrowOffsetPoints * _Point); if(!ObjectCreate(0, name, OBJ_ARROW, 0, t, arrowPrice)) { if(InpShowDebug) Print("Failed to create arrow: ", GetLastError()); return; } ObjectSetInteger(0, name, OBJPROP_ARROWCODE, bullish ? InpArrowUpCode : InpArrowDownCode); ObjectSetInteger(0, name, OBJPROP_COLOR, bullish ? InpArrowColorUp : InpArrowColorDown); ObjectSetInteger(0, name, OBJPROP_WIDTH, InpArrowSize); ObjectSetInteger(0, name, OBJPROP_ANCHOR, anchor); // Add label if enabled if(InpShowArrowLabels) { string lbl = name + "_LBL"; double lblPrice = arrowPrice + (InpArrowLabelOffset * _Point * (bullish ? 1 : -1)); if(ObjectCreate(0, lbl, OBJ_TEXT, 0, t, lblPrice)) { ObjectSetString(0, lbl, OBJPROP_TEXT, bullish ? "BUY" : "SELL"); ObjectSetInteger(0, lbl, OBJPROP_COLOR, bullish ? InpArrowColorUp : InpArrowColorDown); ObjectSetInteger(0, lbl, OBJPROP_FONTSIZE, InpArrowLabelFontSize); ObjectSetString(0, lbl, OBJPROP_FONT, InpArrowLabelFont); ObjectSetInteger(0, lbl, OBJPROP_ANCHOR, ANCHOR_LEFT_UPPER); } } }
Gleichzeitig verwaltet PlayAlert() Benachrichtigungen über verschiedene Kanäle, darunter Töne, Popups, Push-Benachrichtigungen und E-Mails, und stellt so sicher, dass Trader unabhängig von ihrem Gerät oder ihrer Umgebung umgehend über Breakouts mit hoher Zuverlässigkeit informiert werden. Jedes Setup wird für einen kurzen Zeitraum (InpMaxLockBars) gesperrt, um Mehrfachsignale für dasselbe Muster zu verhindern, und Muster werden automatisch deaktiviert, sobald sie abgelaufen sind oder ein Ausbruch eintritt. Dieser Prozess sorgt für einen übersichtlichen Arbeitsbereich und hebt aktuelle Signale mit hoher Wahrscheinlichkeit hervor.
Verwaltung des Musterlebenszyklus und Rauschunterdrückung
// Check if enough bars have passed since last signal to avoid overtrading bool CooldownOK() { if(g_lastSignalBar == 0) return true; int barsSince = iBarShift(_Symbol, _Period, g_lastSignalBar, true); return (barsSince >= InpMinBarsBetweenSignals); }
Um Fehlauslösungen und übermäßigen Handel weiter zu verhindern, wendet das System Mechanismen zur Rauschunterdrückung an. Die Funktion CooldownOK() stellt sicher, dass zwischen den Signalen eine Mindestanzahl von Bars verstreicht, wodurch die Auswirkungen von Marktturbulenzen gemindert werden. Die Routine UpdateLockedPatterns() verlängert die Timer für aktive Muster und lässt diejenigen automatisch ablaufen, die ihre maximale Laufzeit erreicht haben oder bereits erfüllt wurden.
// Update active pattern timers and expire patterns that have reached max lock bars void UpdateLockedPatterns() { datetime currentTime = iTime(_Symbol, _Period, 0); for(int i=0; i<ArraySize(g_lockedPatterns); i++) { if(!g_lockedPatterns[i].active) continue; g_lockedPatterns[i].lockBars++; // optionally, update visual rectangle for active patterns if(g_lockedPatterns[i].rectName != "" && InpShowLockedRangeRects) UpdateLockedRangeRectangle(g_lockedPatterns[i].rectName, currentTime, g_lockedPatterns[i].high, g_lockedPatterns[i].low); // Expire patterns that have reached max lock bars if(g_lockedPatterns[i].lockBars > InpMaxLockBars) { if(InpShowDebug) Print("Pattern expired after ", g_lockedPatterns[i].lockBars, " bars"); RemoveLockedPattern(i); } } }
Diese Kontrollmechanismen sorgen für ein diszipliniertes Handelsumfeld, verringern die Häufigkeit von Fehlalarmen und stellen sicher, dass Signale nur dann generiert werden, wenn die Marktstruktur auf eine echte Chance hindeutet. Dieser disziplinierte Ansatz hilft Tradern dabei, nicht auf geringfügige Marktschwankungen oder unruhige Marktbedingungen zu reagieren, sondern sich stattdessen auf Setups mit hoher Erfolgswahrscheinlichkeit zu konzentrieren.
Kernausführung: OnTick()
Alle Analysen, Entscheidungsfindungen und Signalisierungen werden innerhalb der Funktion OnTick() koordiniert. Es wird erst beim Ende jeder neuen Bar ausgelöst, was die Ressourcennutzung optimiert und für Stabilität sorgt. Innerhalb von OnTick() aktualisiert die Routine nacheinander die bestehenden Musterzustände, sucht nach neuen Fraktalen, bewertet potenzielle Zonen, führt eine geometrische Validierung durch, überwacht Ausbrüche und aktualisiert visuelle Überlagerungen.
// Main routine called on each new tick; runs at bar close void OnTick() { // Only proceed at bar close datetime closed = iTime(_Symbol, _Period, 1); if(closed == 0 || closed == g_lastClosedBar) return; g_lastClosedBar = closed; // Update pattern timers and expire old patterns UpdateLockedPatterns(); // Check for breakout signals CheckAllBreakouts(); // Limit number of active patterns if(GetActivePatternCount() >= g_maxSimultaneousLocks) { if(InpShowDebug) Print("Max active patterns reached"); return; } // Enforce cooldown to prevent overtrading if(!CooldownOK()) { if(InpShowDebug) { int sinceBars = iBarShift(_Symbol, _Period, g_lastSignalBar, true); Print("Cooldown active: ", sinceBars, "/", InpMinBarsBetweenSignals, " bars since last signal"); } return; } // Proceed with fractal detection and pattern analysis // (Insert fractal detection, range evaluation, geometric validation, etc.) // ... }
Diese strukturierte Pipeline gewährleistet einen zuverlässigen Echtzeitbetrieb auch bei volatilen oder sich schnell verändernden Märkten. Visuelle Überlagerungen – wie beispielsweise farbige Punkte zur Markierung von Fraktalen, Trendlinien zur Veranschaulichung von Kursbewegungen, Zonen zur Hervorhebung von Konsolidierungsphasen und Pfeile zur Anzeige von Ausbrüchen – werden auf der Grundlage aktueller Marktdaten dynamisch erstellt oder aktualisiert. Dieses visuelle Feedback vermittelt Tradern ein unmittelbares, intuitives Verständnis der Marktstruktur und potenzieller Handelssignale.
Ressourcenverwaltung und Systemstabilität
Ein effektives Ressourcenmanagement ist für die langfristige Systemstabilität von entscheidender Bedeutung. Während der Ausführung von OnInit() wird das Handle des ATR-Indikators abgerufen und zur Wiederverwendung zwischengespeichert. Während der Ausführung von OnDeinit() wird es freigegeben, um Speicherlecks zu vermeiden. Grafische Objekte wie Trendlinien, Bereiche und Pfeile werden systematisch mit einheitlichen Präfixen und eindeutigen Kennungen benannt, was Aktualisierungen und Löschvorgänge vereinfacht.
// On initialization, acquire indicator handles and prepare environment int OnInit() { g_atrHandle = iATR(_Symbol, _Period, InpATRPeriod); if(g_atrHandle == INVALID_HANDLE) { Print("Failed to create ATR handle. Error=", GetLastError()); return INIT_FAILED; } // Resize pattern lock array for simultaneous patterns ArrayResize(g_lockedPatterns, g_maxSimultaneousLocks); for(int i=0; i< g_maxSimultaneousLocks; i++) g_lockedPatterns[i].active = false; // Clean up previous graphical objects DeleteByPrefix(PFX_SW); DeleteByPrefix(PFX_DOT); DeleteByPrefix(PFX_LN); DeleteByPrefix(PFX_TX); DeleteByPrefix(PFX_TRI); ObjectDelete(0, OBJ_CAND); // Initialize variables g_lastClosedBar = 0; g_lastSignalBar = 0; g_arrowCounter = 0; // Print startup info Print("System initialized successfully"); return INIT_SUCCEEDED; }
Arrays, die mehrere Muster unterstützen, werden dynamisch in ihrer Größe angepasst, sodass das System komplexe Szenarien mit überlappenden Setups oder mehreren Instrumenten ohne Leistungseinbußen bewältigen kann. Sorgfältige Bereinigungsroutinen und ein disziplinierter Umgang mit dem Arbeitsspeicher gewährleisten, dass das System über längere Zeiträume hinweg, bei unterschiedlichen Symbolen und unter wechselnden Marktbedingungen stabil bleibt.
// On deinitialization, release indicator handles and clean up objects void OnDeinit(const int reason) { if(g_atrHandle != INVALID_HANDLE) IndicatorRelease(g_atrHandle); // Remove graphical objects DeleteByPrefix(PFX_SW); DeleteByPrefix(PFX_DOT); DeleteByPrefix(PFX_LN); DeleteByPrefix(PFX_TX); DeleteByPrefix(PFX_TRI); ObjectDelete(0, OBJ_CAND); // Output stats Print("Deinitialization complete"); Print("Total patterns processed: ", g_totalPatterns); Print("Breakouts: ", g_totalBreakouts, " (Buy: ", g_buyBreakouts, ", Sell: ", g_sellBreakouts, ")"); Print("Patterns expired: ", g_patternsExpired); }
Schlussbemerkungen
Diese Implementierung ist ein Beispiel für professionelle Programmierung in MQL5. Durch die Kombination von fraktaler Erkennung, strenger Zonenfilterung und detaillierter geometrischer Validierung wandelt das System subtile Ungleichgewichte in äußerst zuverlässige, umsetzbare Signale um. Visuelle Überlagerungen, Benachrichtigungen und die Verwaltung des Musterlebenszyklus schaffen eine umfassende Handelsumgebung, die Leistungsstärke und Übersichtlichkeit in Einklang bringt.
Die modulare Architektur lässt sich individuell anpassen; Trader können Schwellenwerte verfeinern, Filter hinzufügen oder die visuelle Darstellung nach Bedarf optimieren. Diese Flexibilität gewährleistet, dass das System auch weiterhin an sich wandelnde Märkte und individuelle Handelsstile angepasst werden kann. Die Geometric Asymmetry Breakout-Strategie ist somit ein skalierbares, beständiges Rahmenkonzept, das darauf ausgelegt ist, Trader bei der Orientierung in komplexen, dynamischen Märkten zu unterstützen.
Tests und Ergebnisse
Damit ein Instrument effektiv ist und durchweg positive Ergebnisse liefert, sind gründliche Tests unter verschiedenen Marktbedingungen und über unterschiedliche Zeiträume hinweg unerlässlich. In diesem Abschnitt stelle ich die Ergebnisse der von mir durchgeführten Tests vor und gehe auf die Bedingungen ein, unter denen das Tool am effektivsten funktionierte. Nach umfangreichen Tests mit verschiedenen Währungspaaren zeichnete sich ein klares Leistungsmuster ab. Das Tool erwies sich bei den wichtigsten, hochliquiden Währungspaaren als am effektivsten, wobei die stärksten und beständigsten Ergebnisse beim EURUSD im H1-Zeitrahmen zu verzeichnen waren.
Nachfolgend finden Sie ein Chart aus dem Strategy Tester, das einen Testlauf für EURUSD (H1) zeigt und verdeutlicht, wo das Tool seine besten und praktisch relevantesten Ergebnisse zeigte.
Das bedeutet jedoch nicht, dass das Tool nur unter diesen spezifischen Bedingungen funktioniert. Die beobachtete Leistung wird stark von den Schwellenwerten der Eingangsparameter und den während der Tests angewendeten Signalfiltern beeinflusst. Verschiedene Instrumente weisen unterschiedliche Eigenschaften auf – einige sind volatiler, andere weniger, während wieder andere eine höhere Liquidität bieten. Aus diesem Grund spielte die Parameterkalibrierung während der Tests eine entscheidende Rolle. Die Eingabewerte wurden so angepasst, dass sie das Verhalten jedes Paares und jedes Zeitraums widerspiegelten, anstatt einheitlich angewendet zu werden. In Abstimmung mit der Volatilität, der Liquidität und den strukturellen Tendenzen eines Marktes zeigte das Tool über mehrere Instrumente hinweg eine beständige Wirksamkeit, nicht nur beim EURUSD auf der H1-Zeitebene.
Ein weiterer Test wurde am AUDUSD-Paar durchgeführt, der ebenfalls positive und konsistente Ergebnisse lieferte. Dieser Test wurde mit dem Strategy Tester im visuellen Modus durchgeführt, wodurch genau beobachtet werden konnte, wie der EA Konsolidierungsbereiche identifizierte, eine interne Tendenz entwickelte und Ausbruchsignale in Echtzeit generierte.

Wie in der Visualisierung zu sehen ist, hat der EA den GA-Konsolidierungsspanne korrekt erkannt, die interne geometrische Asymmetrie bestätigt und erst dann ein gültiges Signal ausgegeben, nachdem der Kurs außerhalb der Grenze des festgelegten Konsolidierungsspannes geschlossen hatte. Dieser Test bestätigt erneut, dass das Tool über ein einzelnes Instrument hinaus zuverlässig funktioniert, vorausgesetzt, die Eingabeparameter und Filter sind ordnungsgemäß auf die Volatilität und Struktur des Marktes abgestimmt.
Schlussfolgerung
In diesem Artikel wurde das Geometric Asymmetry (GA) Breakout-Konzept als strukturierter, regelbasierter Ansatz zur Erkennung aussagekräftiger Übergänge von Konsolidierungsspannen zu Trends untersucht. Durch die Kombination von fraktalbasierter Strukturerkennung, Konsolidierungsbewertung, Analyse geometrischer Ungleichgewichte und strenger Ausbruchsbestätigung konzentriert sich die Methode eher auf den Marktkontext und die Bestätigung als auf die Vorhersage.
Tests mit verschiedenen Währungspaaren und Zeitrahmen haben gezeigt, dass die Performance weitgehend davon abhängt, wie gut die Eingabeparameter auf die Volatilität, Liquidität und das strukturelle Verhalten des jeweiligen Marktes abgestimmt sind. Die bei wichtigen Währungspaaren wie EURUSD (H1) und AUDUSD beobachteten Ergebnisse belegen die Fähigkeit des Frameworks, echte Expansionsphasen zu erfassen und gleichzeitig Signale zu vermeiden, die durch Rauschen oder kurzlebige Kursschwankungen verursacht werden. Die Stärke des GA-Ansatzes liegt in seiner Disziplin. Signale werden erst dann generiert, wenn sich eine gültige Konsolidierungsspanne herausgebildet hat, eine interne Tendenz anhand der Asymmetrie objektiv festgestellt wurde und der Kurs deutlich außerhalb der festgelegten Grenze schließt. Diese sequenzielle Filterung reduziert falsche Ausbrüche und stellt sicher, dass die Signale die tatsächliche Richtungsentwicklung widerspiegeln.
Geometric Asymmetry ist als Rahmenwerk zur Entscheidungsunterstützung und Signalerzeugung konzipiert und stellt kein vollautomatisches Handelssystem dar. Dank seines modularen Aufbaus können Nutzer Schwellenwerte verfeinern, Filter anpassen und Parameter an verschiedene Instrumente anpassen, ohne die Kernlogik zu verändern. Diese Flexibilität macht das GA-Framework zu einem praktischen und robusten Instrument für Trader, die nach einer strukturierten und transparenten Methode zur Breakout-Analyse unter sich ändernden Marktbedingungen suchen.
Die Strategie der geometrischen Asymmetrie sollte, wie jedes analytische Instrument, nicht ohne gründliche Tests im Live-Handel angewendet werden. Den Nutzern wird empfohlen, umfangreiche Tests auf Demokonten durchzuführen, die Parameter an die von ihnen gewählten Finanzinstrumente und Zeitrahmen anzupassen und stets ein angemessenes Risikomanagement anzuwenden. Die Wertentwicklung in der Vergangenheit, einschließlich der Backtest-Ergebnisse, ist keine Garantie für zukünftige Ergebnisse.
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/21197
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.
Die Übertragung der Trading-Signale in einem universalen Expert Advisor.
Der MQL5-Standardbibliotheks-Explorer (Teil 7): Interaktive Positionskennzeichnung mit CCanvas
Eine alternative Log-datei mit der Verwendung der HTML und CSS
MQL5-Handelswerkzeuge (Teil 18): Abgerundete Sprechblasen mit Orientierungssteuerung
- 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.