
Vom Neuling zum Experten: Support and Resistance Strength Indicator (SRSI)
Inhalt
- Einführung
- Überblick über die Diskussion
- Ein Beweis für die Natur des heutigen Marktes.
- Implementierung von MQL5 zur Entwicklung von SRSI.
- Tests und Ergebnisse
- Schlussfolgerung
- Anhang (SRSI-Quelldatei)
Einführung
Die Märkte halten sich stets an frühere Preisniveaus, die ihre Bewegungen beeinflusst haben. Ein typischer Händlertag beginnt oft mit dem manuellen Zeichnen dieser Schlüsselniveaus mit dem bekannten Linieninstrument in MetaTrader 5. Dieser manuelle Prozess kann jedoch dazu führen, dass auffällige Werte übersehen oder die Bedeutung falsch eingeschätzt wird, was den Bedarf an einer automatisierten Lösung verdeutlicht.
Man könnte sich fragen, warum eine Automatisierung notwendig ist. Während wir Menschen uns bei komplexen, kreativen Aufgaben und der Anpassung an neue Situationen auszeichnen, haben wir oft Probleme mit der Konsistenz und dem Umgang mit großen Datenmengen. Forschungen von Mark Angelo D. Julian, Danilo B. Villarino und Kristine T. Soberano in ihrer Veröffentlichung vom 7. Juli 2024, „The Human Brain Versus Computer: Which is Smarter?“ unterstreicht diesen Punkt. Aus ihrer Studie geht hervor, dass Menschen zwar besser in der Lage sind, Zusammenhänge zu verstehen, Computer jedoch in Bezug auf Verarbeitungsgeschwindigkeit, Datengenauigkeit und die Durchführung sich wiederholender Berechnungen weit überlegen sind. Dieser Kontrast treibt unsere laufende Entwicklung von Algorithmen für den Handel und die Datenanalyse voran.
Überblick über die Diskussion
Heute werden wir Problemlösungstechniken mit Hilfe der MQL5-Programmierung anwenden, um die oben erwähnte Herausforderung zu bewältigen. Diese Diskussion richtet sich an Händler aller Qualifikationsstufen, von Anfängern bis hin zu Experten, da wir wichtige Konzepte ansprechen, die sich auf alle auswirken. Wie Sie wissen, ist der MetaTrader 5 im Wesentlichen ein riesiger Fundus an Kursdaten, Analysetools und historischen Informationen. Kerzen-Serien zum Beispiel sind berechnete Balken, die Eröffnungs-, Höchst-, Tiefst- und Schlusskurse darstellen, und beliebte Indikatoren wie gleitende Durchschnitte werden von diesen Werten abgeleitet. Stellen Sie sich vor, Sie müssten 5.000 Kerzen manuell überprüfen - dieser Prozess ist nicht nur mühsam, sondern auch fehleranfällig. Deshalb ist die Automatisierung der Identifizierung von Unterstützungs- und Widerstandsniveaus so vorteilhaft.
Zwar gibt es bereits mehrere kostenlose und kostenpflichtige Tools auf dem Markt, doch wir erforschen heute einen einzigartigen Ansatz. In dieser Sitzung geht es nicht nur um das Endprodukt, sondern auch um die Vermittlung der MQL5-Programmierkenntnisse, die Sie benötigen, um Ihre eigene maßgeschneiderte Lösung zu erstellen. Im Folgenden werden die Vorteile des von uns entwickelten Support and Resistance Strength Indicator (SRSI) erläutert:
- Effiziente Datenverarbeitung: Analysiert umfangreiche historische Kerzen-Daten, um wichtige Niveaus zu ermitteln.
- Kontinuierliche Automatisierung: Arbeitet automatisch und kontinuierlich und reduziert so manuelle Fehler.
- Niveaudifferenzierung: Identifiziert sowohl schwache als auch starke Unterstützungs- und Widerstandsniveaus.
- Klares Bildmaterial: Bietet eine klare, visuelle Darstellung dieser kritischen Ebenen.
- Umfassende Benachrichtigungen: Bietet Nutzerbenachrichtigungen über Terminal und Push-Benachrichtigungen.
In den folgenden Abschnitten werden wir zunächst historische Kursdaten mithilfe von MetaTrader 5-Charts und manuell ermittelten Unterstützungs- und Widerstandsniveaus sammeln. Diese erste Analyse wird Anhaltspunkte für einen Vergleich des aktuellen Marktverhaltens mit den Ergebnissen der Vergangenheit liefern. Als Nächstes werden wir in den Entwicklungsprozess eintauchen, bei dem ich den Code für unseren nutzerdefinierten Indikator mit Ihnen teilen und aufschlüsseln werde - ich erkläre jede Zeile im Detail, um sicherzustellen, dass Sie vollständig verstehen, wie man MQL5 implementiert und Ihre Ideen in Code umsetzt.
Abschließend werden wir den Testprozess überprüfen und unsere Ergebnisse präsentieren, sodass Sie sowohl über verbesserte Programmierkenntnisse als auch über eine funktionierende Lösung verfügen. Nehmen Sie sich Zeit, folgen Sie den Anweisungen und genießen Sie die Reise in die Programmierung.
Ein Beweis für die Natur des heutigen Marktes
Mein Broker bietet mir einen Zugang zu einer breiten Palette von Handelspaaren. Je nach Kontotyp kann ich Volatilitätspaare, Devisenpaare, Aktienpaare und mehr handeln. Die Abbildung zeigt eine große Auswahl an zusätzlichen Paaren, die für den Handel zur Verfügung stehen. Für diese Untersuchung habe ich mehrere Paare aus dieser Sammlung ausgewählt, um sie zu analysieren.
Um die von Ihrem Broker angebotenen Paare zu sehen und sie zu Ihrer Market Watch-Liste hinzuzufügen, drücken Sie einfach STRG + U auf Ihrer Tastatur oder klicken Sie auf das rote, runde Symbol (wie in der Abbildung unten), um das Fenster Symbole zu öffnen. Doppelklicken Sie dann auf das gewünschte Paar, um es automatisch zu Ihrer Liste hinzuzufügen.
DerivSVG MetaTrader 5 Symbole
Synthetische Paare
Ich begann meine Analyse mit einem synthetischen Paar unter den Volatilitätsindizes - dem Volatility 75 (1s) Index - auf dem wöchentlichen Zeitrahmen. Als dieses Paar um das Jahr 2020 eingeführt wurde, war es zunächst teuer, erlebte aber bald einen lang anhaltenden Absturz und bildete über Wochen einen starken Abwärtstrend. Händler, die in diesem Zeitraum Leerverkäufe tätigten, erzielten wahrscheinlich erhebliche Gewinne. Mein Hauptaugenmerk liegt jedoch auf der Marktstruktur, insbesondere in den letzten drei Jahren.
Der anhaltende Abwärtstrend hat die Händler wahrscheinlich dazu veranlasst, eine trendfolgende Haltung einzunehmen und mit weiteren Rückgängen zu rechnen. Wie die folgende Abbildung zeigt, hat sich die Marktdynamik jedoch verschoben. Der höhere Zeitrahmen weist nun eine unruhige Range-Struktur auf, wobei ähnliche Merkmale in den niedrigeren Zeitrahmen zu beobachten sind. Unter solchen Bedingungen ist es für Swing-Trader schwierig, sich zurechtzufinden.
Unter diesen Umständen ist die Preisentwicklung auf der Grundlage von Unterstützung und Widerstand von entscheidender Bedeutung für die Identifizierung wichtiger Handelsmöglichkeiten. Die folgende Abbildung veranschaulicht dieses Marktverhalten und unterstreicht die Bedeutung eines strukturierten Ansatzes für die technische Analyse.
Volatilität 75 (1s) Index
Aktien-Paar
Ich habe das Wochenchart der US-Technologie analysiert, und es ist offensichtlich, dass der Markt einen Aufwärtstrend mit periodischen Korrekturen aufweist. Diese Korrekturen führen häufig zu Konsolidierungsphasen, in denen sich die Kursbewegung verlangsamt, bevor der Trend wieder aufgenommen wird. In einem Aufwärtsmarkt werden durch Korrekturen in der Regel starke Unterstützungszonen geschaffen, die das Aufwärtsmomentum verstärken.
In diesem höheren Zeitrahmen ist es schwierig, die genauen Muster zu erkennen, die das Kursgeschehen in den niedrigeren Zeitrahmen beeinflussen. Bei näherer Betrachtung werden wir jedoch feststellen, dass das Konzept der Unterstützung und des Widerstands über verschiedene Zeitrahmen hinweg anwendbar bleibt und es uns ermöglicht, verschiedene Marktmuster genauer zu beobachten.
US Tech 100 Wochenchart
Forex-Paar
Das Wochenchart von EUR/USD zeigt eine kleine Impulsphase, gefolgt von einer längeren Schwankungsperiode. Dieses Verhalten ist auf dem höheren Zeitrahmen ersichtlich und erstreckt sich auch auf niedrigere Zeitrahmen. Das Wichtigste hier ist die ausgedehnte Preisspanne, die deutlich macht, dass der Markt viel Zeit mit Konsolidierung verbringt, anstatt zu tendieren. Die nachstehende Abbildung dient als Beweis für dieses anhaltende Marktverhalten innerhalb einer bestimmten Spanne.
EURUSD Wochenchart
Aus den obigen Ausführungen geht eindeutig hervor, dass die Marktpreise zwar steigende oder fallende Trends aufweisen, dass sie jedoch in hohem Maße von früheren Preisniveaus abhängen, um sie zu testen und zu validieren. Während der Konsolidierungsphasen werden diese horizontalen Niveaus je nach gewähltem Zeitrahmen zu Schlüsselbereichen, in denen die Kurse zu reagieren pflegen.
Allerdings ist nicht jedes Niveau stark genug, um eine deutliche Kursbewegung auszulösen. Darüber hinaus sind selbst gut etablierte Unterstützungs- oder Widerstandsniveaus keine Garantie für eine Kursreaktion, aber sie bieten eine höhere Wahrscheinlichkeit, das Marktverhalten zu beeinflussen, wenn sie sich als stark erweisen.
Im nächsten Abschnitt gehen wir kurz auf die Grundlagen von Unterstützung und Widerstand ein, bevor wir uns mit der Entwicklung des Algorithmus beschäftigen.
Implementierung von MQL5 zur Entwicklung von SRSI
Definition von Unterstützung und Widerstand
Unterstützung wird im Allgemeinen als eine Zone der Nachfrage definiert, in der mehrere Preisniveaus zusammenlaufen, was darauf hindeutet, dass die Käufer geneigt sind, einzugreifen und den Preis zu erhöhen. Dieser Bereich stellt eine „Untergrenze“ für den Markt dar, in der die Anhäufung von Kaufinteresse tendenziell weitere Rückgänge verhindert.
- In der Praxis handelt es sich bei der Unterstützung in der Regel nicht um einen einzelnen Preispunkt, sondern um eine Zone, in der frühere Tiefststände oder mehrere Berührungspunkte das Vertrauen der Käufer gestärkt haben.
Umgekehrt ist der Widerstand eine Angebotszone, in der mehrere Preisniveaus zusammenlaufen, was darauf hindeutet, dass die Verkäufer wahrscheinlich eingreifen und den Preis nach unten drücken werden. Dieser Bereich fungiert als „Obergrenze“ für den Markt, in dem der Verkaufsdruck den Kaufdruck übersteigt, was häufig einen weiteren Preisanstieg verhindert. Wie die Unterstützung wird auch der Widerstand in der Regel eher als eine Spanne denn als ein genaues Niveau beobachtet, da es mehrere Höchststände oder Berührungspunkte gibt, die das Verkaufsinteresse verstärken.
Mit diesem Verständnis im Hinterkopf wird die Arbeit mit Unterstützung und Widerstand viel einfacher. Im folgenden Video führe ich Sie durch meine Routine, um Ihnen zu zeigen, wie ich diese Linien normalerweise ziehe.
Entwurf und Implementierung von Algorithmen
Wir brauchen ein Programm, das die manuelle Identifizierung und Markierung von Unterstützungs- und Widerstandszonen nachbildet. Nachdem ich mir das Video angesehen habe, habe ich die wichtigsten Schritte hier zusammengefasst:
- Identifizieren der extremen Wendepunkte: Dabei handelt es sich um signifikante Höchst- (für Widerstand) oder Tiefststände (für Unterstützung), bei denen der Kurs die Richtung wechselt.
- Finden von anderen Prüfpunkte: Nach weiteren Kursniveaus suchen, bei denen der Kurs dem extremen Wendepunkt entspricht oder bis auf 5 Punkte an ihn heranreicht, um seine Bedeutung zu bestätigen.
- Bilden von Bounce-Zonen: Erstellen von rechteckigen Zonen, die die extremen Wendepunkte und ihre Prüfpunkte umfassen, wobei sich die Zone um diese Berührungspunkte herum erstreckt.
- Anpassen der Abmessungen der Zone:
- Höhe: Die vertikale Größe des Zonenrechtecks (in Pips) sollte einstellbar sein.
- Breite: Die horizontale Größe der Zone (in Kerzen-Balken nach rechts) sollte einstellbar sein.
Im Allgemeinen werden wir unser Programm so konfigurieren, dass es eine anpassbare Anzahl von Kerzen scannt, Bedingungen identifiziert, die unsere Kriterien erfüllen, und die entsprechenden Formen, Linien und Beschriftungen zeichnet. Wir werden auch Eingabemöglichkeiten anbieten, um verschiedene Funktionen des Programms zu steuern. Für Benachrichtigungen werden wir Push-Benachrichtigungen und Terminal-Benachrichtigungen implementieren, die in regelmäßigen Abständen innerhalb eines anpassbaren 4-Stunden-Intervalls übermittelt werden. Im Gegensatz zu anderen Indikatoren müssen die Unterstützungs- und Widerstandsniveaus nicht ständig überwacht werden, sodass dieser Ansatz rechtzeitige Benachrichtigungen ohne übermäßige Warnungen gewährleistet. Im Folgenden erkläre ich die Details Schritt für Schritt, zusammen mit Code-Ausschnitten.
Wenn Sie MetaEditor 5 öffnen und einen neuen nutzerdefinierten Indikator erstellen, erhalten Sie eine grundlegende Vorlage, mit der Sie arbeiten können. Diese Vorlage ist wie eine leere Leinwand, die Entwicklern den Einstieg erleichtert, und darauf werden wir unseren SRSI-Indikator aufbauen. So sieht er aus:
//+------------------------------------------------------------------+ //| _SRSI.mq5 | //| Copyright 2025, Metaquotes Ltd | //| https://www.mql5.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Metaquotes Ltd" #property link "https://www.mql5.com/" #property version "1.00" #property indicator_chart_window //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+
Wir werden dies als grundlegenden Leitfaden verwenden, um sicherzustellen, dass alle wichtigen Funktionen ordnungsgemäß umgesetzt werden. In den folgenden Schritten werden wir die Vorlage vervollständigen, neue Funktionen integrieren und deren Funktionsweise ausführlich erläutern. Bitte folgen Sie dem Text bis zum Ende, um ein umfassendes Verständnis zu erhalten.
Schritt 1: Anpassen der Indikatoreigenschaften
Zu Beginn passen wir die Eigenschaften des Indikators an, um ihn zu personalisieren und die Anforderungen von MetaTrader 5 zu erfüllen. Wir aktualisieren die Angaben zum Copyright und zu den Links, um unsere eigenen Informationen wiederzugeben. Wir fügen eine Einstellung für eine strengere Fehlerprüfung hinzu, um Fehler während der Entwicklung zu erkennen. Der Indikator ist so eingestellt, dass er im Hauptfenster des Charts angezeigt wird. Da MetaTrader 5 mindestens einen Puffer benötigt, definieren wir einen einzigen versteckten „Dummy“-Puffer, da unser Indikator nutzerdefinierte Objekte (Linien und Rechtecke) anstelle von gezeichneten Pufferdaten verwenden wird.
#property copyright "Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" #property strict // Enforces stricter error checking #property indicator_chart_window #property indicator_buffers 1 // MT5 requires at least one buffer #property indicator_plots 1 // Ties to the buffer (even if unused for plotting)
Schritt 2: Hinzufügen von Nutzereingaben
Als Nächstes fügen wir nutzerkonfigurierbare Eingaben hinzu, um den Indikator anpassungsfähig zu machen. Es gibt eine Option, mit der wir festlegen können, wie viele vorherige Balken der Indikator analysiert, eine Preisspanne (z. B. standardmäßig 7 Pips) für die Erkennung von Niveautests, eine Mindestanzahl von Tests, die erforderlich sind, damit ein Niveau als stark gilt, und einen Schalter, mit dem wir rechteckige Zonen um starke Niveaus ein- oder ausblenden können. Diese Eingaben ermöglichen es den Nutzern, das Verhalten des Indikators zu optimieren, ohne den Code zu ändern.
input int InpLookBack = 1000; // Number of bars to analyze input double InpTestProximity = 0.0007; // Price range for tests (e.g., 7 pips) input int InpMinTests = 3; // Minimum tests for strong levels input bool InpShowRectangles = true; // Show zones as rectangles
Schritt 3: Erstellen eines Dummy-Puffers
MetaTrader 5 schreibt vor, dass jeder Indikator mindestens einen Puffer hat, auch wenn er nicht angezeigt wird. Wir erstellen ein globales Array, das als Dummy-Puffer dient. Während der Initialisierung binden wir ihn an einen Pufferslot und verbergen ihn vor dem Chart. Dies erfüllt die Anforderungen von MetaTrader 5 und ermöglicht es uns, uns auf das Zeichnen nutzerdefinierter Unterstützungs- und Widerstandsniveaus zu konzentrieren.
double DummyBuffer[];
Verwendung:
int OnInit() { SetIndexBuffer(0, DummyBuffer, INDICATOR_DATA); // Bind buffer to index 0 PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_NONE); // Hide it from the chart return(INIT_SUCCEEDED); }
Schritt 4: Definieren von Datenstrukturen
Um unsere Daten zu organisieren, verwenden wir Enums und Structs. Der Übersichtlichkeit halber definieren wir ein Enum zur Kategorisierung der Stufen (z. B. starke Unterstützung, schwacher Widerstand). Eine Struktur für Preisstufen speichert den Preis, die Anzahl der Tests, den Typ und die Identifikationszeit jeder Stufe. Eine andere Struktur definiert Zonen um starke Niveaus, die ihre oberen und unteren Preise und Zeitspanne halten. Wir haben auch globale Arrays eingerichtet, um starke Pegel, schwache Pegel und Zonen zu speichern, sowie eine Variable, um die letzte Alarmzeit zu verfolgen.
enum ENUM_LEVEL_TYPE { LEVEL_STRONG_SUPPORT, // Strong support level LEVEL_STRONG_RESISTANCE, // Strong resistance level LEVEL_WEAK_SUPPORT, // Weak support level LEVEL_WEAK_RESISTANCE // Weak resistance level }; struct PriceLevel { double price; // Price value of the level int test_count; // Number of times price tested it ENUM_LEVEL_TYPE type; // Strong or weak, support or resistance datetime time; // Time the level was identified }; struct Zone { double top; // Top price of the zone double bottom; // Bottom price of the zone datetime start_time; // When the zone starts datetime end_time; // When the zone ends (current time) }; PriceLevel StrongLevels[]; // Array for strong levels PriceLevel WeakLevels[]; // Array for weak levels Zone Zones[]; // Array for strong level zones datetime LastAlertTime = 0; // Tracks the last alert time
Schritt 5: Erkennen von Umkehrpunkten
Unterstützungs- und Widerstandsniveaus bilden sich häufig an Schwunghochs und -tiefs. Wir erstellen eine Funktion zur Identifizierung von hohen Umkehrpunkten, indem wir prüfen, ob der Höchststand eines Balkens die Höchststände der 5 vorhergehenden und nachfolgenden Balken übersteigt und somit einen Höchststand markiert. In ähnlicher Weise prüft eine Funktion für tiefe Umkehrpunkte, ob das Tief eines Balkens unter den Tiefs der umliegenden 5 Balken liegt, was auf einen Tiefpunkt hindeutet. Die Verwendung eines 5-Balken-Fensters auf jeder Seite gewährleistet, dass diese Punkte signifikant sind.
bool IsSwingHigh(int index, const double &high[]) { int window = 5; // Check 5 bars on each side for (int i = 1; i <= window; i++) { if (index - i < 0 || index + i >= ArraySize(high)) return false; // Out of bounds if (high[index] <= high[index - i] || high[index] <= high[index + i]) return false; // Not a peak } return true; } bool IsSwingLow(int index, const double &low[]) { int window = 5; // Check 5 bars on each side for (int i = 1; i <= window; i++) { if (index - i < 0 || index + i >= ArraySize(low)) return false; // Out of bounds if (low[index] >= low[index - i] || low[index] >= low[index + i]) return false; // Not a trough } return true; }
Schritt 6: Zählen der Tests eines Preises
Die Stärke eines Niveaus hängt davon ab, wie oft der Preis getestet wird. Wir fügen eine Funktion hinzu, um diese Tests zu zählen, indem wir die Balken nach einem Umkehrpunkt untersuchen. Er prüft, ob der Höchst- oder Tiefstwert eines jeden Balkens innerhalb der definierten Preisspanne des Levels liegt, wobei ein Zähler für jeden Test erhöht wird. Die Gesamtzahl der Tests bestimmt, ob das Niveau stark oder schwach ist, basierend auf der vom Nutzer festgelegten Mindestschwelle.
int CountLevelTests(double price, int start_index, const double &high[], const double &low[]) { int tests = 0; for (int i = start_index + 1; i < ArraySize(high); i++) { if (MathAbs(high[i] - price) <= InpTestProximity || MathAbs(low[i] - price) <= InpTestProximity) { tests++; } } return tests; }
Schritt 7: Verarbeitungsebenen
Wir verarbeiten jeden Umkehrpunkt mit einer speziellen Funktion zu einer Ebene. Es zeichnet den Preis, die Anzahl der Tests, die Zeit und den Typ (stark/schwach, Unterstützung/Widerstand) auf, je nachdem, ob es sich um ein hohen oder tiefen Umkehrpunkt handelt und der Testschwelle entspricht. Für starke Niveaus wird auch eine Zone mit einer Preisspanne um das Niveau herum definiert. Der Pegel wird dann zur späteren Verwendung im entsprechenden Feld (stark oder schwach) gespeichert.
void ProcessLevel(int index, double price, bool is_high, const double &high[], const double &low[], const datetime &time[]) { PriceLevel level; level.price = price; level.test_count = CountLevelTests(price, index, high, low); level.time = time[index]; if (is_high) { level.type = (level.test_count >= InpMinTests) ? LEVEL_STRONG_RESISTANCE : LEVEL_WEAK_RESISTANCE; } else { level.type = (level.test_count >= InpMinTests) ? LEVEL_STRONG_SUPPORT : LEVEL_WEAK_SUPPORT; } if (level.test_count >= InpMinTests) { ArrayResize(StrongLevels, ArraySize(StrongLevels) + 1); StrongLevels[ArraySize(StrongLevels) - 1] = level; Zone zone; zone.start_time = time[index]; zone.end_time = TimeCurrent(); zone.top = price + InpTestProximity; zone.bottom = price - InpTestProximity; ArrayResize(Zones, ArraySize(Zones) + 1); Zones[ArraySize(Zones) - 1] = zone; } else { ArrayResize(WeakLevels, ArraySize(WeakLevels) + 1); WeakLevels[ArraySize(WeakLevels) - 1] = level; } }
Schritt 8: Zeichnen auf dem Chart
Zur Darstellung der Ebenen verwenden wir zwei Rendering-Funktionen. Man zeichnet starke Niveaus mit einem grauen Rechteck (falls aktiviert) für die Zone und einer durchgezogenen Linie - blau für Unterstützung, rot für Widerstand - sowie einer Bezeichnung („SS“ oder „SR“). Der andere zeichnet schwache Niveaus mit einer gestrichelten Linie - hellblau für Unterstützung, rosa für Widerstand - und einer Bezeichnung („WS“ oder „WR“) ein. Jedes Objekt erhält einen eindeutigen Namen, der auf seiner Zeit basiert, um eine ordnungsgemäße Verwaltung im Chart zu gewährleisten.
void RenderZone(const Zone &zone, const PriceLevel &level) { string name = "Zone_" + TimeToString(zone.start_time); if (InpShowRectangles) { ObjectCreate(0, name, OBJ_RECTANGLE, 0, zone.start_time, zone.top, zone.end_time, zone.bottom); ObjectSetInteger(0, name, OBJPROP_COLOR, clrLightGray); ObjectSetInteger(0, name, OBJPROP_FILL, true); } string line_name = "Line_" + TimeToString(level.time); ObjectCreate(0, line_name, OBJ_HLINE, 0, 0, level.price); ObjectSetInteger(0, line_name, OBJPROP_COLOR, (level.type == LEVEL_STRONG_SUPPORT) ? clrBlue : clrRed); ObjectSetString(0, line_name, OBJPROP_TEXT, (level.type == LEVEL_STRONG_SUPPORT) ? "SS" : "SR"); } void RenderWeakLine(const PriceLevel &level) { string name = "WeakLine_" + TimeToString(level.time); ObjectCreate(0, name, OBJ_HLINE, 0, 0, level.price); ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DASH); ObjectSetInteger(0, name, OBJPROP_COLOR, (level.type == LEVEL_WEAK_SUPPORT) ? clrLightBlue : clrPink); ObjectSetString(0, name, OBJPROP_TEXT, (level.type == LEVEL_WEAK_SUPPORT) ? "WS" : "WR"); }
Schritt 9: Senden von Warnmeldungen
Wir haben eine Funktion eingebaut, die Warnungen über starke Pegel sendet, ohne den Nutzer zu spammen. Es wird geprüft, ob seit dem letzten Alarm eine Stunde vergangen ist und ob starke Pegel vorliegen. Wenn dies der Fall ist, wird eine Meldung mit dem Typ, dem Preis und dem aktuellen Preis der letzten starken Stufe erstellt und angezeigt. Die Alarmzeit wird aktualisiert, um häufige Benachrichtigungen zu vermeiden.
void SendPeriodicAlert(double current_price) { if (TimeCurrent() - LastAlertTime < 3600) return; // Wait 1 hour between alerts if (ArraySize(StrongLevels) == 0) return; // No strong levels, no alert PriceLevel latest = StrongLevels[ArraySize(StrongLevels) - 1]; string message = "SRZones Alert: Strong " + ((latest.type == LEVEL_STRONG_SUPPORT) ? "Support" : "Resistance") + " at " + DoubleToString(latest.price, 5) + ", Current Price: " + DoubleToString(current_price, 5); Alert(message); LastAlertTime = TimeCurrent(); }
Schritt 10: Alte Zeichnungen bereinigen
Um das Chart sauber zu halten, fügen wir eine Funktion zum Entfernen alter Objekte hinzu. Es löscht alle zuvor gezeichneten Zonen, starken und schwachen Level-Linien mit bestimmten Namenspräfixen. Dies geschieht vor jeder vollständigen Neuberechnung, um die Anzeige mit den aktuellen Werten zu aktualisieren.
void ClearDisplayObjects() { ObjectsDeleteAll(0, "Zone_"); // Delete all zones ObjectsDeleteAll(0, "Line_"); // Delete strong lines ObjectsDeleteAll(0, "WeakLine_"); // Delete weak lines }
Schritt 11: Ausführen der Logik in OnCalculate
Schließlich wird alles in der Hauptberechnungsfunktion zusammengeführt. Beim Start oder wenn ein neuer Balken entsteht, werden alte Objekte gelöscht und die Arrays zurückgesetzt. Sie bestimmt einen Startpunkt auf der Grundlage der nutzerdefinierten Rückblickperiode, um genügend Daten für die Schwingungserkennung zu gewährleisten. Sie durchläuft die Balken in einer Schleife, identifiziert hohe und tiefe Umkehrpunkte, verarbeitet sie zu Niveaus und speichert sie. Anschließend werden alle starken und schwachen Werte angezeigt und auf Warnungen überprüft. Die Funktion gibt die Anzahl der verarbeiteten Balken an MetaTrader 5 zurück.
int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { if (prev_calculated == 0 || rates_total > prev_calculated) { // Full recalc on start or new bar ClearDisplayObjects(); ArrayResize(StrongLevels, 0); ArrayResize(WeakLevels, 0); ArrayResize(Zones, 0); int start = MathMax(5, rates_total - InpLookBack); // Start within lookback period for (int i = start; i < rates_total - 5; i++) { // Leave room for swing checks if (IsSwingHigh(i, high)) ProcessLevel(i, high[i], true, high, low, time); if (IsSwingLow(i, low)) ProcessLevel(i, low[i], false, high, low, time); } for (int i = 0; i < ArraySize(StrongLevels); i++) { RenderZone(Zones[i], StrongLevels[i]); } for (int i = 0; i < ArraySize(WeakLevels); i++) { RenderWeakLine(WeakLevels[i]); } SendPeriodicAlert(close[rates_total - 1]); } return(rates_total); // Tell MT5 how many bars were processed }
Nachdem wir alle Teile zusammengefügt und verschiedene Probleme gelöst hatten, stellten wir erfolgreich unser Endprodukt zusammen, das am Ende dieser Diskussion beigefügt ist. Im nächsten Abschnitt werden wir über unsere Testerfahrungen berichten und in der Schlussfolgerung abschließende Überlegungen anstellen.
Tests und Ergebnisse
Der erste Schritt bestand darin, den Indikator zu starten und ihn mit den Standardeinstellungen zum Chart hinzuzufügen, wobei EURUSD als Referenz verwendet wurde. Bei anderen Währungspaaren sind möglicherweise anfängliche Anpassungen erforderlich, insbesondere beim Pip-Wert, damit der Indikator korrekt angezeigt wird. Beim Testen des Index Volatility 75 (1s) erschienen beispielsweise keine Zonen, bis ich die Pip-Einstellung auf 70 anpasste.
Wie in der folgenden Abbildung zu sehen ist, war die Breite des Rechtecks anfangs relativ klein und musste angepasst werden, um die Größe zu erhöhen, was wir im nächsten Bild getan haben. Alle Einstellungen reagierten gut und zeigten deutliche Veränderungen auf dem Chart. Außerdem werden alle Beschriftungen deutlich angezeigt und können bei Bedarf ausgeblendet werden.
Hinzufügen des Support and Resistance Strength Indicator (SRSI) zum Chart.
Anpassen der Einstellungen für SRSI
Beim ersten Start sendet der Indikator eine Warnung, die das vorherrschende Unterstützungs- oder Widerstandsniveau zusammen mit dem aktuellen Kurs anzeigt. Dies hilft den Nutzern, potenzielle Angebots- und Nachfragezonen zu erkennen. Nachfolgend gibt es ein Expertenprotokoll mit den Details des Alarms.
2025.03.10 07:44:42.548 _SRSI (EURUSD,M15) Alert: Key Level: SR at 1.08715 | Current Price: 1.09021 2025.03.10 07:54:04.239 _SRSI (EURUSD,M15) Alert: Key Level: SR at 1.08715 | Current Price: 1.09033 2025.03.10 07:55:04.965 _SRSI (EURUSD,M5) Alert: Key Level: SR at 1.09013 | Current Price: 1.09044 2025.03.10 09:25:13.506 _SRSI (EURUSD,M5) Alert: Key Level: SR at 1.09013 | Current Price: 1.09210 2025.03.10 11:26:46.761 _SRSI (EURUSD,M5) Alert: Key Level: SR at 1.09013 | Current Price: 1.09192
Außerdem gibt es in den Einstellungen eine Option für Push-Benachrichtigungen, während Terminal-Benachrichtigungen standardmäßig aktiviert sind. Wenn ein Alarm ausgelöst wird, erscheint das Alarmfenster automatisch auf dem Bildschirm des Terminals.
Fenster der Warnhinweise des Terminals“: SRSI-Indikator funktioniert
Schlussfolgerung
Unser Diskussionsziel ist mit der Entwicklung eines fehlerfreien Indikators erfolgreich erreicht worden. Unsere Tests haben ergeben, dass die Ziele des Entwurfs erreicht wurden und die erwartete Funktionalität gegeben ist. Jetzt kann ich meine Unterstützungs- und Widerstandslinien mühelos mit nur wenigen Klicks einzeichnen, und der Algorithmus überprüft sie automatisch auf ihre Zuverlässigkeit. Wie Sie vielleicht im Video bemerkt haben, kann der manuelle Prozess ziemlich langsam sein, aber mit dem Algorithmus werden diese Werte sofort mit jedem Tick berechnet. Während dieses Prozesses sammelten wir wertvolle MQL5-Erkenntnisse für die Entwicklung von Indikatoren, und während die Leistung des Indikators im Laufe der Zeit bewertet werden kann, gibt es verschiedene Möglichkeiten für fortgeschrittene Entwickler, ihn zu verfeinern und zu erweitern.
Bei diesem Ansatz haben wir Strukturen als Mittel zum Schreiben von professionellerem und besser organisiertem Code eingeführt. Es gibt jedoch immer Raum für Verbesserungen, und ich glaube, Sie haben Ihre eigenen Ideen und Vorschläge zur Verbesserung dieses Tools. Sie können es gerne abändern und damit experimentieren, und zögern Sie nicht, Ihre Gedanken in den Kommentaren unten mitzuteilen.
Ich hoffe, diese Diskussion war für Sie aufschlussreich. Bis zum nächsten Mal - viel Spaß beim Programmieren und erfolgreiches Handeln, liebe Entwicklerfreunde!
Anhang (SRSI-Quelldatei)
Datei | Beschreibung |
---|---|
_SRSI.mq5 | Ein Indikator für die Stärke von Unterstützung und Widerstand, der dynamisch anpassbare rechteckige Zonen zeichnet, die starke Unterstützung (SS) und starken Widerstand (SR) deutlich kennzeichnen. Zusätzlich werden zur besseren Visualisierung gestrichelte Linien eingezeichnet, die schwächere Unterstützungs- (WS) und Widerstandsniveaus (WR) anzeigen. |
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/17450





- 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 mag wirklich Ihren Artikel und versuchte es auf FX-Paare, die gut zu funktionieren scheinen... Wie wäre es mit Indizes wie US30? was sind die Einstellung würden Sie empfehlen? Ich habe versucht, die Einstellung der Text Nähe zu 0,035 und die Ergebnisse scheint komisch
Herzlichen Dank!
Herzlichen Dank!
Hallo Freund
Ich verfolge Ihre Artikel und sie sind sehr informativ. Danke für das Teilen und Verbreiten von Wissen.
Ich habe versucht, 21Period ATR mehrere wie unten:
gTestProximity = (MathMax((75/_Digits),0.10*getATR(rates_total - 1))); // (n*getATR(index) ersetzt für ...InpTextProximity;
gMinDistance = (MathMax((150/_Digits),0.20*getATR(rates_total - 1))); // (n*getATR(index) ersetzt für ...InpMinWeakDistance;
Dies hat mir geholfen, SRZones für die Paare EURUSD und XAUUSD zu erhalten, wobei die Werte zwischen 1,08000 und 3000,00 sehr unterschiedlich sind.
Kann für die Leser Ihres Artikels mit weiteren Feinabstimmung ein wenig nützlich sein. Dann könnte der Indikator-Einstellungen universal für die meisten Symbole sein.
Hallo Freund
ich verfolge Ihre Artikel und sie sind informativ. Danke für das Teilen und Verbreiten von Wissen.
Ich habe versucht, 21Period ATR mehrere wie unten:
gTestProximity = (MathMax((75/_Digits),0.10*getATR(rates_total - 1))); // (n*getATR(index) ersetzt für ...InpTextProximity;
gMinDistance = (MathMax((150/_Digits),0.20*getATR(rates_total - 1))); // (n*getATR(index) ersetzt für ...InpMinWeakDistance;
Dies hat mir geholfen, SRZones für die Paare EURUSD und XAUUSD zu erhalten, wobei die Werte zwischen 1,08000 und 3000,00 sehr unterschiedlich sind.
Kann für die Leser Ihres Artikels mit weiteren Feinabstimmung ein wenig nützlich sein. Dann könnte der Indikator-Einstellungen universal für die meisten Symbole sein.
Hallo, mein guter Freund @Anil Varma.
Danke, dass Sie diesen einzigartigen Ansatz mit uns teilen! Ich werde ihn auf jeden Fall ausprobieren.
Hallo Freund
ich verfolge Ihre Artikel und sie sind informativ. Danke für das Teilen und Verbreiten von Wissen.
Ich habe versucht, 21Period ATR mehrere wie unten:
gTestProximity = (MathMax((75/_Digits),0.10*getATR(rates_total - 1))); // (n*getATR(index) ersetzt für ...InpTextProximity;
gMinDistance = (MathMax((150/_Digits),0.20*getATR(rates_total - 1))); // (n*getATR(index) ersetzt für ...InpMinWeakDistance;
Dies hat mir geholfen, SRZones für die beiden Paare EURUSD und XAUUSD zu erhalten, wobei die Werte zwischen 1,08000 und 3000,00 sehr unterschiedlich sind.
Kann für die Leser Ihres Artikels mit weiteren Feinabstimmung ein wenig nützlich sein. Dann könnte der Indikator-Einstellungen universal für die meisten Symbole sein.
Könnten Sie uns Ihre Version des ATR-Indikators mitteilen?
Hallo
Könnten Sie uns Ihre Version des ATR-Indikators mitteilen?
Hallo @Evgeny Fedorenko
Zunächst einmal entschuldige ich mich dafür, dass ich zu spät antworte, aber ich habe meine Aufmerksamkeit auf den Kurs Quant Financial Modeling gelenkt.
Zweitens habe ich keinen Indikator für mich selbst erstellt, sondern nur den Indikatorcode von Clemence Benjamin mit der in meinem Beitrag vorgeschlagenen Änderung ausprobiert.
Ich hoffe, das hilft Ihnen weiter.