
Aufbau eines Modells von Kerzen, Trend und Nebenbedingungen (Teil 2): Zusammenführung integrierter Indikatoren
Inhalt
- Einführung
- Ein Blick zurück in die Geschichte
- Identifizierung einiger Probleme mit dem derzeitigen System
- Versionierung unseres nächsten MQL5-Programms
- Erforschung gleitender Durchschnitte
- Einbindung gleitender Durchschnitte in unser Programm
- Erkundung des RSI
- Umsetzung der RSI
- Vergleich der Ergebnisse
- Schlussfolgerung
Einführung
MetaTrader 5 enthält mehrere integrierte Indikatoren, die Händlern einen erheblichen analytischen Vorteil auf dem Markt verschaffen. In diesem Artikel werden insbesondere zwei von ihnen behandelt: Gleitende Durchschnitte und Relative Stärke Index. Gleitende Durchschnitte werden häufig verwendet, um die Richtung eines Trends sowie potenzielle Unterstützungs- und Widerstandsniveaus zu ermitteln. Sie glätten die Preisdaten zu einer einzigen fließenden Linie und erleichtern so die Erkennung von Trends. Der Relative-Stärke-Index (RSI) hingegen ist ein Momentum-Oszillator, der die Geschwindigkeit und Veränderung von Kursbewegungen misst. Händler verwenden den RSI, um überkaufte und überverkaufte Marktbedingungen festzustellen, was ihnen helfen kann, fundiertere Handelsentscheidungen zu treffen. Durch die Kombination dieser beiden Indikatoren können Händler wertvolle Einblicke in Markttrends und potenzielle Einstiegs- und Ausstiegspunkte für ihre Trades gewinnen.
Hier finden Sie einige der häufig verwendeten integrierten Indikatoren in MetaTrader 5:
- Gleitende Durchschnitte
- Bollinger Bands
- Index der relativen Stärke
- MACD( Gleitender Durchschnitt Konvergenz Divergenz)
- Stochastik Oszillator
- Average True Range
- Ichimoku Kinko Hyo
- Fibonacci Rücksetzungsebenen
Durch die Verwendung von gleitenden Durchschnitten und dem Relative Strength Index in Verbindung mit anderen technischen Analyseinstrumenten können Händler eine umfassendere Handelsstrategie entwickeln. Durch die kontinuierliche Beobachtung der Marktbedingungen und die entsprechende Anpassung ihrer Strategien können Händler der Zeit voraus sein und profitable Gelegenheiten nutzen. Es ist wichtig, diszipliniert und geduldig zu bleiben, da der Handel unvorhersehbar und volatil sein kann. Indem sie gleitende Durchschnitte und den Relative Strength Index in ihre Analysen einbeziehen, können Händler ihren Entscheidungsprozess verbessern und ihre Erfolgschancen auf dem Markt erhöhen. Denken Sie daran, dass handeln eine Fähigkeit ist, die Zeit und Übung erfordert, um sie zu beherrschen. Daher ist es wichtig, dass Sie sich weiterhin dem Lernen und der Verbesserung Ihrer Handelsfähigkeiten widmen.
Ein Blick zurück in die Geschichte
Betrachten wir den nachstehenden Code, um die Leistung des Indikators anhand von historischen Daten zu bewerten, die mindestens einige tausend Balken umfassen. Kerzen-Charts sind für die Erkennung von Markttrends von entscheidender Bedeutung, da sie die Beziehung zwischen Eröffnungs-, Schluss-, Höchst- und Tiefstkursen für jeden Zeitraum veranschaulichen. Durch die Analyse vergangener Kursbewegungen können Händler die Trendrichtung und -stärke bestimmen und ihre Handelsstrategien entsprechend ausrichten. Historische Kerzen-Muster können wichtige Unterstützungs- und Widerstandsniveaus aufzeigen, an denen die Kurse häufig pausieren oder umkehren. Indem sie untersuchen, wie sich die Kurse in der Vergangenheit auf diesen Niveaus verhalten haben, können Händler zukünftige Kursbewegungen vorhersehen und effektive Einstiegs- und Ausstiegspunkte für ihre Handelsgeschäfte festlegen.Händler können historische Kerzen-Daten nutzen, um ihre Handelsstrategien zu testen und ihre Leistung in verschiedenen Marktszenarien zu messen. Durch das Testen von Handelsgeschäfte anhand historischer Daten können Händler die Wirksamkeit ihrer Strategien bewerten und die notwendigen Anpassungen vornehmen, um ihre Handelsergebnisse zu verbessern. Die Beschäftigung mit der Geschichte der Kerzencharts ist ein wesentlicher Bestandteil der technischen Analyse und bietet Händlern wertvolle Einblicke in Markttrends, -muster und -verhaltensweisen, die ihnen dabei helfen können, fundierte und profitable Handelsentscheidungen zu treffen.
Neben der Analyse historischer Kerzen-Muster können Händler auch technische Indikatoren verwenden, um ihr Verständnis der Marktdynamik weiter zu verbessern. Diese Indikatoren können helfen, potenzielle Einstiegs- und Ausstiegspunkte zu identifizieren und Signale für Trendumkehrungen oder -fortsetzungen zu liefern. Durch die Kombination der Erkenntnisse aus Kerzen-Charts mit den von Indikatoren generierten Signalen können Händler eine umfassendere Handelsstrategie entwickeln, die sowohl die Preisbewegung als auch die technische Analyse berücksichtigt. Dieser ganzheitliche Ansatz kann die Entscheidungsfindung verbessern und die Wahrscheinlichkeit erfolgreicher Handelsgeschäfte auf den dynamischen und sich ständig verändernden Finanzmärkten erhöhen.
Schauen wir uns diesen Teil an, der definiert, wie weit zurück unser Indikator in der Kerzen-Chart-Historie als Teil unseres Hauptcodes angezeigt werden soll:
#define PLOT_MAXIMUM_BARS_BACK 10000 //the integer value can be made higher expanding the gap you can visualize in history #define OMIT_OLDEST_BARS 50
Identifizierung einiger Probleme mit dem derzeitigen System
In diesem Stadium untersuchen wir die Signale, die der Trend Constraint Indicator auf dem Chart liefert. Obwohl die Einschränkung negative Signale erfolgreich herausgefiltert hat, gibt es immer noch Probleme mit trendabweichenden Signalen auf einer sehr kleinen visuellen Skala. Es ist wichtig, diese Signale zu eliminieren und sich auf echte Trendsignale zu konzentrieren. Dies unterstreicht die Notwendigkeit, integrierte Tools wie den gleitenden Durchschnitt und den RSI durch MQL5 zu nutzen. In den folgenden Abschnitten werden wir uns mit diesen Instrumenten näher befassen.
Abb. 1: Trend Constraint v1.00, Boom 500 Index
In den nächsten Abschnitten werden wir untersuchen, wie der gleitende Durchschnitt und der RSI unsere Trendanalyse verbessern und genauere Signale für die Entscheidungsfindung liefern können. Indem wir diese Instrumente in unsere Analyse einbeziehen, wollen wir die Gesamteffizienz unserer Handelsstrategie verbessern und bessere Ergebnisse auf dem Markt erzielen. Lassen Sie uns die Funktionalitäten und Vorteile dieser Tools näher betrachten, um unseren Handelsansatz zu optimieren.
Versionierung unseres nächsten MQL5-Programms
Sobald unsere MQL5-Reise beginnt, markiert jede abgeschlossene Etappe eine Version. Da wir unser Programm ständig um neue Funktionen erweitern, müssen wir auf eine neue Version umgestellt werden. Schauen wir uns an, wie wir das am Anfang unseres Codes machen. Nachfolgend sehen Sie unsere erste Version der Trend-Beschränkung in Code.
///Indicator Name: Trend Constraint #property copyright "Clemence Benjamin" #property link "https://mql5.com" #property version "1.00" #property description "A model that seek to produce sell signal when D1 candle is Bearish only and buy signal when it is Bullish"
Um unsere Version zu aktualisieren, müssen wir lediglich die Ziffern unter der Eigenschaft version in unserem Code ändern. In diesem Artikel wird unsere nächste Version des Trend Constraint beispielsweise 1.01 sein. Nachstehend finden Sie den aktualisierten Codeausschnitt, der zeigt, wie er im Hauptcode später im Artikel erscheinen wird.
///Indicator Name: Trend Constraint #property copyright "Clemence Benjamin" #property link "https://mql5.com" #property version "1.01" #property description "A model that seek to produce sell signal when D1 candle is Bearish only and buy signal when it is Bullish"
Gut gemacht! Auf diese Weise aktualisieren wir unser MQL5-Programm. Als Nächstes werden wir zu den Versionen 1.02, 1.03, 1.04 und so weiter übergehen.
Entdecken der gleitenden Durchschnitte
Die gleitenden Durchschnitte sind für die Darstellung von Markttrends von entscheidender Bedeutung und umfassen langsame und schnelle gleitende Durchschnitte. Das Kreuzen dieser beiden kann entweder eine Trendfortsetzung oder eine Trendumkehr anzeigen. In diesem Artikel habe ich einen geglätteten gleitenden Durchschnitt mit einer Periodenlänge von 7 im Vergleich zu einem wesentlich langsameren einfachen gleitenden Durchschnitt mit einer Periodenlänge von 400 verwendet, um bestimmte Off-Trend-Signale zu eliminieren. Dieser Ansatz ermöglichte eine genauere Darstellung des zugrunde liegenden Markttrends und filterte kurzfristige Schwankungen und Störungen heraus. Durch die Verwendung einer Kombination aus schnellen und langsamen gleitenden Durchschnitten war ich in der Lage, signifikante Trendänderungen zu erkennen und gleichzeitig Fehlsignale zu minimieren. Diese Methode hat sich bei der Erfassung der breiteren Marktbewegungen als effektiv erwiesen und liefert wertvolle Erkenntnisse für fundierte Handelsentscheidungen.
Der gleitende Durchschnitt ist ein weit verbreitetes Instrument der technischen Analyse, das die Preisdaten glättet, indem es einen ständig aktualisierten Durchschnittspreis bildet. Er hilft Händlern, Trends und potenzielle Umkehrpunkte zu erkennen. Das Konzept des gleitenden Durchschnitts wurde entwickelt, um die Auswirkungen kurzfristiger Schwankungen zu verringern und längerfristige Trends in der Preisentwicklung aufzuzeigen.
Die Verwendung gleitender Durchschnitte in der Finanzanalyse geht auf frühe technische Analysten wie Richard Donchian und George Marechal in der Mitte des 20. Jahrhunderts zurück.
Die Formel zur Berechnung eines einfachen gleitenden Durchschnitts (SMA) ist einfach:
SMA = (P1 + P2 ... + Pn)/n
wobei:
- SMA = Einfacher gleitender Durchschnitt
- P1,P2,...,Pn = Preis für die angegebenen Perioden (z.B. Schlusskurse)
- n = Anzahl der Perioden (z. B. Tage), über die die Durchschnittswerte berechnet werden.
Abb. 2: Gleitende Durchschnitte, EURUSD
Einbindung von gleitenden Durchschnitten in das Programm
Der langsamste gleitende Durchschnitt kann bei der Erkennung von Trendänderungen von Bedeutung sein. Dies zeigt sich darin, wie der Preis mit langsamen gleitenden Durchschnitten interagiert. Normalerweise testet der Kurs den langsamen gleitenden Durchschnitt mehrmals, bevor er den Trend fortsetzt oder ändert. Der langsame gleitende Durchschnitt folgt der aktuellen Kursbewegung. Auf diese Weise fungiert der langsame gleitende Durchschnitt als robustes Unterstützungs- oder Widerstandsniveau und spiegelt die Stärke des zugrunde liegenden Trends wider. Händler verwenden diesen Indikator häufig, um Trendumkehrungen oder -fortsetzungen zu bestätigen, da er mit seiner zeitlichen Verzögerung ein zuverlässiges Maß für die Marktstimmung darstellt. Durch die Beobachtung des Verhältnisses zwischen dem Kurs und dem langsamen gleitenden Durchschnitt können Anleger wertvolle Erkenntnisse über die Marktdynamik gewinnen und fundierte Handelsentscheidungen treffen.
Darüber hinaus kann die Fähigkeit des langsamen gleitenden Durchschnitts, Kursschwankungen zu glätten, den Händlern ein klareres Bild von der Gesamtrichtung des Marktes vermitteln. Indem sie sich auf die Konvergenz oder Divergenz zwischen dem Kurs und dem langsamen gleitenden Durchschnitt konzentrieren, können Anleger potenzielle Verschiebungen der Dynamik vorhersehen. Die Zuverlässigkeit dieses Indikators bei der Erfassung langfristiger Trends macht ihn zu einem wertvollen Instrument für Händler, die erhebliche Kursbewegungen abwarten und gleichzeitig kurzfristige Störungen herausfiltern möchten. Das Verständnis der Nuancen des langsam gleitenden Durchschnitts kann die Fähigkeit eines Händlers verbessern, die Komplexität der Finanzmärkte mit größerer Präzision und Zuversicht zu navigieren.
Im vorangegangenen Artikel haben wir einen D1 Trend Constraint Indicator mit 2 Puffern für Kauf und Verkauf entwickelt. Obwohl sie anfangs zufriedenstellend war, wollen wir nun ihre Wirksamkeit weiter verbessern. Ähnlich wie bei unseren früheren Arbeiten besteht der Code aus 2 Puffern. Unser Ziel ist es, die Ausgabe auf langsame gleitende Durchschnitte zu beschränken, um falsche Signale herauszufiltern. Langsam gleitende Durchschnitte spielen eine wichtige Rolle bei der Bestimmung von Trends. Die Beschränkung sieht vor, dass nur gekauft wird, wenn der Kurs über dem SMA 400 liegt, und nur verkauft wird, wenn er darunter liegt.
- Geglätteter einfacher gleitender Durchschnitt (SSMA) 7 zur Darstellung des Preises
- Einfacher gleitender Durchschnitt 400 zur Darstellung der Trenddurchsetzung
- MQL5-Code für die Bedingung.
///Indicator Name: Trend Constraint #property copyright "Clemence Benjamin" #property link "https://mql5.com" #property version "1.00" #property description "A model that seek to produce sell signal when D1 candle is Bearish only and buy signal when it is Bullish" //--- indicator settings #property indicator_chart_window #property indicator_buffers 2 #property indicator_plots 2 #property indicator_type1 DRAW_ARROW #property indicator_width1 5 #property indicator_color1 0xD42A00 #property indicator_label1 "Buy" #property indicator_type2 DRAW_ARROW #property indicator_width2 5 #property indicator_color2 0x0000D4 #property indicator_label2 "Sell" #define PLOT_MAXIMUM_BARS_BACK 5000 #define OMIT_OLDEST_BARS 50 //--- indicator buffers double Buffer1[]; double Buffer2[]; double myPoint; //initialized in OnInit int MA_handle; double MA[]; int MA_handle2; double MA2[]; double Open[]; double Close[]; int MA_handle3; double MA3[]; int MA_handle4; double MA4[]; double Low[]; double High[]; void myAlert(string type, string message) { if(type == "print") Print(message); else if(type == "error") { Print(type+" | Trend Constraint @ "+Symbol()+","+IntegerToString(Period())+" | "+message); } else if(type == "order") { } else if(type == "modify") { } } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { SetIndexBuffer(0, Buffer1); PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1)); PlotIndexSetInteger(0, PLOT_ARROW, 241); SetIndexBuffer(1, Buffer2); PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1)); PlotIndexSetInteger(1, PLOT_ARROW, 242); //initialize myPoint myPoint = Point(); if(Digits() == 5 || Digits() == 3) { myPoint *= 10; } MA_handle = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_EMA, PRICE_CLOSE); if(MA_handle < 0) { Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } MA_handle2 = iMA(NULL, PERIOD_CURRENT, 21, 0, MODE_EMA, PRICE_CLOSE); if(MA_handle2 < 0) { Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } MA_handle3 = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_SMMA, PRICE_CLOSE); if(MA_handle3 < 0) { Print("The creation of iMA has failed: MA_handle3=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } MA_handle4 = iMA(NULL, PERIOD_CURRENT, 400, 0, MODE_SMA, PRICE_CLOSE); if(MA_handle4 < 0) { Print("The creation of iMA has failed: MA_handle4=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } 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[]) { int limit = rates_total - prev_calculated; //--- counting from 0 to rates_total ArraySetAsSeries(Buffer1, true); ArraySetAsSeries(Buffer2, true); //--- initial zero if(prev_calculated < 1) { ArrayInitialize(Buffer1, EMPTY_VALUE); ArrayInitialize(Buffer2, EMPTY_VALUE); } else limit++; datetime TimeShift[]; if(CopyTime(Symbol(), PERIOD_CURRENT, 0, rates_total, TimeShift) <= 0) return(rates_total); ArraySetAsSeries(TimeShift, true); int barshift_M1[]; ArrayResize(barshift_M1, rates_total); int barshift_D1[]; ArrayResize(barshift_D1, rates_total); for(int i = 0; i < rates_total; i++) { barshift_M1[i] = iBarShift(Symbol(), PERIOD_M1, TimeShift[i]); barshift_D1[i] = iBarShift(Symbol(), PERIOD_D1, TimeShift[i]); } if(BarsCalculated(MA_handle) <= 0) return(0); if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) <= 0) return(rates_total); ArraySetAsSeries(MA, true); if(BarsCalculated(MA_handle2) <= 0) return(0); if(CopyBuffer(MA_handle2, 0, 0, rates_total, MA2) <= 0) return(rates_total); ArraySetAsSeries(MA2, true); if(CopyOpen(Symbol(), PERIOD_M1, 0, rates_total, Open) <= 0) return(rates_total); ArraySetAsSeries(Open, true); if(CopyClose(Symbol(), PERIOD_D1, 0, rates_total, Close) <= 0) return(rates_total); ArraySetAsSeries(Close, true); if(BarsCalculated(MA_handle3) <= 0) return(0); if(CopyBuffer(MA_handle3, 0, 0, rates_total, MA3) <= 0) return(rates_total); ArraySetAsSeries(MA3, true); if(BarsCalculated(MA_handle4) <= 0) return(0); if(CopyBuffer(MA_handle4, 0, 0, rates_total, MA4) <= 0) return(rates_total); ArraySetAsSeries(MA4, true); if(CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total); ArraySetAsSeries(Low, true); if(CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total); ArraySetAsSeries(High, true); //--- main loop for(int i = limit-1; i >= 0; i--) { if (i >= MathMin(PLOT_MAXIMUM_BARS_BACK-1, rates_total-1-OMIT_OLDEST_BARS)) continue; //omit some old rates to prevent "Array out of range" or slow calculation if(barshift_M1[i] < 0 || barshift_M1[i] >= rates_total) continue; if(barshift_D1[i] < 0 || barshift_D1[i] >= rates_total) continue; //Indicator Buffer 1 if(MA[i] > MA2[i] && MA[i+1] < MA2[i+1] //Moving Average crosses above Moving Average && Open[barshift_M1[i]] >= Close[1+barshift_D1[i]] //Candlestick Open >= Candlestick Close && MA3[i] > MA4[i] //Moving Average > Moving Average ) { Buffer1[i] = Low[i]; //Set indicator value at Candlestick Low } else { Buffer1[i] = EMPTY_VALUE; } //Indicator Buffer 2 if(MA[i] < MA2[i] && MA[i+1] > MA2[i+1] //Moving Average crosses below Moving Average && Open[barshift_M1[i]] <= Close[1+barshift_D1[i]] //Candlestick Open <= Candlestick Close && MA3[i] < MA4[i] //Moving Average < Moving Average ) { Buffer2[i] = High[i]; //Set indicator value at Candlestick High } else { Buffer2[i] = EMPTY_VALUE; } } return(rates_total); } //Thank you for following along this is ready to compile
Erforschung des RSI-Oszillators
Der RSI hilft bei der Identifizierung von Extremzonen des Marktes, einschließlich überkaufter und überverkaufter Bereiche. Dies kann für Händler nützlich sein, die potenzielle Umkehrpunkte oder Gelegenheiten zur Trendfortsetzung ermitteln möchten. Durch die Verwendung des RSI in Verbindung mit anderen technischen Indikatoren und Analysemethoden können Händler fundiertere Entscheidungen treffen, wenn sie in den Handel einsteigen oder diesen beenden. Darüber hinaus kann der RSI auch verwendet werden, um die Stärke eines Trends zu bestätigen oder um Divergenzen zwischen Preis und Dynamik zu erkennen, die auf einen potenziellen Richtungswechsel hindeuten können. Händler sollten sich nicht ausschließlich auf den RSI verlassen, sondern immer auch andere Faktoren wie die Marktbedingungen, Nachrichten und die allgemeine Marktstimmung berücksichtigen, bevor sie Handelsentscheidungen treffen. Es ist wichtig, sich daran zu erinnern, dass kein einzelner Indikator narrensicher ist und dass für erfolgreiche Handelsstrategien oft eine Kombination von Instrumenten und Analysen erforderlich ist.
Die nachstehende Formel für den RSI geht auf J. Welles Wilder Jr. zurück, der das Konzept 1978 einführte.
RSI = 100 - (100/(1+RS))
wobei:
- RS = Durchschnittlicher Anstieg / Durchschnittlicher Abstieg
- Durchschnittlicher Anstieg = Summe der Zuwächse der angegebenen Perioden / Anzahl der Perioden
- Durchschnittlicher Abstieg = Summe der Rückgänge der angegebenen Perioden / Anzahl der Perioden
Abb. 3: RSI-Niveaus, Boom 500 Index
Umsetzung des RSI
Es kann sehr nützlich sein, RSI-Niveaus im Code zu identifizieren und sie mit den Haupttrends in Einklang zu bringen. In diesem Abschnitt werden wir die RSI-Bedingungen in unser MQL5-Indikatorprogramm integrieren. Die Einbeziehung der RSI-Bedingungen in unser MQL5-Indikatorprogramm ermöglicht es uns, Markttrends besser zu analysieren und fundiertere Handelsentscheidungen zu treffen. Indem wir die RSI-Werte mit den Haupttrends abgleichen, können wir potenzielle Einstiegs- und Ausstiegspunkte mit größerer Genauigkeit identifizieren und so die Wirksamkeit unserer Handelsstrategie erhöhen. Früher haben wir uns auf das Kreuzen des gleitenden Durchschnitts als Einstiegsbedingung verlassen. Jetzt entfernen wir den MA-Crossover und verwenden stattdessen RSI-Levels für den Einstieg, zusammen mit anderen kürzlich aufgenommenen Bedingungen, um eine neue Version, Trend Constrain V1.02, zu erstellen.
In diesem Stadium müssen wir Eingaben für den RSI-Wert machen, um die überkauften und überverkauften Zonen zu optimieren. Prüfen Sie den unten stehenden Code.
input double Oversold = 30; input double Overbought = 70; //I have set the default standard values, but you can alter them to suit your strategy and instrument being traded.
Lassen Sie uns nun diese RSI-Bedingungen in unseren Code implementieren, um die Funktionalität unseres Indikators zu verbessern. Beginnen wir damit, die RSI-Stufen zu definieren, die wir in unserem Indikator verwenden wollen. Wir können das überkaufte Niveau auf 70 und das überverkaufte Niveau auf 30 setzen. Dies wird uns helfen, potenzielle Umkehrpunkte auf dem Markt zu erkennen. Als Nächstes fügen wir unserem Code die notwendige Logik hinzu, um diese RSI-Bedingungen zu prüfen und entsprechende Signale zu erzeugen. Dadurch erhalten wir einen umfassenderen Überblick über die Marktdynamik und können fundiertere Handelsentscheidungen treffen. Fahren wir mit der Implementierung dieser Änderungen in unserem MQL5-Indikatorprogramm fort.
///Indicator Name: Trend Constraint #property copyright "Clemence Benjamin" #property link "https://mql5.com" #property version "1.02" #property description "A model that seek to produce sell signal when D1 candle is Bearish only and buy signal when it is Bullish" ///--- indicator settings #property indicator_chart_window #property indicator_buffers 2 #property indicator_plots 2 #property indicator_type1 DRAW_ARROW #property indicator_width1 5 #property indicator_color1 0xFF3C00 #property indicator_label1 "Buy" #property indicator_type2 DRAW_ARROW #property indicator_width2 5 #property indicator_color2 0x0000FF #property indicator_label2 "Sell" #define PLOT_MAXIMUM_BARS_BACK 5000 #define OMIT_OLDEST_BARS 50 //--- indicator buffers double Buffer1[]; double Buffer2[]; input double Oversold = 30; input double Overbought = 70; double myPoint; //initialized in OnInit int RSI_handle; double RSI[]; double Open[]; double Close[]; int MA_handle; double MA[]; int MA_handle2; double MA2[]; double Low[]; double High[]; void myAlert(string type, string message) { if(type == "print") Print(message); else if(type == "error") { Print(type+" | Trend Constraint V1.02 @ "+Symbol()+","+IntegerToString(Period())+" | "+message); } else if(type == "order") { } else if(type == "modify") { } } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { SetIndexBuffer(0, Buffer1); PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1)); PlotIndexSetInteger(0, PLOT_ARROW, 241); SetIndexBuffer(1, Buffer2); PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1)); PlotIndexSetInteger(1, PLOT_ARROW, 242); //initialize myPoint myPoint = Point(); if(Digits() == 5 || Digits() == 3) { myPoint *= 10; } RSI_handle = iRSI(NULL, PERIOD_CURRENT, 14, PRICE_CLOSE); if(RSI_handle < 0) { Print("The creation of iRSI has failed: RSI_handle=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } MA_handle = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_SMMA, PRICE_CLOSE); if(MA_handle < 0) { Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } MA_handle2 = iMA(NULL, PERIOD_CURRENT, 400, 0, MODE_SMA, PRICE_CLOSE); if(MA_handle2 < 0) { Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } 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[]) { int limit = rates_total - prev_calculated; //--- counting from 0 to rates_total ArraySetAsSeries(Buffer1, true); ArraySetAsSeries(Buffer2, true); //--- initial zero if(prev_calculated < 1) { ArrayInitialize(Buffer1, EMPTY_VALUE); ArrayInitialize(Buffer2, EMPTY_VALUE); } else limit++; datetime TimeShift[]; if(CopyTime(Symbol(), PERIOD_CURRENT, 0, rates_total, TimeShift) <= 0) return(rates_total); ArraySetAsSeries(TimeShift, true); int barshift_M1[]; ArrayResize(barshift_M1, rates_total); int barshift_D1[]; ArrayResize(barshift_D1, rates_total); for(int i = 0; i < rates_total; i++) { barshift_M1[i] = iBarShift(Symbol(), PERIOD_M1, TimeShift[i]); barshift_D1[i] = iBarShift(Symbol(), PERIOD_D1, TimeShift[i]); } if(BarsCalculated(RSI_handle) <= 0) return(0); if(CopyBuffer(RSI_handle, 0, 0, rates_total, RSI) <= 0) return(rates_total); ArraySetAsSeries(RSI, true); if(CopyOpen(Symbol(), PERIOD_M1, 0, rates_total, Open) <= 0) return(rates_total); ArraySetAsSeries(Open, true); if(CopyClose(Symbol(), PERIOD_D1, 0, rates_total, Close) <= 0) return(rates_total); ArraySetAsSeries(Close, true); if(BarsCalculated(MA_handle) <= 0) return(0); if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) <= 0) return(rates_total); ArraySetAsSeries(MA, true); if(BarsCalculated(MA_handle2) <= 0) return(0); if(CopyBuffer(MA_handle2, 0, 0, rates_total, MA2) <= 0) return(rates_total); ArraySetAsSeries(MA2, true); if(CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total); ArraySetAsSeries(Low, true); if(CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total); ArraySetAsSeries(High, true); //--- main loop for(int i = limit-1; i >= 0; i--) { if (i >= MathMin(PLOT_MAXIMUM_BARS_BACK-1, rates_total-1-OMIT_OLDEST_BARS)) continue; //omit some old rates to prevent "Array out of range" or slow calculation if(barshift_M1[i] < 0 || barshift_M1[i] >= rates_total) continue; if(barshift_D1[i] < 0 || barshift_D1[i] >= rates_total) continue; //Indicator Buffer 1 if(RSI[i] < Oversold && RSI[i+1] > Oversold //Relative Strength Index crosses below fixed value && Open[barshift_M1[i]] >= Close[1+barshift_D1[i]] //Candlestick Open >= Candlestick Close && MA[i] > MA2[i] //Moving Average > Moving Average ) { Buffer1[i] = Low[i]; //Set indicator value at Candlestick Low } else { Buffer1[i] = EMPTY_VALUE; } //Indicator Buffer 2 if(RSI[i] > Overbought && RSI[i+1] < Overbought //Relative Strength Index crosses above fixed value && Open[barshift_M1[i]] <= Close[1+barshift_D1[i]] //Candlestick Open <= Candlestick Close && MA[i] < MA2[i] //Moving Average < Moving Average ) { Buffer2[i] = High[i]; //Set indicator value at Candlestick High } else { Buffer2[i] = EMPTY_VALUE; } } return(rates_total); } // Thank you for following along we are here
Vergleich der Ergebnisse
Nach der Überprüfung des vorherigen Artikels haben wir erhebliche Fortschritte bei der Erstellung eines klaren Charts mit der Anzahl der dargestellten Signale gemacht. Der RSI und die gleitenden Durchschnitte haben sich positiv auf unsere Ergebnisse ausgewirkt und dienen als visuelle Indikatoren zur Überwachung von Trendänderungen. Unser Kerzen-Trendindikator mit höherem Zeitrahmen hat ebenfalls Verbesserungen gezeigt. Darüber hinaus hat die Einbeziehung des SMA-400-Indikators weitere Einblicke in potenzielle Marktumkehrungen ermöglicht, was die Genauigkeit unserer Analysen insgesamt erhöht hat. Durch die Kombination dieser verschiedenen Signale sind wir besser in der Lage, fundierte Handelsentscheidungen zu treffen und uns an die sich verändernden Marktbedingungen anzupassen. Ich bin begeistert von den Fortschritten, die wir gemacht haben, und werde mich weiterhin dafür einsetzen, diese Strategie zu verfeinern, um in Zukunft noch bessere Ergebnisse zu erzielen.
Abb. 4: Trend Constraint v1.02, Boom 500 Index
Das obige Bild geht auf den Anfang des Artikels zurück, als wir einige Probleme mit dem derzeitigen System aufzeigten
Abb. 5: Trend Constraint v1.02, Boom 500 Index
Schlussfolgerung
Der Kerzen-Indikator „Trend Constraint“ kann gleitende Durchschnitte nicht ersetzen, aber er kann sie ergänzen, um hervorragende Ergebnisse zu erzielen. Die in MT5 integrierten Indikatoren dienen als Grundlage für die Erstellung weiterer nutzerdefinierter Indikatoren. In Kombination können diese Instrumente sehr wirksam sein. Wir sind in eine neue Phase dieser Entwicklung eingetreten und sehen uns nun mit Problemen im Zusammenhang mit Gewichten und Erfrischungen konfrontiert, die Aufmerksamkeit erfordern. Unser nächster Artikel wird sich auf die Bewältigung dieser Herausforderungen konzentrieren, während wir das System weiter verfeinern.
Siehe Algobook
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/14803





- 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.