
Zeichnen von Widerstands- und Unterstützungsebenen mithilfe von MQL5
Inhaltsverzeichnis
- Einleitung
- Ziel dieses Beitrags
- Kurze Beschreibung von früher vorgestellten Methoden zum Zeichnen von Unterstützungs- und Widerstandsebenen
- Prinzip des Findens von Extrema
- Funktion zum Finden des extremen Balkens mit dem geringsten Index (erster Balken) Ext_1
- Allgemeine Funktion zum Finden aller nachfolgenden Extrema Ext_2
- Verarbeitung der Ergebnisse
- Beispiel eines Indikators, der Unterstützungs- und Widerstandsebenen anzeigt
- Fazit
Einleitung
Zuerst möchte ich Ihnen kurz erklären, was Unterstützungs- und Widerstandslinien sind, wie sie aufgebaut werden und wie ich sie für den Handel nutze.
Alle Trendfiguren, -linien und -modelle sind Kombinationen aus Unterstützungs- und Widerstandslinien, die der klassischen Trendanalyse zugrunde liegen. Die Widerstandslinie basiert auf maximalen Preisen, die auftreten, wenn Händler ("Bullen") aufhören, eine Währung zu einem höheren Preis zu kaufen, und anfangen, offene Positionen zum Kauf zu schließen. Der Preis eines Finanzinstruments reagiert darauf mit einen Zurückfallen, bis eine ähnliche Situation unter "Bären" eintritt, d. h. die Unterstützungslinie auf Mindestpreisen aufgebaut wird.
Somit kann angenommen werden, dass Maxima entstehen, wenn eine Währung überkauft wird, und Minima, wenn sie überverkauft wird. Aus diesem Grund nutze ich zum Zeichnen von Unterstützungs- und Widerstandslinien einen Standardindikator aus dem Satz von MetaTrader: Relative Strength Index (RSI), der 1978 von John Wilder entwickelt und publiziert wurde. Dieser Indikator bestimmt überkaufte und überverkaufte Zonen einer Währung.
Ich nutze den Indikator RSI mit der Periode 8. Dieser Wert ist nicht das Ergebnis meiner Beobachtungen, sondern wurde von Eric L. Nyman in seinem Buch "The Small Trader's Encyclopedia" für alle Diagrammzeiträume außer Tages- und größeren Diagrammen empfohlen. Ich bin mit den Ergebnissen der Arbeit meines Indikators mit RSI (8) absolut zufrieden.
Es gibt zwei unterschiedliche Meinungen darüber, ob Kerzendochte bei der Suche nach maximalen und minimalen Preisen (High und Low) berücksichtigt werden sollten. Ich persönlich berücksichtige sie und vergleiche High-Preise mit Low-Preisen, wenn ich nach Extrema suche. Wenn Sie sie nicht berücksichtigen möchten, können sie einfach einige kleine Veränderungen am weiter unten vorgestellten Indikatorcode vornehmen.
Der Handel mit Unterstützungs- und Widerstandslinien kann genauso außerhalb dieser Linien stattfinden wie bei Preisschwankungen innerhalb des durch diese Linien gebildeten Bereichs.
Abb. 1. Kaufsignal
Ich betrachte die zweite Methode als weniger wirksam, insbesondere, wenn das Zurückfallen des Preises von einer der Linien eine wichtige Rolle für das Treffen von Handelsentscheidungen spielt. In Abbildung 1 sieht man die Situation, dass der Preis nach einem Zurückfallen von der Widerstandslinie die Unterstützungslinie nicht erreicht, umkehrt und durch die Widerstandslinie bricht. Dadurch wird ein Kaufsignal stärker. Mit der Analyse der Winkel, die durch Linien gebildet werden, die die Zeitachse überkreuzen, definieren wir eine allgemeine Trendrichtung. Wenn der Preis des Finanzinstruments eine der Linien überkreuzt, ermöglicht dies einen Rückschluss bezüglich einer Stärkung oder Umkehrung des vorhandenen Trends. Häufig erreicht der Preis, bevor er beispielsweise die Unterstützungslinie überkreuzt, nur die Mitte der Unterstützungslinie (dieser Faktor verstärkt ein Handelssignal).
Ex existiert eine Plattform namens "Autochartist", die für die Erkennung von Trendfiguren und -modellen vorgesehen ist. Als Experiment habe ich zwei Monate lang auf einem Demokonto mit Signalen des Zurückfallens des Preises vom Widerstands- oder Unterstützungsniveau gehandelt. Die meisten Transaktionen wurden dabei im Gegensatz zu Handelssignalen aus Durchbruchsniveaus mit einem Verlust abgeschlossen.
Unterstützungs- und Widerstandsebenen werden ebenfalls zum Bestimmen der Beschleunigung oder Verlangsamung von Trends verwendet. Erhöht sich der Winkel einer Trendlinie in einem haussierenden Trend, bedeutet das eine Beschleunigung, deren Auftreten zu einer Fortführung des Trends führt. Andererseits bedeutet die Erhöhung des Winkels in einem baissierenden Trend, dass sich der Trend verlangsamt. Eine Unterstützungslinie (auf Basis von Low-Preisen) dient als Trendlinie bei einem haussierenden Trend und eine Widerstandslinie (auf Basis von High-Preisen) als Trendlinie bei einem baissierenden Trend.
Abb. 2. Verlangsamung eines haussierenden Trends
Abb. 3. Verlangsamung eines baissierenden Trends
Die Verlangsamung eines Trends kann auf seine zeitnahe Umkehrung hindeuten.
Ziel dieses Beitrags
Die Analyse von grafischen Figuren, die durch Unterstützungs- und Widerstandslinien geformt werden, ist eine der ältesten Methoden der technischen Analyse. Aus eigener Erfahrung auf dem Devisenmarkt kann ich festhalten, dass diese Methode nicht nur alt ist, sondern auch wirksam. Ich glaube, dass sie von vielen Händlern genutzt wird. Der manuelle Aufbau von Unterstützungs- und Widerstandslinien mit dem MetaTrader 5 Terminal ist eine einfache Aufgabe für jeden Händler, der über etwas theoretisches Wissen verfügt. Doch das gilt nicht für die Erstellung eines Programms, das diese Linien automatisch zeichnet.
In diesem Beitrag möchte ich meine eigene Methode zum Zeichnen von Unterstützungs- und Widerstandslinien vorstellen, die sowohl in MQL5 als auch in MQL4 umgesetzt werden kann. Ich hoffe, dass Sie diese Informationen nützlich finden werden.
Kurze Beschreibung von früher vorgestellten Methoden zum Zeichnen von Unterstützungs- und Widerstandsebenen
Gebote für Währungspaare befinden sich die meiste Zeit über innerhalb der Unterstützungs- und Widerstandslinien. Diese Tatsache liegt dem Beitrag von Gleb Slobodow zum Zeichnen dieser Linien zugrunde. Somit haben wir zwei horizontale Ebenen, die einen Bereich von Preisschwankungen definieren. Der Durchbruch einer dieser Linien gibt uns vermutlich ein Signal zum Kaufen oder Verkaufen. Allerdings hat das vorgestellte Prinzip einige Nachteile:
- Die Anzahl der zu analysierenden Balken wird manuell festgelegt. Dieser Parameter definiert einen Preisbereich und somit den Wert von Unterstützungs- und Widerstandsebenen.
- Der Prozess zum Zeichnen der Ebenen ist nicht vollautomatisiert und bietet somit nicht die Möglichkeit, ein automatisiertes Handelssystem zu erstellen.
- Mithilfe dieser Methode erhalten wir horizontale Ebenen, die uns nicht die Analyse der Richtung und Stärke des Trends ermöglichen.
Der in Igor Geraskos Handelsstrategie verwendete Indikator von Unterstützungs- und Widerstandsebenen definiert ebenfalls horizontale Ebenen.
In diesem Beitrag möchte ich Ihnen ein Prinzip des Zeichnens von Unterstützungs- und Widerstandslinien vorstellen, das die Bestimmung der Trendrichtung und die Entstehung von Trendmodellen und -figuren ermöglicht. Die Linien werden basierend auf absoluten Minima und Maxima gezeichnet.
Prinzip des Findens von Extrema
Die Bestimmung von Maximal- und Minimalpreisen in einem bestimmten Zeitraum ist kein Problem. Es ist wichtig, die Länge des zu analysierenden Diagrammabschnitts (Zeitintervall) richtig zu wählen, die sich ständig ändert und somit nicht manuell festgelegt werden kann. Um diesen Abschnitt des Währungsdiagramms zu finden, nutze ich den Indikator Relative Strength Index (RSI), der im Standard-Indikatorensatz des MetaTrader 5 Terminals enthalten ist.
Überkaufte und überverkaufte Ebenen werden gemäß den Ebenen des RSI-Indikators bestimmt. Zu diesen Zeitpunkten weicht das Diagramm unserer Währungspaare von seiner Richtung (seinem Trend) ab und erzeugt ein Zurückfallen des Preises. Extrema werden insbesondere hier geformt. In diesen Lücken suchen wir nach den Minimal- und Maximalpreisen.
Als überverkaufte Ebene nehme ich den Wert 35 des RSI-Indikators, als überkaufte Ebene 65 (die obere und untere Ebene sind von der Mitte des RSI = 50 gleich weit entfernt). Der Zeitraum des RSI-Indikators entspricht 8.
Beachten Sie, dass während eines starken Trends, beispielsweise eines steigenden Trends, der RSI häufig mehrfach die obere Ebene überkreuzt, die untere allerdings nicht erreicht. Dies macht eine Anpassung der Ebene erforderlich, die nicht der Trendrichtung entspricht.
Abb. 4. Suchbereiche für Extrema
In der obigen Abbildung habe ich einen Suchbereich für Balken mit Extrema bestimmt – jeweils des ersten, zweiten, dritten und vierten mit den Zahlen 1, 2, 3, und 4. Vor der Überkreuzung einer Untergrenze (RSI = 35) wird der RSI-Indikator ab dem aktuellen Balken dreimal im überkauften Bereich (RSI >= 65) eingefügt. Somit entstehen drei Zeitintervalle für die Suche nach dem ersten Extremum. Im weiteren Verlauf werden nacheinander Suchzonen für drei aufeinanderfolgende Balken bestimmt.
In den Zonen 1 und 3 suche ich nach Balken mit den höchsten Preisen und in den Zonen 2 und 4 Balken mit den niedrigsten Preisen. Somit erhalten wir 4 Extrema. Indem wir sie mit Strahlen kombinieren, erhalten wir den aufsteigenden Preiskanal.
Abb. 5 Aufsteigender Kanal
Vermutlich ist ihnen aufgefallen, dass an der Suche nach den Mindestpreisen nur 4 Balken (2 je Zone) beteiligt waren. Aufgrund des vorherrschenden Aufwärtstrends hat der RSI-Indikator das Minimum kaum berührt, während der Indikator sich fast genauso lange außerhalb von RSI = 65 befand wie innerhalb des Kanals 35 < RSI < 65. Deshalb wird der Indikatorcode, den ich in diesem Beitrag zum Finden der Punkte 2 und 4 vorgestellt habe, die zur Mitte (in Richtung 50) verschobene RSI-Ebene nutzen. Je nachdem, was das erste Extremum war (Minimum oder Maximum), wird eine hohe oder niedrige RSI-Ebene festgelegt.
Alle Währungspaare und alle Zeiträume des Diagramms der RSI-Werte und des Werts der nachfolgenden Abweichung werden experimentell ausgewählt. Ich betrachte dies als Nachteil meines Systems zum Bestimmen von Extrema.
Funktion zum Finden des extremen Balkens mit dem geringsten Index (erster Balken) Ext_1
Die Funktion zum Finden von extremen Balken, die ich "Ext_1" genannt habe, hat die folgenden Eingabeparameter:
int Ext_1(double low, //low RSI level, oversold level double high, //high RSI level, overbought level int bars, //number of analyzed bars, to avoid copying unnecessary data //possible to set bars = 300 int h_rsi, //handle of RSI indicator string symbol, //symbol of chart float distans, //distance for deviation of one of indicator levels //allows to define search boundaries of first extremum bar ENUM_TIMEFRAMES period_trade) //period of chart
Die ersten beiden Eingabeparameter der Funktion sind die Parameter des RSI-Indikators. Sie spielen bei der Berechnung der Indikatorlinie keine Rolle und werden nur für eine praktische optische Bewertung der Werte verwendet (Lage der Indikatorlinie in Bezug auf die angegebenen Ebenen). Ich nutze diese Ebenen zum Bestimmen von Preisbereichen, unter denen ich nach den Minimal- und Maximalwerten suchen werde. Die Parameter "low" und "high" erhalten Werte von entsprechenden externen Variablen, die im Indikatorcode auf globaler Ebene eingegeben wurden:
input double Low_RSI = 35.0; // Low RSI level for finding extremum input double High_RSI= 65.0; // High RSI level for finding extremum
Der Eingabeparameter "bars" legt die Anzahl der Elemente fest, die in die Arrays kopiert werden, die die Preise "Low" und "High" der Balken sowie die Werte des RSI-Indikators beinhalten:
double m_rsi[],m_high[],m_low[]; //initialization of arrays int h_high = CopyHigh(symbol, period_trade, 0, bars, m_high); //fill array of high candle prices int h_low = CopyLow(symbol, period_trade, 0, bars, m_low); //fill array of low candle prices if(CopyBuffer(h_rsi, 0, 0, bars, m_rsi)<bars) //fill array with indicator RSI data { Print("Failed to copy indicator buffer!"); }
Die Arrays m_rsi[], m_high[] und m_low[] haben eine umgekehrte Indexierungsreihenfolge:
ArraySetAsSeries(m_rsi,true); ArraySetAsSeries(m_high,true); ArraySetAsSeries(m_low,true);
Wie ich bereits erwähnt habe, nimmt die Linie des RSI-Indikators, die einen Wertebereich von 0 bis 100 hat, bei einem vorherrschenden haussierenden Trend meistens einen Wert > 50 an. Wenn Minima geformt werden, liegt der RSI-Wert weiter vom Mittelpunkt (50) entfernt als bei der Entstehung des Maximums. Deshalb muss bei der Überkreuzung eines der Indikatorwerte (low oder high) ein anderer Wert näher an den Mittelpunkt verschoben werden. Die Höhe der Abweichung wird durch den Eingabeparameter "distans" bestimmt, der den Wert einer externen Variable erhält:
input float Distans=13.0; // Deviation of RSI level
Der Eingabeparameter "h_rsi" der Funktion "Ext_1" erhält den Wert des RSI-Handles, der aus der Initialisierung des Indikators mithilfe der Funktion iRSI() entsteht:
h_RSI=iRSI(Trade_Symbol,Period_Trade,Period_RSI,PRICE_CLOSE); //return handle of RSI indicator
Die Variablen Trade_Symbol und Period_Trade werden auf globaler Ebene initialisiert und enthalten Informationen über das Währungspaar bzw. den Zeitraum des Diagramms. Die Variable Period_RSI enthält den Wert des Zeitraums des Indikators RSI, der in den externen Parametern meines Indikators festgelegt ist:
input uchar Period_RSI =8; // RSI period
Sobald wir die Arrays mit den Preisen der High- und Low-Balken sowie den Wert des Indikators RSI gemäß diesen Balken erzeugt und befüllt haben, können wir mit der tatsächlichen Suche nach dem ersten Extremum fortfahren. Um zu bestimmen, wo sich die ersten Extrema befinden (Unterstützungs- oder Widerstandslinie), und um die Analyse der Balken zum richtigen Zeitpunkt anzuhalten, werden zwei Variablen des Typen bool benötigt:
bool ext_max = true; //bool type variables are used to stop bool ext_min = true; //bar analysis at the right time
Der Wert ext_max = true ermöglicht die Suche nach dem maximalen Extremum, der Wert ext_min = true dementsprechend die Suche nach dem minimalen Extremum. Bei der ersten Überkreuzung des RSI-Indikators durch eine der Ebenen (low oder high) ändert sich der Wert einer der bool-Variablen zu false. Die Überkreuzung der RSI-Ebene, für die die Analyse der Balken deaktiviert ist, bedeutet, dass die erforderliche Anzahl von Balken analysiert und das erste Extremum gefunden wurde.
Wenn der Wert des RSI-Indikators bei der Analyse des ersten Balkens außerhalb einer seiner Ebenen liegt, ist es wahrscheinlich, dass die Formierung des Preisbereichs, in dem das Extremum gesucht werden soll, noch nicht abgeschlossen ist. In diesem Fall ist es nicht zielführend, ihn zu analysieren. Die Analyse solcher Balken sollte ausgeschlossen werden. In der nachfolgenden Abbildung habe ich den Preisbereich gekennzeichnet, in dem keine Analyse durchgeführt wird (beachten Sie die Position der Linie des RSI-Indikators in Relation zur oberen Ebene):
Abb. 6. Deaktivieren der Analyse im unvollständigen Preisbereich
Zur Umsetzung dieser Vorgehensweise muss eine weitere Variable des Typen bool erstellt werden:
bool flag=false;
Um Höchst- und Mindestpreise unter den zu analysierenden Balken zu bestimmen, müssen die folgenden zusätzlichen Variablen des Typen double erstellt werden:
double min = 100000.0; //variables to identify maximum and minimum prices double max = 0.0; //...
Die gesamte Schleife für die Suche nach dem Balken mit dem ersten Extremum sieht so aus:
for(int i=0;i<bars;i++) //bar loop { double rsi = m_rsi[i]; //get RSI indicator value double price_max = NormalizeDouble(m_high[i], digits); //High prices double price_min = NormalizeDouble(m_low[i], digits); //Low prices of selected bar if(flag==false) //condition to avoid searching for extremum on incomplete trend { if(rsi<=low||rsi>=high) //if first bars in overbought zones or oversold zones, continue; //then move to next bar else flag = true; //if not, proceed with analysis } if(rsi<low) //if found crossing of RSI with low level { if(ext_min==true) //if RSI hasn't crossed high level { if(ext_max==true) //if searching for maximum extremum hasn't been disabled { ext_max=false; //then disable searching for maximum extremum if(distans>=0) high=high-distans; //change high level, on which then } //second bar search will be executed if(price_min<min) //search and memorise first bar index { //comparing Low candle prices min=price_min; index_bar=i; } } else break; /*Exit loop since searching for minimum extremum is already disabled, it means the maximum is found*/ } if(rsi>high) //further, algorithm is the same, only in search for maximum extremum { if(ext_max==true) { if(ext_min==true) { ext_min=false; if(distans>=0) low=low+distans; } if(price_max>max) { max=price_max; index_bar=i; } } else break; /*Exit loop since searching for maximum extremum is disabled, it means the minimum is found*/ } }
Allgemeine Funktion zum Finden aller nachfolgenden Extrema Ext_2
Diese Funktion erhält die gleichen Eingabeparameter wie die Funktion Ext_1 sowie drei weitere wichtige Parameter:
- Den Parameter, der einen Verweis zur Struktur enthält, in der die Indizes der extremen Balken gespeichert werden. Es muss bestimmt werden, ab welchem Balkenindex die Suche nach dem Extremum beginnt.
- Die Seriennummer des zu findenden extremen Balkens (nimmt einen Wert zwischen 2 und 4 an). Sie wird benötigt, um den Index des gewünschten Balkens aus der Struktur zu bestimmen und um festzulegen, auf welcher Linie (Unterstützung oder Widerstand) sich das gewünschte Extremum befinden soll.
- Den Parameter des Typen bool, der bestimmt, auf welcher Linie (Unterstützung oder Widerstand) sich der erste extreme Balken befinden soll. Ohne diese Information ist es unmöglich, anhand der Seriennummer zu bestimmen, auf welcher Linie sich der gewünschte Balken befinden soll.
int Ext_2(double low, //low RSI level, oversold level double high, //high RSI level, overbought level int bars, //number of analyzed bars, to avoid copying unnecessary data into arrays int h_rsi, //handle of RSI indicator string symbol, //symbol of chart st_Bars &bars_ext,//structure containing codes of found bars char n_bar, //ordinal number of bar required to find (2,3 or 4) float distans, //distance for deviation of one of indicator levels bool first_ext,//type of first bar ENUM_TIMEFRAMES period_trade)//period of chart
Auf globaler Ebene erstellen wir einen Strukturtyp, der die Indizes aller 4 extremen Balken beinhalten wird:
struct st_Bars //structure initialization { int Bar_1; int Bar_2; int Bar_3; int Bar_4; }; st_Bars Bars_Ext; //declaration of structure type variable
Um die Indikatorlinie zu bestimmen, auf der sich das gewünschte Extremum befinden soll, müssen zuerst zwei Variablen des Typen bool erstellt werden:
bool high_level= false; //variables to determine type of desired bar bool low_level = false; //...
Wenn die Ordnungszahl des gewünschten extremen Balkens 2 oder 4 ist und der erste extreme Balken auf der Unterstützungslinie liegt, muss der gewünschte Balken auf der Widerstandslinie liegen. Deshalb müssen Balken analysiert werden, deren RSI-Wert größer oder gleich der oberen Ebene (Parameter high) ist. Wenn die Ordnungszahl des gewünschten extremen Balkens 3 ist und der erste extreme Balken sich auf der Unterstützungslinie befindet, wird sich der gewünschte Balken ebenfalls auf dieser Linie befinden. Wenn der erste extreme Balken auf der Widerstandslinie liegt, wird die Position des gewünschten Balkens entsprechend gewählt.
if(n_bar!=3) { if(first_ext==true)//if first point was maximum { low_level=true;//then this should be minimum if(distans>=0) low=low+distans; //if necessary, displace low level of RSI } else //if minimum { high_level = true; if(distans>=0) high=high-distans; //if necessary, displace high level of RSI } } else { if(first_ext==false)//if first point was minimum { low_level=true;//then this point has to be minimum if(distans>=0) high=high-distans; //if necessary, displace high level of RSI } else //if maximum { high_level = true; if(distans>=0) low=low+distans; //if necessary, displace low level of RSI } }
Eine weitere Variable des Typen bool wird benötigt, um den Zeitpunkt zu bestimmen, wenn das gewünschte Extremum gefunden wurde und die Analyse der Balken angehalten werden kann.
bool _start = false;
Der Wert dieser Variable ändert sich zu true, wenn wir in der Historie den zu analysierenden Balkenbereich finden. Die Analyse der Balken wird beendet, wenn _start = true. Wenn low_level = true, überkreuzt die RSI-Indikatorlinie die Ebene high. Wenn high_level = true, überkreuzt die RSI-Indikatorlinie die Ebene low.
if(_start==true && ((low_level==true && rsi>=high) || (high_level==true && rsi<=low))) break; //exit loop if second extremum is found, and RSI crossed opposite level
Die Schleife für die Suche nach extremen Balken sieht so aus:
for(int i=bar_1;i<bars;i++) //analyze remaining bars { rsi=m_rsi[i]; price_max = NormalizeDouble(m_high[i], digits); price_min = NormalizeDouble(m_low[i], digits); if(_start==true && ((low_level==true && rsi>=high) || (high_level==true && rsi<=low))) { break; //exit loop if second extremum is found, and RSI crossed opposite level } if(low_level==true) //if looking for minimum extremum { if(rsi<=low) { if(_start==false) _start=true; if(price_min<min) { min=price_min; index_bar=i; } } } else //if looking for maximum extremum { if(rsi>=high) { if(_start==false) _start=true; if(price_max>=max) { max=price_max; index_bar=i; } } } }
Die Variable Bar_1 enthält den Index des vorherigen extremen Balkens, der mithilfe des Operators switch berechnet wird:
switch(n_bar) //find index of previous bar { case 2: bar_1 = bars_ext.Bar_1; break; case 3: bar_1 = bars_ext.Bar_2; break; case 4: bar_1 = bars_ext.Bar_3; break; }
Um herauszufinden, auf welcher Indikatorlinie (Unterstützung oder Widerstand) sich der erste extreme Balken befindet, genügt es, seinen Index und den Wert des RSI-Indikators auf dem Balken mit dem erhaltenen Index abzurufen:
bool One_ext (st_Bars & bars_ext, // variable of structure type to obtain first bar index string symbol, //symbol of chart int h_rsi, //handle of indicator double low, //set oversold level of RSI (high level can be used) ENUM_TIMEFRAMES period_trade) //period of chart { double m_rsi[]; //array initialization of indicator data ArraySetAsSeries(m_rsi,true); //indexing CopyBuffer(h_rsi,0,0,bars_ext.Bar_1+1,m_rsi); //fill array with RSI data double rsi=m_rsi[bars_ext.Bar_1]; //define RSI value on bar with first extremum if(rsi<=low) //if value is below low level, return(false); //then first extremum is minimum else //if not, return(true); //then maximum }
Verarbeitung der Ergebnisse
Wir kennen nun die Indizes aller vier Balken und ihre entsprechenden Preise (low oder high). Um die Arrays zu befüllen, die dem Wert der Indikatorlinien auf jedem Balken entsprechen, werden die Gleichungen von zwei Linien benötigt, die den Unterstützungs- und Widerstandslinien entsprechen. Die wohlbekannte Liniengleichung, die zu diesem Zweck genutzt wird, lautet: y = kx + b. In unserem Fall ist "x" der Index eines Balkens und "y" ein Preis (Preis der low-Kerze für die Unterstützungslinie, Preis der high-Kerze für die Widerstandslinie).
Um die Werte der Koeffizienten "k" und "b" zu finden, genügt es, die entsprechenden Werte von zwei bekannten extremen Balken in der Liniengleichung zu ersetzen und die erhaltenen Ausdrücke im Gleichungssystem zu kombinieren. Als Ergebnis erhalten wie die folgenden Ausdrücke im System:
K=(price_2-price_1)/(_bar2-_bar1); //find coefficient K B=price_1-K*_bar1; //find coefficient B
mit
double K,B;
"K" und "B" sind globale Variablen, die den Werten der Koeffizienten "k" und "b" in der Liniengleichung entsprechen;
int _bar1,_bar2;
Dies sind Indizes von Balken, die sich auf der gleichen Linie befinden;
double price_1,price_2;
Dies sind die low-Preise der entsprechenden Balken, wenn es erforderlich ist, "K" und "B" für die Unterstützungslinie zu definieren, oder die high-Preise der entsprechenden Balken, wenn es erforderlich ist, "K" und "B" für die Widerstandslinie zu bestimmen.
Die unten dargelegte Funktion legt die Werte der globalen Variablen "K" und "B" für die Unterstützungslinie fest, wenn der Parameter "_line" false ist, und für die Widerstandslinie, wenn der Parameter "_line" true ist:
void Level(bool _line, //parameter that defines resistance/support line, which coefficients have to be found bool _first_ext, //type of first extremum (already familiar to you) st_Bars &bars_ext, //structure that contains bar indexes string _symbol, //symbol ENUM_TIMEFRAMES _period) //period of chart { int bars=Bars_H; //number of analyzed bars double m_high[],m_low[]; //initialization of arrays ArraySetAsSeries(m_high,true); //arrays are indexed from first element ArraySetAsSeries(m_low,true); //... int h_high = CopyHigh(_symbol, _period, 0, bars, m_high); //fill array of High candle price int h_low = CopyLow(_symbol, _period, 0, bars, m_low); //fill array of Low candle price double price_1,price_2; int _bar1,_bar2; int digits=(int)SymbolInfoInteger(_symbol,SYMBOL_DIGITS);//number of decimal places in current symbol if(_line==true) //if resistance line is required { if(_first_ext==true) //if first extremum is maximum { price_1 = NormalizeDouble(m_high[bars_ext.Bar_1], digits); price_2 = NormalizeDouble(m_high[bars_ext.Bar_3], digits); _bar1 = bars_ext.Bar_1; _bar2 = bars_ext.Bar_3; } else //if minimum { price_1 = NormalizeDouble(m_high[bars_ext.Bar_2], digits); price_2 = NormalizeDouble(m_high[bars_ext.Bar_4], digits); _bar1 = bars_ext.Bar_2; _bar2 = bars_ext.Bar_4; } } else //if support line is required { if(_first_ext==true) //if first extremum is maximum { price_1 = NormalizeDouble(m_low[bars_ext.Bar_2], digits); price_2 = NormalizeDouble(m_low[bars_ext.Bar_4], digits); _bar1 = bars_ext.Bar_2; _bar2 = bars_ext.Bar_4; } else //if minimum { price_1 = NormalizeDouble(m_low[bars_ext.Bar_1], digits); price_2 = NormalizeDouble(m_low[bars_ext.Bar_3], digits); _bar1 = bars_ext.Bar_1; _bar2 = bars_ext.Bar_3; } } K=(price_2-price_1)/(_bar2-_bar1); //find coefficient K B=price_1-K*_bar1; //find coefficient B }
Die Liniengleichung lautet: y = kx + b. Dabei wird der Preis des Finanzinstruments für die Achse "y" und der Index des Balkens für die Achse "x" verwendet. Wenn wir für die Achse "x" die Anzahl der Sekunden seit dem 1. Januar 1970 nutzen, sehen die Ergebnisse des Liniendiagramms im Wochenendbereich chaotisch aus. Aus diesem Grund habe ich die Indizes der Balken verwendet.
Aus der Funktion "OnCalculate" wird die Funktion "Level" zweimal aufgerufen: einmal vor dem Befüllen des Arrays für die Widerstandslinie und einmal zum Befüllen des Arrays für die Unterstützungslinie mit Preiswerten:
for(int i=0;i<Bars_H;i++) { resistanceBuffer[i]=NormalizeDouble(K*i+B,Dig); } Level(false,First_Ext,Bars_Ext,Trade_Symbol,Period_Trade); //get coefficients K и B for resistance line for(int i=0;i<Bars_H;i++) { supportBuffer[i]=NormalizeDouble(K*i+B,Dig); }
Beispiel eines Indikators, der Unterstützungs- und Widerstandsebenen anzeigt
Das Resultat der Ausführung des Indikators, der alle oben aufgeführten Funktionen nutzt und die Unterstützungs- und Widerstandslinien zeichnet, sieht so aus:
Abb. 7. Resultat der Ausführung des Indikators
Der Indikator ist so konstruiert, dass die Werte von Arrays der Unterstützungs- und Widerstandslinien nach dem Entstehen eines neuen extremen Balkens geändert werden können und die Ebenen automatisch neu gezeichnet werden. Wenn wir allerdings den Winkel berechnen und speichern, den eine dieser Linien mit der Zeitachse des Diagramms bildet, und diesen dann mit dem neuen Winkel der gleichen Linie vergleichen, ist es möglich, einen Rückschluss über eine Beschleunigung oder Verlangsamung des Trends zu ziehen, wie es in diesem Beitrag bereits erwähnt wurde.
Der vollständige Code des Indikators befindet sich in der an diesen Beitrag angehängten Datei.
Fazit
Natürlich ist es viel einfacher, diese Linien manuell zu konstruieren, da man so nicht die Parameter des Indikators für jedes Symbol und jeden Zeitraum auswählen muss. Allerdings dient dieser Indikator als Basis oder Bestandteil der Strategie, die dem automatischen Handelssystem zugrunde liegt. Nach dem Erhalt eines Daten-Arrays von Indikatorlinien können Sie den Neigungswinkel und die Richtung des Trends analysieren und die durch diese Linien geformte grafische Form identifizieren. All das macht es letztendlich möglich, die Stärke eines Kauf- oder Verkaufssignals zu analysieren und sowohl innerhalb des Preiskanals als auch beim Durchbruch von Unterstützungs- und Widerstandslinien zu handeln.
Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/1742





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