
Entwicklung eines Toolkit zur Analyse von Preisaktionen (Teil 19): ZigZag Analyzer
Einführung
Trendlinien bilden das Rückgrat der technischen Analyse und der modernen Kursentwicklung. Sie bilden das Gerüst der Kursmuster, auf die sich Devisen-, Kryptowährungs-, Rohstoff-, Aktien- und Derivatehändler verlassen. Richtig gezeichnet, zeigen Trendlinien effizient Markttrends auf und helfen Händlern, potenzielle Chancen zu erkennen.
Unabhängig davon, ob Sie ein Daytrader oder ein kurzfristiger Händler sind, Trendlinien spielen in vielen Handelssystemen und -strategien eine wichtige Rolle. In unserer Entwicklungsserie des Price Action Analysis Toolkit stellen wir ein Tool namens ZigZag Analyzer vor. Dieses Tool konzentriert sich auf das Zeichnen von Trendlinien unter Verwendung des ZigZag-Indikators, um Umkehrpunkte zu identifizieren, die die Grundlage für die Konstruktion von Trendlinien bilden. MQL5 ist eine leistungsstarke Sprache für die Automatisierung von Handelssystemen und ermöglicht es uns, fortschrittliche Tools wie den ZigZag Analyzer zu entwickeln, die sich den Marktbedingungen anpassen und die Entscheidungsfindung in Echtzeit unterstützen.
Wir beginnen mit der Erforschung von Trendlinien, untersuchen dann den Zigzag-Indikator, skizzieren den Systemalgorithmus, stellen den MQL5-Code vor, überprüfen die Ergebnisse und schließen mit unseren abschließenden Erkenntnissen. Nachstehend finden Sie das Inhaltsverzeichnis:
Trendlinien
Eine Trendlinie ist eine schräg verlaufende Linie, die wichtige Kurspunkte, in der Regel höhere Tiefst- oder niedrigere Höchststände, miteinander verbindet und in die Zukunft als Unterstützungs- oder Widerstandsniveau projiziert. Er zeigt die wahrscheinliche Richtung und Dynamik der Kursbewegungen an. Um eine Trendlinie zu zeichnen, müssen Sie zunächst die allgemeine Marktrichtung bestimmen. Ein Aufwärtstrend ist durch eine Abfolge von höheren Hochs und höheren Tiefs gekennzeichnet, während ein Abwärtstrend durch niedrigere Hochs und niedrigere Tiefs gekennzeichnet ist. Zur Veranschaulichung betrachten Sie ein Chart, das ein Abwärtsmuster zeigt, bei dem Sie die fallenden hohen Umkehrpunkte verbinden würden, um die Trendlinie festzulegen. Während der Preiskonsolidierung kann die Bildung mehrerer Trendlinien Muster aufzeigen, die Handelssignale verstärken. Nachstehend finden Sie eine bildliche Darstellung.
Abb. 1. Trendlinien
Das Chart veranschaulicht zwei Schlüsselkonzepte: Unterstützung und Widerstand. Ein Unterstützungsniveau ist ein Bereich, in dem die Abwärtsbewegung häufig zum Stillstand kommt, weil die Käufer aktiv genug werden, um den Verkaufsdruck aufzufangen. Bei der Anwendung von Trendlinien wird die Unterstützung in der Regel durch aufwärts gerichtete Linien angezeigt, die wichtige Tiefpunkte verbinden. Im Gegensatz dazu ist ein Widerstandsniveau ein Bereich, in dem die Aufwärtsbewegung aufgrund eines verstärkten Verkaufsdrucks häufig pausiert. Bei Trendlinien wird der Widerstand durch abwärts gerichtete Linien dargestellt, die wichtige Hochpunkte miteinander verbinden. Händler zeichnen häufig Trendlinien über mehrere Zeithorizonte hinweg, um festzustellen, ob sich ein Markt über kurze, mittlere oder lange Zeiträume aufwärts oder abwärts bewegt.Trendlinien sind ein wertvolles Instrument der technischen Analyse, da sie den Marktteilnehmern helfen, die Gesamtrichtung des Preises eines Vermögenswerts abzuschätzen. Durch die Verbindung signifikanter Höchst- oder Tiefststände in einem ausgewählten Zeitrahmen stellen diese Linien visuell dar, ob sich der Markt aufwärts, abwärts oder seitwärts bewegt. Diese Erkenntnis ist besonders nützlich für Händler und kurzfristige Anleger, die sich bei ihren Entscheidungen auf Preistrends verlassen.
Zickzack-Indikator
Der genaue Ursprung des Zig-Zag-Indikators ist zwar nicht eindeutig belegt, aber einige Quellen schreiben seine Entdeckung Bill Wolfe zu, einem S&P 500-Händler, der für die Entwicklung der Wolfe-Wellen bekannt ist, einer Methode, die den Elliott-Wellen ähnelt, aber über andere Charttechniken verfügt. Die Wolfe-Wellen bestehen aus fünf Wellen, die veranschaulichen, wie sich Angebot und Nachfrage auf einen Gleichgewichtspreis zubewegen. Der Zig Zag-Indikator hebt signifikante Kursumkehrungen hervor, die einen bestimmten Schwellenwert überschreiten, der in der Regel als Prozentsatz ausgedrückt wird. Wenn der Kurs diese Schwelle überschreitet, setzt der Indikator einen neuen Punkt und zieht eine gerade Linie vom vorherigen Punkt aus, wodurch kleinere Schwankungen herausgefiltert werden. Auf diese Weise lassen sich die zugrunde liegenden Trends über verschiedene Zeiträume hinweg leichter erkennen.
Händler können den prozentualen Schwellenwert (z. B. 4 % oder 5 %) anpassen, um mehr oder weniger Kursschwankungen zu erfassen, je nach Volatilität des Vermögenswerts oder ihrem persönlichen Handelsstil. Diese Flexibilität trägt dazu bei, dass der Zig-Zag-Indikator potenzielle Wendepunkte besser erkennen kann. In der wellenbasierten Analyse, wie z. B. der Elliot-Wellentheorie, kann das Zig Zag helfen, die Struktur jeder Welle zu verdeutlichen. Letztendlich ist es oft notwendig, mit verschiedenen Einstellungen zu experimentieren, um das optimale Gleichgewicht zwischen dem Herausfiltern von Rauschen und dem Erkennen aussagekräftiger Kursbewegungen zu finden.
Abb. 2. Zick-Zack-Indikator
Abbildung 2 oben zeigt ein Chart mit dem Zig Zag-Indikator. Sie zeigt, wie aus den Umkehrpunkten Trendlinien konstruiert werden können. Der Zig-Zag-Indikator vereinfacht die Trendanalyse, indem er kleinere Kursschwankungen herausfiltert und wichtige Wendepunkte hervorhebt. Er markiert signifikante Höchst- und Tiefststände, die als Ankerpunkte für die Zeichnung von Trendlinien dienen. In einem Aufwärtstrend bildet die Verbindung dieser Schwungtiefs eine Unterstützungslinie, während in einem Abwärtstrend die Verbindung der hohen Umkehrpunkte eine Widerstandslinie bildet. Diese Methode hebt die Gesamtrichtung des Marktes hervor, indem sie das Rauschen eliminiert. Durch die Anpassung der Sensitivität des Indikators kann die Genauigkeit dieser Trendlinien weiter verfeinert werden, um bessere Handelseinblicke zu erhalten.
System-Algorithmus
1. Globale Deklarationen und Eingabeparameter
In diesem ersten Abschnitt richten wir Schlüsseleingaben und globale Variablen ein, mit denen Sie den Analyzer anpassen können, ohne in den Code einzugreifen. Wir definieren Parameter wie den Chart-Zeitrahmen und spezifische Eigenschaften für den ZigZag-Indikator wie Tiefe, Abweichung und Rückschritt. Diese Einstellungen legen fest, wie der Analysator Umkehrpunkte auswählt. Wir deklarieren auch Arrays, um die ZigZag-Daten zu speichern und um die Zeit und den Preis der wichtigsten Pivots aufzuzeichnen.
Wir schätzen diese Einrichtung wegen ihrer Einfachheit und ihres modularen Aufbaus. So können Sie beispielsweise durch Ändern des Zeitrahmenparameters problemlos zwischen kurzfristigen und langfristigen Trends wechseln. Mit den ZigZag-Eigenschaften können Sie die Empfindlichkeit des Indikators einstellen, sodass Sie die Analyse an unterschiedliche Marktbedingungen oder Vermögenswerte anpassen können. Wir verwenden globale Variablen und Arrays als zentralen Knotenpunkt für alle dynamischen Daten. Dieser Ansatz verbessert die Leistung und macht den Code einfacher zu pflegen. Wenn neue Daten eintreffen, werden sie effizient gespeichert und stehen für die Analyse bereit, was die Anpassung und Fehlersuche erheblich vereinfacht.
Insgesamt schaffen wir durch die Zentralisierung dieser kritischen Eingaben und Erklärungen ein flexibles und klares Werkzeug, das es Ihnen ermöglicht, den Analysator an Ihre Bedürfnisse anzupassen, während die zugrunde liegenden Prozesse robust und zuverlässig bleiben.
// Input parameters input ENUM_TIMEFRAMES InpTimeFrame = PERIOD_CURRENT; // Timeframe to analyze input int ZZ_Depth = 12; // ZigZag depth input int ZZ_Deviation = 5; // ZigZag deviation input int ZZ_Backstep = 3; // ZigZag backstep input int LookBackBars = 200; // Bars to search for pivots input int ExtendFutureBars = 100; // Bars to extend trendlines into the future // Global indicator handle for ZigZag int zzHandle; // Arrays for ZigZag data and pivot storage double zzBuffer[]; datetime pivotTimes[]; double pivotPrices[]; bool pivotIsPeak[]; // Variable to detect new bars datetime lastBarTime = 0;
- InpTimeFrame: Der Zeitrahmen für die Analyse.
- ZZ_Depth, ZZ_Deviation, ZZ_Backstep: Parameter, die die Empfindlichkeit und das Verhalten des ZigZag-Indikators beeinflussen.
Arrays wie zzBuffer speichern die Ausgabe des ZigZag-Indikators. Zusätzliche Arrays (pivotTimes, pivotPrices, pivotIsPeak) sind für die Speicherung von Details zu jedem erkannten Pivot reserviert. Eine Variable (lastBarTime) hilft bei der Feststellung, ob ein neuer Balken begonnen hat, und stellt sicher, dass die Analyse nur bei Bedarf aktualisiert wird.
2. Die Initialisierungsfunktion (OnInit)
In der Initialisierungsfunktion führen wir den Code einmal aus, wenn der Indikator geladen wird. Unser Hauptziel ist es hier, den ZigZag-Indikator anhand der Nutzereingaben zu erstellen und zu konfigurieren. Wir rufen die Funktion iCustom auf, um zu versuchen, den ZigZag-Indikator zu instanziieren und sein Handle zu speichern. Wenn die Initialisierung des Indikators fehlschlägt und ein ungültiges Handle zurückgegeben wird, protokollieren wir einen Fehler und halten die weitere Verarbeitung an.
Wir verwenden diese Funktion, um sicherzustellen, dass alles korrekt eingerichtet ist, bevor eine Analyse stattfindet. Sie fungiert als Torwächter und verhindert, dass der restliche Code ausgeführt wird, wenn es ein Problem mit dem Indikator-Setup gibt. Diese frühzeitige Prüfung spart Zeit und vermeidet unnötige Fehler im weiteren Verlauf der Ausführung. Indem wir die Initialisierung hier zentralisieren, erleichtern wir die Verwaltung und Fehlersuche im System, falls etwas schief geht. Die Funktion stellt außerdem sicher, dass alle nutzerdefinierten Einstellungen von Anfang an angewendet werden, was eine solide Grundlage für die nachfolgende Analyse darstellt.
int OnInit() { zzHandle = iCustom(_Symbol, InpTimeFrame, "ZigZag", ZZ_Depth, ZZ_Deviation, ZZ_Backstep); if(zzHandle == INVALID_HANDLE) { Print("Error creating ZigZag handle"); return(INIT_FAILED); } return(INIT_SUCCEEDED); }
- Erstellung von Indikatoren: Verwendet wird iCustom, um den ZigZag-Indikator mit bestimmten Parametern zu laden.
- Fehlerbehandlung: Prüft, ob das zurückgegebene Handle gültig ist. Protokolliert eine Fehlermeldung und bricht ab, wenn die Initialisierung fehlschlägt.
3. Die Deinitialisierungsfunktion (OnDeinit)
Wenn der Indikator entfernt oder die Plattform geschlossen wird, ist es wichtig, alle Objekte zu bereinigen und die zugewiesenen Ressourcen freizugeben. Die Funktion OnDeinit sorgt dafür, dass alle grafischen Objekte (wie Trendlinien oder horizontale Linien), die auf dem Chart gezeichnet wurden, gelöscht werden und der Handle des ZigZag-Indikators freigegeben wird. Auf diese Weise wird sichergestellt, dass keine unerwünschten Elemente auf der Chart verbleiben und dass die Ressourcen des Systems ordnungsgemäß verwaltet werden.
Ressourcenbereinigung: Löscht alle erstellten Chartobjekte, um Unordnung zu vermeiden.Freigabe des Handles: Gibt das Handle des Indikators ZigZag mit IndicatorRelease frei.
void OnDeinit(const int reason) { ObjectDelete(0, "Downtrend_HighLine"); ObjectDelete(0, "Uptrend_LowLine"); ObjectDelete(0, "Major_Resistance"); ObjectDelete(0, "Major_Support"); ObjectDelete(0, "Minor_Resistance"); ObjectDelete(0, "Minor_Support"); IndicatorRelease(zzHandle); }
4. Die Hauptausführungsfunktion (OnTick)
Dies ist das Herzstück des Algorithmus, der bei jedem neuen Tick abläuft. Die Funktion prüft zunächst, ob sich ein neuer Balken gebildet hat, indem sie den Zeitstempel des aktuellen Balkens mit der zuletzt gespeicherten Zeit vergleicht. Wird kein neuer Balken erkannt, wird die Funktion vorzeitig beendet, um Rechenleistung zu sparen. Sobald ein neuer Balken bestätigt wird, werden alte Chartobjekte entfernt, die neuesten ZigZag-Daten mit CopyBuffer abgerufen und dann zwei Hilfsfunktionen aufgerufen: eine zum Zeichnen von Trendlinien und eine weitere zum Zeichnen von Unterstützungs- und Widerstandsniveaus.
void OnTick() { datetime currentBarTime = iTime(_Symbol, InpTimeFrame, 0); if(currentBarTime == lastBarTime) return; lastBarTime = currentBarTime; // Remove previous objects ObjectDelete(0, "Downtrend_HighLine"); ObjectDelete(0, "Uptrend_LowLine"); ObjectDelete(0, "Major_Resistance"); ObjectDelete(0, "Major_Support"); ObjectDelete(0, "Minor_Resistance"); ObjectDelete(0, "Minor_Support"); if(CopyBuffer(zzHandle, 0, 0, LookBackBars, zzBuffer) <= 0) { Print("Failed to copy ZigZag data"); return; } ArraySetAsSeries(zzBuffer, true); DrawZigZagTrendlines(); DrawSupportResistance(); }
- Neuer Bar-Check: Verwendet iTime, um eine Änderung des Balkens zu erkennen.
- Puffer-Update: Aktualisiert zzBuffer mit den neuesten Daten des ZigZag.
- Chart-Updates: Löscht frühere grafische Objekte, um neue Objekte vorzubereiten. Ruft Funktionen zum Zeichnen von Trendlinien und Unterstützungs-/Widerstandslinien auf.
5. Zeichnen von ZigZag-basierten Trendlinien (DrawZigZagTrendlines)
Diese Funktion ist dafür verantwortlich, die signifikanten Umkehrpunkte aus den ZigZag-Daten zu identifizieren und sie zur Berechnung von Trendlinien zu verwenden. Er durchläuft den Puffer, um Hochs und Tiefs zu sammeln, je nachdem, ob der aktuelle ZigZag-Wert mit dem Hoch oder Tief des Balkens übereinstimmt. Sobald die Umkehrpunkte gesammelt sind, verwendet der Code eine lineare Regression, um die Trendlinie für jeden Satz von Punkten zu bestimmen. Bei der Regressionsberechnung werden die folgenden Formeln verwendet:
1. Steigung (m)
Abb. 3. Regressionsformel
2. Achsenabschnitt (b)
Abb. 4. Achsenabschnitt
- (t) steht für die Zeitwerte (oder die unabhängige Variable).
- (p) steht für die Preiswerte (oder die abhängige Variable).
- (N) ist die Anzahl der in der Regression verwendeten Datenpunkte.
Extraktion der Umkehrpunkte: Durchläuft in einer Schleife zzBuffer, um bis zu 10 Höchst- und Tiefstwerte zu erfassen.
Ausschluss des letzten Umkehrpunktes: Verwirft den letzten Umkehrpunkt, um das Rauschen zu reduzieren.
Regressionsanalyse: Berechnet die Steigung (m) und den Achsenabschnitt (b) anhand der obigen Formeln.
void DrawZigZagTrendlines() { double highPrices[10], lowPrices[10]; datetime highTimes[10], lowTimes[10]; int highCount = 0, lowCount = 0; // Extract swing points from the ZigZag buffer for(int i = 0; i < LookBackBars - 1; i++) { if(zzBuffer[i] != 0) { if(iHigh(_Symbol, InpTimeFrame, i) == zzBuffer[i] && highCount < 10) { highPrices[highCount] = zzBuffer[i]; highTimes[highCount] = iTime(_Symbol, InpTimeFrame, i); highCount++; } else if(iLow(_Symbol, InpTimeFrame, i) == zzBuffer[i] && lowCount < 10) { lowPrices[lowCount] = zzBuffer[i]; lowTimes[lowCount] = iTime(_Symbol, InpTimeFrame, i); lowCount++; } } } // Exclude the most recent swing if possible int usedHighCount = (highCount >= 4) ? highCount - 1 : highCount; int usedLowCount = (lowCount >= 4) ? lowCount - 1 : lowCount; double mHigh = 0, bHigh = 0, mLow = 0, bLow = 0; bool validHigh = false, validLow = false; // Regression for highs if(usedHighCount >= 3) { double sumT = 0, sumP = 0, sumTP = 0, sumT2 = 0; for(int i = 0; i < usedHighCount; i++) { double t = (double)highTimes[i]; double p = highPrices[i]; sumT += t; sumP += p; sumTP += t * p; sumT2 += t * t; } int N = usedHighCount; double denominator = N * sumT2 - sumT * sumT; if(denominator != 0) { mHigh = (N * sumTP - sumT * sumP) / denominator; bHigh = (sumP - mHigh * sumT) / N; } else bHigh = sumP / N; validHigh = true; } // Regression for lows if(usedLowCount >= 3) { double sumT = 0, sumP = 0, sumTP = 0, sumT2 = 0; for(int i = 0; i < usedLowCount; i++) { double t = (double)lowTimes[i]; double p = lowPrices[i]; sumT += t; sumP += p; sumTP += t * p; sumT2 += t * t; } int N = usedLowCount; double denominator = N * sumT2 - sumT * sumT; if(denominator != 0) { mLow = (N * sumTP - sumT * sumP) / denominator; bLow = (sumP - mLow * sumT) / N; } else bLow = sumP / N; validLow = true; } // Define time limits for trendlines datetime pastTime = iTime(_Symbol, InpTimeFrame, LookBackBars - 1); datetime futureTime = lastBarTime + ExtendFutureBars * PeriodSeconds(); // Draw trendlines if both regressions are valid if(validHigh && validLow) { // When slopes have the same sign, use average slope for parallel lines if(mHigh * mLow > 0) { double mParallel = (mHigh + mLow) / 2.0; double bHighParallel = highPrices[0] - mParallel * (double)highTimes[0]; double bLowParallel = lowPrices[0] - mParallel * (double)lowTimes[0]; datetime highStartTime = pastTime; double highStartPrice = mParallel * (double)highStartTime + bHighParallel; double highEndPrice = mParallel * (double)futureTime + bHighParallel; if(!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice)) Print("Failed to create High Trendline"); else { ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed); ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true); ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true); } datetime lowStartTime = pastTime; double lowStartPrice = mParallel * (double)lowStartTime + bLowParallel; double lowEndPrice = mParallel * (double)futureTime + bLowParallel; if(!ObjectCreate(0, "Uptrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice)) Print("Failed to create Low Trendline"); else { ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_COLOR, clrGreen); ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_RAY_LEFT, true); ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_RAY_RIGHT, true); } } else // Draw separate trendlines if slopes differ { datetime highStartTime = pastTime; double highStartPrice = mHigh * (double)highStartTime + bHigh; double highEndPrice = mHigh * (double)futureTime + bHigh; if(!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice)) Print("Failed to create High Trendline"); else { ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed); ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true); ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true); } datetime lowStartTime = pastTime; double lowStartPrice = mLow * (double)lowStartTime + bLow; double lowEndPrice = mLow * (double)futureTime + bLow; if(!ObjectCreate(0, "Uptrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice)) Print("Failed to create Low Trendline"); else { ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_COLOR, clrGreen); ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_RAY_LEFT, true); ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_RAY_RIGHT, true); } } } else { // Draw only available regression if only one set of points is valid if(validHigh) { datetime highStartTime = pastTime; double highStartPrice = mHigh * (double)highStartTime + bHigh; double highEndPrice = mHigh * (double)futureTime + bHigh; if(!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice)) Print("Failed to create High Trendline"); else { ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed); ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true); ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true); } } if(validLow) { datetime lowStartTime = pastTime; double lowStartPrice = mLow * (double)lowStartTime + bLow; double lowEndPrice = mLow * (double)futureTime + bLow; if(!ObjectCreate(0, "Uptrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice)) Print("Failed to create Low Trendline"); else { ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_COLOR, clrGreen); ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_RAY_LEFT, true); ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_RAY_RIGHT, true); } } } }
Trendlinien-Zeichnung (wenn beide Trends gültig sind)
Gleiches Vorzeichen der Steigung: Es wird eine gemittelte Steigung für parallele Linien verwendet. Verschiedene Zeichen: Zeichnen der einzelnen Trendlinien. Verwendet wird ObjectCreate und ObjectSetInteger um die Linien zu platzieren und zu gestalten.
6. Zeichnen von Unterstützungs- und Widerstandsniveaus (DrawSupportResistance)
Der Unterstützungs- und Widerstandsteil des Codes dient der dynamischen Identifizierung wichtiger horizontaler Kursniveaus auf der Grundlage der vom ZigZag-Indikator gelieferten bestätigten Umkehrpunkte. Der Algorithmus bestimmt nicht nur das höchste bestätigte Hoch als Hauptwiderstand und das niedrigste bestätigte Tief als Hauptunterstützung, sondern geht noch weiter, indem er signifikante Hochs und Tiefs herausfiltert, um sowohl Haupt- als auch Nebenwerte zu bestimmen. Dieser Prozess ist von entscheidender Bedeutung, da Unterstützung und Widerstand grundlegende Konzepte in der technischen Analyse sind; Unterstützung stellt ein Niveau dar, bei dem der Preis aufgrund einer erhöhten Nachfrage dazu neigt, nicht weiter zu fallen, während Widerstand ein Niveau angibt, bei dem der Preis aufgrund des Angebotsdrucks typischerweise Schwierigkeiten hat, sich nach oben zu bewegen.
Bei dieser Implementierung untersucht der Code alle bestätigten Umkehrpunkte, sortiert und vergleicht sie sorgfältig, um die extremsten Werte zu isolieren. Dadurch wird sichergestellt, dass die auf dem Chart eingezeichneten Niveaus nicht nur vorübergehende Schwankungen sind, sondern aussagekräftige Zonen darstellen, die in der Vergangenheit Preisumkehrungen beeinflusst haben. Indem der Algorithmus den zweithöchsten und zweitniedrigsten Wert als geringfügigen Widerstand und Unterstützung identifiziert, bietet er zusätzliche Einblicke. Diese kleineren Niveaus können als frühe Signale oder sekundäre Ziele dienen und Händlern eine nuancierte Sicht auf mögliche Kursreaktionen bieten, bevor sie die kritischeren Hauptniveaus erreichen.
Dieser Ansatz ist in einem sich ständig wandelnden Markt von großem Nutzen. Sobald neue Kursdaten eintreffen, nimmt der ZigZag-Indikator neue Umkehrpunkte auf und aktualisiert automatisch die Unterstützungs- und Widerstandsniveaus, um die aktuelle Marktstruktur widerzuspiegeln. Diese Echtzeitanpassung ist für Händler von entscheidender Bedeutung, da sie ihnen hilft, sich an sich verändernde Preisbarrieren anzupassen, die ihre Ein- oder Ausstiegsentscheidungen beeinflussen könnten. Diese Ebenen werden auf dem Chart als horizontale Linien in unterschiedlichen Farben dargestellt, sodass sie auf einen Blick zu erkennen sind. Diese zusätzliche Klarheit ermöglicht es Händlern, schnell zu erkennen, in welchen Schlüsselbereichen der Preis reagieren könnte, und hilft ihnen, Stop-Loss-Aufträge zu platzieren oder Profit Targets mit mehr Vertrauen festzulegen. Letztendlich berechnet dieser Teil des Codes nicht nur Unterstützung und Widerstand, sondern wandelt die rohen Marktdaten in klare, umsetzbare Erkenntnisse um, was ihn zu einem unverzichtbaren Werkzeug für jeden Händler macht, der Charttechnik verwendet.
void DrawSupportResistance() { double confirmedHighs[10], confirmedLows[10]; int confHighCount = 0, confLowCount = 0; for(int i = 0; i < LookBackBars - 1; i++) { if(zzBuffer[i] != 0) { if(iHigh(_Symbol, InpTimeFrame, i) == zzBuffer[i] && confHighCount < 10) { confirmedHighs[confHighCount] = zzBuffer[i]; confHighCount++; } else if(iLow(_Symbol, InpTimeFrame, i) == zzBuffer[i] && confLowCount < 10) { confirmedLows[confLowCount] = zzBuffer[i]; confLowCount++; } } } int usedHighCount = (confHighCount >= 4) ? confHighCount - 1 : confHighCount; int usedLowCount = (confLowCount >= 4) ? confLowCount - 1 : confLowCount; double majorResistance = -1e9, majorSupport = 1e9; double minorResistance = -1e9, minorSupport = 1e9; double tempHigh = -1e9, tempLow = -1e9; for(int i = 0; i < usedHighCount; i++) { if(confirmedHighs[i] > majorResistance) { tempHigh = majorResistance; majorResistance = confirmedHighs[i]; } else if(confirmedHighs[i] > tempHigh) { tempHigh = confirmedHighs[i]; } } if(tempHigh > -1e9) minorResistance = tempHigh; for(int i = 0; i < usedLowCount; i++) { if(confirmedLows[i] < majorSupport) { tempLow = majorSupport; majorSupport = confirmedLows[i]; } else if(confirmedLows[i] < tempLow) { tempLow = confirmedLows[i]; } } if(tempLow < 1e9) minorSupport = tempLow; if(usedHighCount > 0) { if(!ObjectCreate(0, "Major_Resistance", OBJ_HLINE, 0, 0, majorResistance)) Print("Failed to create Major Resistance"); else ObjectSetInteger(0, "Major_Resistance", OBJPROP_COLOR, clrMagenta); if(minorResistance > -1e9 && minorResistance < majorResistance) { if(!ObjectCreate(0, "Minor_Resistance", OBJ_HLINE, 0, 0, minorResistance)) Print("Failed to create Minor Resistance"); else ObjectSetInteger(0, "Minor_Resistance", OBJPROP_COLOR, clrFuchsia); } } if(usedLowCount > 0) { if(!ObjectCreate(0, "Major_Support", OBJ_HLINE, 0, 0, majorSupport)) Print("Failed to create Major Support"); else ObjectSetInteger(0, "Major_Support", OBJPROP_COLOR, clrAqua); if(minorSupport < 1e9 && minorSupport > majorSupport) { if(!ObjectCreate(0, "Minor_Support", OBJ_HLINE, 0, 0, minorSupport)) Print("Failed to create Minor Support"); else ObjectSetInteger(0, "Minor_Support", OBJPROP_COLOR, clrBlue); } } }
Die Datenerfassung iteriert durch den Puffer, um bestätigte Höchst- und Tiefstwerte zu extrahieren. Die Niveaubestimmung verwendet Vergleiche, um die Extremwerte zu isolieren. Große Widerstände/Unterstützungen werden als die extremsten Werte festgelegt, während die nächstgrößeren Werte zu kleinen Werten werden. Die grafische Darstellung erzeugt horizontale Linien (OBJ_HLINE) für jede identifizierte Ebene. Zur leichteren Unterscheidung sind die einzelnen Zeilen farbig hinterlegt.
MQL5 Code
//+------------------------------------------------------------------+ //| ZigZag Analyzer.mq5| //| 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 // Input parameters input ENUM_TIMEFRAMES InpTimeFrame = PERIOD_CURRENT; // Timeframe to analyze input int ZZ_Depth = 12; // ZigZag depth input int ZZ_Deviation = 5; // ZigZag deviation input int ZZ_Backstep = 3; // ZigZag backstep input int LookBackBars = 200; // Bars to search for pivots input int ExtendFutureBars = 100; // Bars to extend trendlines into the future // Global indicator handle for ZigZag int zzHandle; // Arrays for ZigZag data and pivot storage double zzBuffer[]; datetime pivotTimes[]; double pivotPrices[]; bool pivotIsPeak[]; // Variable to detect new bars datetime lastBarTime = 0; //+------------------------------------------------------------------+ //| Initialization function | //+------------------------------------------------------------------+ int OnInit() { zzHandle = iCustom(_Symbol, InpTimeFrame, "ZigZag", ZZ_Depth, ZZ_Deviation, ZZ_Backstep); if(zzHandle == INVALID_HANDLE) { Print("Error creating ZigZag handle"); return(INIT_FAILED); } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { ObjectDelete(0, "Downtrend_HighLine"); ObjectDelete(0, "Uptrend_LowLine"); ObjectDelete(0, "Major_Resistance"); ObjectDelete(0, "Major_Support"); ObjectDelete(0, "Minor_Resistance"); ObjectDelete(0, "Minor_Support"); IndicatorRelease(zzHandle); } //+------------------------------------------------------------------+ //| Tick function | //+------------------------------------------------------------------+ void OnTick() { datetime currentBarTime = iTime(_Symbol, InpTimeFrame, 0); if(currentBarTime == lastBarTime) return; lastBarTime = currentBarTime; // Remove previous objects ObjectDelete(0, "Downtrend_HighLine"); ObjectDelete(0, "Uptrend_LowLine"); ObjectDelete(0, "Major_Resistance"); ObjectDelete(0, "Major_Support"); ObjectDelete(0, "Minor_Resistance"); ObjectDelete(0, "Minor_Support"); if(CopyBuffer(zzHandle, 0, 0, LookBackBars, zzBuffer) <= 0) { Print("Failed to copy ZigZag data"); return; } ArraySetAsSeries(zzBuffer, true); DrawZigZagTrendlines(); DrawSupportResistance(); } //+------------------------------------------------------------------+ //| Draw ZigZag-based Trendlines | //+------------------------------------------------------------------+ void DrawZigZagTrendlines() { double highPrices[10], lowPrices[10]; datetime highTimes[10], lowTimes[10]; int highCount = 0, lowCount = 0; // Extract swing points from the ZigZag buffer for(int i = 0; i < LookBackBars - 1; i++) { if(zzBuffer[i] != 0) { if(iHigh(_Symbol, InpTimeFrame, i) == zzBuffer[i] && highCount < 10) { highPrices[highCount] = zzBuffer[i]; highTimes[highCount] = iTime(_Symbol, InpTimeFrame, i); highCount++; } else if(iLow(_Symbol, InpTimeFrame, i) == zzBuffer[i] && lowCount < 10) { lowPrices[lowCount] = zzBuffer[i]; lowTimes[lowCount] = iTime(_Symbol, InpTimeFrame, i); lowCount++; } } } // Exclude the most recent swing if possible int usedHighCount = (highCount >= 4) ? highCount - 1 : highCount; int usedLowCount = (lowCount >= 4) ? lowCount - 1 : lowCount; double mHigh = 0, bHigh = 0, mLow = 0, bLow = 0; bool validHigh = false, validLow = false; // Regression for highs if(usedHighCount >= 3) { double sumT = 0, sumP = 0, sumTP = 0, sumT2 = 0; for(int i = 0; i < usedHighCount; i++) { double t = (double)highTimes[i]; double p = highPrices[i]; sumT += t; sumP += p; sumTP += t * p; sumT2 += t * t; } int N = usedHighCount; double denominator = N * sumT2 - sumT * sumT; if(denominator != 0) { mHigh = (N * sumTP - sumT * sumP) / denominator; bHigh = (sumP - mHigh * sumT) / N; } else bHigh = sumP / N; validHigh = true; } // Regression for lows if(usedLowCount >= 3) { double sumT = 0, sumP = 0, sumTP = 0, sumT2 = 0; for(int i = 0; i < usedLowCount; i++) { double t = (double)lowTimes[i]; double p = lowPrices[i]; sumT += t; sumP += p; sumTP += t * p; sumT2 += t * t; } int N = usedLowCount; double denominator = N * sumT2 - sumT * sumT; if(denominator != 0) { mLow = (N * sumTP - sumT * sumP) / denominator; bLow = (sumP - mLow * sumT) / N; } else bLow = sumP / N; validLow = true; } // Define time limits for trendlines datetime pastTime = iTime(_Symbol, InpTimeFrame, LookBackBars - 1); datetime futureTime = lastBarTime + ExtendFutureBars * PeriodSeconds(); // Draw trendlines if both regressions are valid if(validHigh && validLow) { // When slopes have the same sign, use average slope if(mHigh * mLow > 0) { double mParallel = (mHigh + mLow) / 2.0; double bHighParallel = highPrices[0] - mParallel * (double)highTimes[0]; double bLowParallel = lowPrices[0] - mParallel * (double)lowTimes[0]; datetime highStartTime = pastTime; double highStartPrice = mParallel * (double)highStartTime + bHighParallel; double highEndPrice = mParallel * (double)futureTime + bHighParallel; if(!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice)) Print("Failed to create High Trendline"); else { ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed); ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true); ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true); } datetime lowStartTime = pastTime; double lowStartPrice = mParallel * (double)lowStartTime + bLowParallel; double lowEndPrice = mParallel * (double)futureTime + bLowParallel; if(!ObjectCreate(0, "Uptrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice)) Print("Failed to create Low Trendline"); else { ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_COLOR, clrGreen); ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_RAY_LEFT, true); ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_RAY_RIGHT, true); } } else { datetime highStartTime = pastTime; double highStartPrice = mHigh * (double)highStartTime + bHigh; double highEndPrice = mHigh * (double)futureTime + bHigh; if(!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice)) Print("Failed to create High Trendline"); else { ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed); ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true); ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true); } datetime lowStartTime = pastTime; double lowStartPrice = mLow * (double)lowStartTime + bLow; double lowEndPrice = mLow * (double)futureTime + bLow; if(!ObjectCreate(0, "Uptrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice)) Print("Failed to create Low Trendline"); else { ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_COLOR, clrGreen); ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_RAY_LEFT, true); ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_RAY_RIGHT, true); } } } else { if(validHigh) { datetime highStartTime = pastTime; double highStartPrice = mHigh * (double)highStartTime + bHigh; double highEndPrice = mHigh * (double)futureTime + bHigh; if(!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice)) Print("Failed to create High Trendline"); else { ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed); ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true); ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true); } } if(validLow) { datetime lowStartTime = pastTime; double lowStartPrice = mLow * (double)lowStartTime + bLow; double lowEndPrice = mLow * (double)futureTime + bLow; if(!ObjectCreate(0, "Uptrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice)) Print("Failed to create Low Trendline"); else { ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_COLOR, clrGreen); ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_RAY_LEFT, true); ObjectSetInteger(0, "Uptrend_LowLine", OBJPROP_RAY_RIGHT, true); } } } } //+------------------------------------------------------------------+ //| Draw Support and Resistance Levels | //+------------------------------------------------------------------+ void DrawSupportResistance() { double confirmedHighs[10], confirmedLows[10]; int confHighCount = 0, confLowCount = 0; for(int i = 0; i < LookBackBars - 1; i++) { if(zzBuffer[i] != 0) { if(iHigh(_Symbol, InpTimeFrame, i) == zzBuffer[i] && confHighCount < 10) { confirmedHighs[confHighCount] = zzBuffer[i]; confHighCount++; } else if(iLow(_Symbol, InpTimeFrame, i) == zzBuffer[i] && confLowCount < 10) { confirmedLows[confLowCount] = zzBuffer[i]; confLowCount++; } } } int usedHighCount = (confHighCount >= 4) ? confHighCount - 1 : confHighCount; int usedLowCount = (confLowCount >= 4) ? confLowCount - 1 : confLowCount; double majorResistance = -1e9, majorSupport = 1e9; double minorResistance = -1e9, minorSupport = 1e9; double tempHigh = -1e9, tempLow = -1e9; for(int i = 0; i < usedHighCount; i++) { if(confirmedHighs[i] > majorResistance) { tempHigh = majorResistance; majorResistance = confirmedHighs[i]; } else if(confirmedHighs[i] > tempHigh) { tempHigh = confirmedHighs[i]; } } if(tempHigh > -1e9) minorResistance = tempHigh; for(int i = 0; i < usedLowCount; i++) { if(confirmedLows[i] < majorSupport) { tempLow = majorSupport; majorSupport = confirmedLows[i]; } else if(confirmedLows[i] < tempLow) { tempLow = confirmedLows[i]; } } if(tempLow < 1e9) minorSupport = tempLow; if(usedHighCount > 0) { if(!ObjectCreate(0, "Major_Resistance", OBJ_HLINE, 0, 0, majorResistance)) Print("Failed to create Major Resistance"); else ObjectSetInteger(0, "Major_Resistance", OBJPROP_COLOR, clrMagenta); if(minorResistance > -1e9 && minorResistance < majorResistance) { if(!ObjectCreate(0, "Minor_Resistance", OBJ_HLINE, 0, 0, minorResistance)) Print("Failed to create Minor Resistance"); else ObjectSetInteger(0, "Minor_Resistance", OBJPROP_COLOR, clrFuchsia); } } if(usedLowCount > 0) { if(!ObjectCreate(0, "Major_Support", OBJ_HLINE, 0, 0, majorSupport)) Print("Failed to create Major Support"); else ObjectSetInteger(0, "Major_Support", OBJPROP_COLOR, clrAqua); if(minorSupport < 1e9 && minorSupport > majorSupport) { if(!ObjectCreate(0, "Minor_Support", OBJ_HLINE, 0, 0, minorSupport)) Print("Failed to create Minor Support"); else ObjectSetInteger(0, "Minor_Support", OBJPROP_COLOR, clrBlue); } } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+
Ergebnisse
Bevor wir die Ergebnisse analysieren, fügen wir zunächst den ZigZag-Indikator in das Chart ein. Um den Prozess besser zu verstehen, sehen Sie sich bitte das nachstehende GIF-Chart an. Diese visuelle Hilfe soll die einzelnen Schritte veranschaulichen. Anhand des Charts können Sie sehen, wie der Indikator integriert und konfiguriert ist. Wenn das klar ist, können wir zur Analyse der Ergebnisse übergehen.
Abb. 5. Initialisierung des ZigZag-Indikators
Diese Reihe von Charts veranschaulicht die Ergebnisse, wobei jedes Chart von ausführlichen Erläuterungen begleitet wird. Das nachstehende Chart zeigt zunächst das Ergebnis, das nach der Ausführung des Zig Zag Analyzer-Tools für den Stufenindex erzielt wurde. Wie beobachtet, werden die Trendlinien genau gezeichnet, wenn der EA auf das Chart angewendet wird. Sowohl die untere als auch die obere Linie sind abwärts gerichtet, was auf einen Abwärtstrend hindeutet. Darüber hinaus zeigen die Charts deutlich die großen und kleinen Unterstützungs- und Widerstandsebenen an.
Abb. 6. Ergebnis zum Stufenindex
Dieser Screenshot bietet zusätzliche Einblicke in die Analyse. In der Abbildung sehen Sie wichtige Umkehrpunkte wie untere Hochs und untere Tiefs, die für die Konstruktion von Trendlinien verwendet werden. Größere und kleinere Unterstützungs- und Widerstandsniveaus sind deutlich markiert. Vor allem die Schnittpunkte zwischen den Trendlinien und den wichtigsten Kursniveaus markieren starke Umkehrpunkte. Das höchste untere Hoch trifft auf den Hauptwiderstand und das niedrigste untere Tief auf die Hauptunterstützung, wo eine Umkehr stattfindet.
Abb. 7. Stufenindex
Dieses USDCHF-Chart zeigt eingezeichnete Trendlinien. Sie sind auf dem Markt präsent, aber nicht übermäßig dominant. Der Markt respektiert die Unterstützungs- und Widerstandsniveaus, was die Wirksamkeit des Systems bestätigt. Ich habe die Punkte hervorgehoben, an denen die Trendlinien die Marktschwankungen berühren.
Abb. 8. USDCHF
Schließlich können wir seine Performance im Index Volatility 25 betrachten. Die Trendlinien sind deutlich eingezeichnet und verbinden die Umkehrpunkte. Die Linien verdeutlichen die Bewegungen des Marktes mit Präzision. Diese Klarheit stärkt die Zuverlässigkeit des Systems unter verschiedenen Marktbedingungen. Die Ergebnisse bestätigen die Wirksamkeit unseres Ansatzes.
Abb. 9. Volatilität 25 Index
Schlussfolgerung
Das Tool Zig Zag Analyzer ist eine leistungsstarke Methode zur Automatisierung der Preisaktionsanalyse mit MQL5. Unsere Tests zeigen, dass die Trendlinien in Märkten, die sich im Trend befinden, effektiv gezeichnet werden. Ich glaube, dass dieser Ansatz zur Entwicklung zusätzlicher Tools führen kann, die Muster wie Fahnen- und Dreiecksformationen erkennen. Der Zig Zag Analyzer dient Anfängern im Devisenhandel als Ausgangspunkt, um Trends zu beobachten und potenzielle Unterstützungs- oder Widerstandszonen zu erkennen. Sie ist auch für erfahrene Händler wertvoll, da Trendlinien für die Preisaktionsanalyse von zentraler Bedeutung sind. Dieses Tool eignet sich hervorragend zum Lernen und kann an verschiedene Handelsstrategien angepasst werden, wobei auch andere Bestätigungsmethoden einbezogen werden können.
Datum | Name des Werkzeugs | Beschreibung | Version | Aktualisierungen | Hinweis |
---|---|---|---|---|---|
01/10/24 | Chart Projector | Skript zur Überlagerung der Kursentwicklung des Vortages mit einem Ghost-Effekt. | 1.0 | Erste Veröffentlichung | Toolkit Nummer 1 |
18/11/24 | Analytical Comment | Er liefert Informationen zum Vortag in Tabellenform und nimmt die zukünftige Marktentwicklung vorweg. | 1.0 | Erste Veröffentlichung | Toolkit Nummer 2 |
27/11/24 | Analytics Master | Reguläre Aktualisierung der Marktmetriken alle zwei Stunden. | 1.01 | Zweite Veröffentlichung | Toolkit Nummer 3 |
02/12/24 | Analytics Forecaster | Reguläre Aktualisierung der Marktmetriken alle zwei Stunden mit Telegram-Integration. | 1.1 | Dritte Ausgabe | Toolkit Nummer 4 |
09/12/24 | Volatility Navigator | Der EA analysiert die Marktbedingungen anhand der Indikatoren Bollinger Bands, RSI und ATR. | 1.0 | Erste Veröffentlichung | Toolkit Nummer 5 |
19/12/24 | Mean Reversion Signal Reaper | Analysiert den Markt anhand der Strategie „Umkehr zur Mitte“ und liefert Signale. | 1.0 | Erste Veröffentlichung | Toolkit Nummer 6 |
9/01/25 | Signal Pulse | Analysator für mehrere Zeitrahmen. | 1.0 | Erste Veröffentlichung | Toolkit Nummer 7 |
17/01/25 | Metrics Board | Bedienfeld mit Taste für die Analyse. | 1.0 | Erste Veröffentlichung | Toolkit Nummer 8 |
21/01/25 | External Flow | Analytik durch externe Bibliotheken. | 1.0 | Erste Veröffentlichung | Toolkit Nummer 9 |
27/01/25 | VWAP | Volumengewichteter Durchschnittspreis | 1.3 | Erste Veröffentlichung | Toolkit Nummer 10 |
02/02/25 | Heikin Ashi | Trendglättung und Identifizierung von Umkehrsignalen | 1.0 | Erste Veröffentlichung | Toolkit Nummer 11 |
04/02/25 | FibVWAP | Signalerzeugung durch Python-Analyse | 1.0 | Erste Veröffentlichung | Toolkit Nummer 12 |
14/02/25 | RSI DIVERGENCE | Kursentwicklung versus RSI-Divergenzen | 1.0 | Erste Veröffentlichung | Toolkit Nummer 13 |
17/02/25 | Parabolic Stop and Reverse (PSAR) | Automatisierung der PSAR-Strategie | 1.0 | Erste Veröffentlichung | Toolkit Nummer 14 |
20/02/25 | Quarters Drawer Script | Einzeichnen der Ebenen der Viertel auf dem Chart | 1.0 | Erste Veröffentlichung | Toolkit Nummer 15 |
27/02/25 | Intrusion Detector | Erkennen und warnen, wenn der Preis ein Viertel-Niveau erreicht | 1.0 | Erste Veröffentlichung | Toolkit Nummer 16 |
27/02/25 | TrendLoom Tool | Analysepanel für mehrere Zeitrahmen | 1.0 | Erste Veröffentlichung | Toolkit Nummer 17 |
11/03/25 | Quarters Board | Bedienfeld mit Tasten zum Aktivieren oder Deaktivieren der Viertel-Ebenen | 1.0 | Erste Veröffentlichung | Toolkit Nummer 18 |
26/03/25 | ZigZag Analyzer | Zeichnen von Trendlinien mit dem ZigZag-Indikator | 1.0 | Erste Veröffentlichung | Toolkit Nummer 19 |
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/17625
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.
Ich finde diesen Indikator sehr interessant. Er würde mir bei meiner technischen Analyse sehr helfen, da ich die meiste Zeit damit verbringe, um den richtigen Trend, die Unterstützung und den Widerstand zu finden. Ich habe den Code heruntergeladen, und er wurde korrekt kompiliert, aber wenn ich ihn in den Chart einfüge, werden keine Informationen angezeigt. Mache ich etwas falsch? Ich habe wieder ein Video angehängt. Mit freundlichen Grüßen.
>Hallo Cristina, viele Grüße.
Ich finde diesen Indikator sehr interessant. Er würde mir bei meiner technischen Analyse sehr helfen, da ich die meiste Zeit damit verbringe, um den richtigen Trend, die Unterstützung und den Widerstand zu finden. Ich habe den Code heruntergeladen, und er wurde korrekt kompiliert, aber wenn ich ihn in den Chart einfüge, werden keine Informationen angezeigt. Mache ich etwas falsch? Ich habe wieder ein Video angehängt. Mit freundlichen Grüßen.
Hie diego herrera
>Hallo Cristina, viele Grüße.
Ich finde diesen Indikator sehr interessant. Er würde mir bei meiner technischen Analyse sehr helfen, da ich die meiste Zeit damit verbringe, um den richtigen Trend, die Unterstützung und den Widerstand zu finden. Ich habe den Code heruntergeladen, und er wurde korrekt kompiliert, aber wenn ich ihn in den Chart einfüge, werden keine Informationen angezeigt. Mache ich etwas falsch? Ich habe wieder ein Video angehängt. Meine Grüße.
>Hallo Cristina, viele Grüße.
Ich finde diesen Indikator sehr interessant. Er würde mir bei meiner technischen Analyse sehr helfen, da ich die meiste Zeit damit verbringe, um den richtigen Trend, die Unterstützung und den Widerstand zu finden. Ich habe den Code heruntergeladen, und er wurde korrekt kompiliert, aber wenn ich ihn in den Chart einfüge, werden keine Informationen angezeigt. Mache ich etwas falsch? Ich habe wieder ein Video angehängt. Mit freundlichen Grüßen.
Versuchen Sie dies