
Auf Fraktalen basiertes Zeichnen von Trendlinien mithilfe von MQL4 und MQL5
Inhaltsverzeichnis
- Einleitung
- 1. Eingabeparameter, die Funktion DeInit() und die Deklaration von Variablen
- 2. Die Suche nach den nächstgelegenen Fraktalen
- 3. Bestimmung des Kurses und der Zeitwerte der Fraktale
- 4. Das Kreieren von Objekten und Editieren ihrer Eigenschaften Das Neuzeichnen von Linien
- 5. Überprüfung der Ladehistorie von Balken
- 6. Signale von Trendlinien-Breakthroughs, Push Notifications
- 7. Der praktische Nutzen von Trendlinien fürs Trading
- Fazit
Einleitung
Ich habe mir kürzlich einige Gedanken über die Verwendung von Trendlinien gemacht. Dabei kam die Frage auf, welche Methode man zur Bestimmung der Punkte zum Zeichnen der Linien verwenden soll - sowie die Frage nach der Präzision des Zeichnens. Ich habe mich für Fraktale als Basis entschieden.
Infolge meines Hauptberufs analysiere ich sehr oft Märkte, was es mir erlaubt, ein wenig Zeit ins Trading zu investieren. Ferner gilt, dass man nicht einfach so Linien auf einen größeren Zeitrahmen zeichnen kann - die Linien sollten durch extreme Punkte und mit einer Präzision von bis zu 15 Minuten gezeichnet werden. Die Ursache ist die, dass die Fraktalzeit eines größeren Zeitrahmens nicht immer mit der Zeit des selben Extrempunktes (M15) übereinstimmt. Kurs gesagt: An dieser Stelle kommt die Automatisierung ins Spiel. Es trug sich einmal zu, dass ich einen Code mithilfe von MQL5 geschrieben und dann auf MQL4 gewechselt habe, da ich das Programm für MetaTrader 4 benötigte.
In diesem Artikel werde ich Ihnen meine Lösung des Problems erläutern, indem ich MQL4 und MQL5 verwenden werde. Der Artikel soll zwar beide Sprachen miteinander vergleichen, allerdings wäre es unfair, die Effizienz von MQL4 gegen die von MQL5 antreten zu lassen. Außerdem bin ich mir natürlich darüber im Klaren, dass es wahrscheinlich auch noch andere Lösungen gibt, die eventuell sogar noch effektiver als meine eigene sind. In jedem Fall richtet sich vorliegender Artikel an Anfänger im Schreiben von Skripten mittels MQL5 und MQL4 bzw. an all jene, die planen, mit Fraktalen und Trendlinien zu interagieren.
1. Eingabeparameter, die Funktion DeInit() und die Deklaration von Variablen
Ich habe die folgenden Variablen und Eingabeparameter benutzt:
input color Resistance_Color=Red; // setting the resistance line color input ENUM_LINE_STYLE Resistance_Style; // setting the resistance line style input int Resistance_Width=1; // setting the resistance line width input color Support_Color=Red; // setting the support line color input ENUM_LINE_STYLE Support_Style; // setting the support line style input int Support_Width=1; // setting the support line width
Diese Parameter sind für MQL4 und MQL5 absolut identisch.
In MQL5 müssen wir den Indikator im Voraus anlegen.
//--- iFractals indicator handle int Fractal; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- getting the iFractals indicator handle Fractal=iFractals(Symbol(),PERIOD_D1); //--- return(INIT_SUCCEEDED); }
Da das Programm grafische Objekte zeichnen wird, ergibt es Sinn, diese zu entfernen, wenn man den EA vom Chart abzieht:
void OnDeinit(const int reason) { ObjectDelete(0,"TL_Resistance"); ObjectDelete(0,"TL_Support"); }
Zum Zeichnen zweier Linien (Support und Resistance) bedarf es vier Punkten. Um den Punkt zu ermitteln, den die Linie passiert, müssen wir die Zeit und den Kurs kennen.
Die Koordinaten werden entsprechend folgender Reihenfolge bestimmt: Zuerst müssen wir den Extrembalken finden, woraufhin wir den Kurs und die Zeit des Extrempunktes bestimmen können.
Variablen in der Funktion OnTick() deklarieren.
MQL4 |
---|
//--- declaration of variables int n,UpperFractal_1,UpperFractal_2,LowerFractal_1,LowerFractal_2; |
MQL5 |
---|
//--- declaration of variables int n,UpperFractal_1,UpperFractal_2,LowerFractal_1,LowerFractal_2; //--- declaring the arrays for writing values of the iFractal indicator buffer double FractalDown[],FractalUp[]; double UpFractal_1,UpFractal_2,LowFractal_1,LowFractal_2; |
Zunächst habe ich nur diejenigen Variablen deklariert, die Indexe von Balken mit geformten Fraktalen speichern.
In MQL4:
- Die Variable n wird dafür gebraucht, um das nächste bekannte Fraktal unter Zuhilfenahme des For-Loop-Operators zu finden;
- UpperFractal_1, UpperFractal_2, LowerFractal_1, LowerFractal_2 - all diese Variablen werden den Index des Balkens am nächsten und zweitnächsten Extrempunkt mit dem höchsten/niedrigsten Preis (bzgl. der Bestimmung des Fraktals) speichern;
In MQL5 führen wir zusätzliche Variablen ein:
- FractalDown[], FractalUp[]; - Deklarierung von Arrays des Werts double zum Speichern der Werte des iFractals-Indikatorpuffers;
- Als Nächstes folgen die Variablen des Typs double: UpFractal_1, UpFractal_2, LowFractal_1, LowFractal_2. Diese werden den Wert des Preises der Extrempunkte speichern.
2. Die Suche nach den nächstgelegenen Fraktalen
Um den Balkenindex mit einem geformten Fraktal zu finden, verwenden wir den For-Loop-Operator.
Lassen Sie uns die Indexe der beiden ersten Balken bestimmen, die mit dem ersten/zweiten oberen Fraktal korrespondieren:
MQL4 |
---|
//--- finding the bar index of the first nearest upper fractal for(n=0; n<(Bars-1);n++) { if(iFractals(NULL,1440,MODE_UPPER,n)!=NULL) break; UpperFractal_1=n+1; } //--- finding the bar index of the second nearest upper fractal for(n=UpperFractal_1+1; n<(Bars-1);n++) { if(iFractals(NULL,1440,MODE_UPPER,n)!=NULL) break; UpperFractal_2=n+1; } |
MQL5 |
---|
//--- first, we need to write the Fractal indicator buffer values into the arrays //--- filling arrays with buffer values CopyBuffer(Fractal,0,TimeCurrent(),Bars(Symbol(),PERIOD_D1),FractalUp); CopyBuffer(Fractal,1,TimeCurrent(),Bars(Symbol(),PERIOD_D1),FractalDown); //--- indexing like in timeseries ArraySetAsSeries(FractalUp,true); ArraySetAsSeries(FractalDown,true); //--- next, we use the for loop operator to find the first upper fractal for(n=0; n<Bars(Symbol(),PERIOD_D1); n++) { //--- if the value is not empty, break the loop if(FractalUp[n]!=EMPTY_VALUE) break; } //--- writing the price value of the first fractal into the variable UpFractal_1=FractalUp[n]; //--- writing the index of the first fractal into the variable UpperFractal_1=n; //--- finding the second upper fractal for(n=UpperFractal_1+1; n<Bars(Symbol(),PERIOD_D1); n++) { if(FractalUp[n]!=EMPTY_VALUE) //if the value is not empty, break the loop break; } //--- writing the price value of the second fractal into the variable UpFractal_2=FractalUp[n]; //--- writing the index of the second fractal into the variable UpperFractal_2=n; |
Ich habe hier klipp und klar mithilfe von Funktionen zur Bewertung von Zeitserien einen der Hauptunterschiede zwischen MQL5 und MQ4 aufgezeigt.
In MQL4 habe ich umgehend damit begonnen, den Index des Balkens mit einem geformten Fraktal zu suchen. In MQL 5 habe ich hingegen die FractalUp[]-/FractalDown[]-Arrays zum Speichern von Preiswerten von oberen und unteren Fraktalen spezifiziert, indem ich auf den Indikator iFractals unter Zuhilfenahme der Funktion CopyBuffer() zugegriffen habe. Danach habe ich die Indexierung dieser Arrays (ähnlich den Zeitserien) vorgenommen - und zwar mithilfe der Funktion ArraySetAsSeries().
In MQL 4 hatte ich nur Indexe der Balken mit bekannten Fraktalen, aber in MQL 5 erhielt ich durch die Funktion CopyBuffer() Balkenindexe sowie Preiswerte von Fraktalen.
Auf ähnliche Weise finden wir die ersten beiden niedrigeren Fraktale:
MQL4 |
---|
//--- finding the bar index of the first nearest lower fractal for(n=0; n<(Bars-1);n++) { if(iFractals(NULL,1440,MODE_LOWER,n)!=NULL) break; LowerFractal_1=n+1; } //--- finding the bar index of the second nearest lower fractal for(n=LowerFractal_1+1; n<(Bars-1);n++) { if(iFractals(NULL,1440,MODE_LOWER,n)!=NULL) break; LowerFractal_2=n+1; } |
MQL5 |
---|
//--- finding the values of the lower fractals //--- finding the first lower fractal for(n=0; n<Bars(Symbol(),PERIOD_D1); n++) { //--- if the value is not empty, break the loop if(FractalDown[n]!=EMPTY_VALUE) break; } //--- writing the price value of the first fractal into the variable LowFractal_1=FractalDown[n]; //--- writing the index of the first fractal into the variable LowerFractal_1=n; //--- finding the second lower fractal for(n=LowerFractal_1+1; n<Bars(Symbol(),PERIOD_D1); n++) { if(FractalDown[n]!=EMPTY_VALUE) break; } //--- writing the price value of the second fractal into the variable LowFractal_2=FractalDown[n]; //--- writing the index of the second fractal into the variable LowerFractal_2=n; |
Wie Sie sehen, ist der Code in MQL4 und MQL5 ziemlich ähnlich. Allerdings gibt es einen kleinen Syntaxunterschied.
3. Bestimmung des Kurses und der Zeitwerte der Fraktale
Um eine Linie zu zeichnen, müssen wir zunächst die Zeit und den Preis eines Fraktals bestimmen. Natürlich könnten wir in MQL4 ganz einfach die vordefinierten Zeitserien High[] und Low[] sowie die Funktion iTime() verwenden. Allerdings benötigen wir außerdem noch ein wenig präzisere Zeitkoordinaten, um ein korrektes Einzeichnen der Trendlinie sicherzustellen.
Die Abb. 1-2 zeigen die Differenz zwischen den Zeitwerten der H4-Extrempunkte und der M15-Zeitrahmen an.
Abb. 1 Der Zeitwert des Extrempunktes (H4)
Abb. 2 Der Zeitwert des Extrempunktes (M15)
Ich bin zu der Überzeugung gelangt, dass eine Extrempunktpräzision von 15 Minuten für diesen Zweck vollauf genügt.
Grundsätzlich gilt: Das Prinzip zur Klarstellung der Extrempunkte ist in MQL4 und MQL5 beinahe identisch. Gleichwohl gibt es einige Unterschiede hinsichtlich der Details:
MQL4 | MQL5 |
---|---|
|
|
Der Code mit detaillierten Anmerkungen steht unten:
MQL4 |
---|
// Step 1. Determining the extreme point time value on a larger timeframe: //--- determining the time of fractals datetime UpFractalTime_1=iTime(NULL, 1440,UpperFractal_1); datetime UpFractalTime_2=iTime(NULL, 1440,UpperFractal_2); datetime LowFractalTime_1=iTime(NULL, 1440,LowerFractal_1); datetime LowFractalTime_2=iTime(NULL, 1440,LowerFractal_2); |
// Step 2. Determining the index of the extreme bar on a smaller timeframe: //--- finding the fractal index on M15 int UpperFractal_1_m15=iBarShift(NULL, 15, UpFractalTime_1,true); int UpperFractal_2_m15=iBarShift(NULL, 15, UpFractalTime_2,true); int LowerFractal_1_m15=iBarShift(NULL, 15, LowFractalTime_1,true); int LowerFractal_2_m15=iBarShift(NULL, 15, LowFractalTime_2,true); |
// Step 3. Using the arrays to find the clarified extreme points on М15: //--- using the arrays to find the clarified extreme points //--- introducing the i variable to use in the for loop operator int i; //--- 1. First, find the lower extreme points //--- 3.1 Finding the first lower extreme point //--- declaring the array for storing the index values of the bars int Lower_1_m15[96]; //--- declaring the array for storing the price values double LowerPrice_1_m15[96]; //--- starting the for loop: for(i=0;i<=95;i++) { //--- filling the array with the bar index values Lower_1_m15[i]=LowerFractal_1_m15-i; //--- filling the array with the price values LowerPrice_1_m15[i]=iLow(NULL,15,LowerFractal_1_m15-i); } //--- determining the minimum price value in the array int LowestPrice_1_m15=ArrayMinimum(LowerPrice_1_m15,WHOLE_ARRAY,0); //--- determining the bar with the lowest price in the array int LowestBar_1_m15=Lower_1_m15[LowestPrice_1_m15]; //--- determining the time of the lowest price bar datetime LowestBarTime_1_m15=iTime(NULL,15,Lower_1_m15[LowestPrice_1_m15]); //--- 3.2 Finding the second lower extreme point int Lower_2_m15[96]; double LowerPrice_2_m15[96]; for(i=0;i<=95;i++) { //--- filling the array with the bar index values Lower_2_m15[i]=LowerFractal_2_m15-i; //--- filling the array with the price values LowerPrice_2_m15[i]=iLow(NULL,15,LowerFractal_2_m15-i); } //--- determining the minimum price value in the array int LowestPrice_2_m15=ArrayMinimum(LowerPrice_2_m15,WHOLE_ARRAY,0); //--- determining the bar with the lowest price in the array int LowestBar_2_m15=Lower_2_m15[LowestPrice_2_m15]; //--- determining the time of the lowest price bar datetime LowestBarTime_2_m15=iTime(NULL,15,Lower_2_m15[LowestPrice_2_m15]); //--- 3.3 Finding the first upper extreme point int Upper_1_m15[96]; double UpperPrice_1_m15[96]; for(i=0;i<=95;i++) { //--- filling the array with the bar index values Upper_1_m15[i]=UpperFractal_1_m15-i; //--- filling the array with the price values UpperPrice_1_m15[i]=iHigh(NULL,15,UpperFractal_1_m15-i); } //--- determining the maximum price value in the array int HighestPrice_1_m15=ArrayMaximum(UpperPrice_1_m15,WHOLE_ARRAY,0); //--- determining the bar with the highest price in the array int HighestBar_1_m15=Upper_1_m15[HighestPrice_1_m15]; //--- determining the time of the highest price bar datetime HighestBarTime_1_m15=iTime(NULL,15,Upper_1_m15[HighestPrice_1_m15]); //--- 3.4 Finding the second upper extreme point int Upper_2_m15[96]; double UpperPrice_2_m15[96]; for(i=0;i<=95;i++) { //--- filling the array with the bar index values Upper_2_m15[i]=UpperFractal_2_m15-i; //--- filling the array with the price values UpperPrice_2_m15[i]=iHigh(NULL,15,UpperFractal_2_m15-i); } |
MQL5 |
---|
// Step 1. Determining the extreme point time value on a larger timeframe: //--- declaring the arrays for storing the time values of the corresponding bar index on a larger timeframe datetime UpFractalTime_1[],LowFractalTime_1[],UpFractalTime_2[],LowFractalTime_2[]; //--- determining the time of fractals on a larger timeframe CopyTime(Symbol(),PERIOD_D1,UpperFractal_1,1,UpFractalTime_1); CopyTime(Symbol(),PERIOD_D1,LowerFractal_1,1,LowFractalTime_1); CopyTime(Symbol(),PERIOD_D1,UpperFractal_2,1,UpFractalTime_2); CopyTime(Symbol(),PERIOD_D1,LowerFractal_2,1,LowFractalTime_2); |
// Step 2. Determining the generation time of the next day bar: //--- determining the generation time of the next day bar (the stop time for CopyHigh(), CopyLow() and CopyTime()) datetime UpFractalTime_1_15=UpFractalTime_1[0]+86400; datetime UpFractalTime_2_15=UpFractalTime_2[0]+86400; datetime LowFractalTime_1_15=LowFractalTime_1[0]+86400; datetime LowFractalTime_2_15=LowFractalTime_2[0]+86400; |
// Step 3. Declaring and filling the arrays for storing the price and time values for the 15-minute timeframe: //--- declaring the arrays for storing the maximum and minimum price values double High_1_15[],Low_1_15[],High_2_15[],Low_2_15[]; //--- filling the arrays with the CopyHigh() and CopyLow() functions CopyHigh(Symbol(),PERIOD_M15,UpFractalTime_1[0],UpFractalTime_1_15,High_1_15); CopyHigh(Symbol(),PERIOD_M15,UpFractalTime_2[0],UpFractalTime_2_15,High_2_15); CopyLow(Symbol(),PERIOD_M15,LowFractalTime_1[0],LowFractalTime_1_15,Low_1_15); CopyLow(Symbol(),PERIOD_M15,LowFractalTime_2[0],LowFractalTime_2_15,Low_2_15); //--- declaring the arrays for storing the time values corresponding to the extreme bar indexes datetime High_1_15_time[],High_2_15_time[],Low_1_15_time[],Low_2_15_time[]; //--- filling the arrays CopyTime(Symbol(),PERIOD_M15,UpFractalTime_1[0],UpFractalTime_1_15,High_1_15_time); CopyTime(Symbol(),PERIOD_M15,UpFractalTime_2[0],UpFractalTime_2_15,High_2_15_time); CopyTime(Symbol(),PERIOD_M15,LowFractalTime_1[0],LowFractalTime_1_15,Low_1_15_time); CopyTime(Symbol(),PERIOD_M15,LowFractalTime_2[0],LowFractalTime_2_15,Low_2_15_time); |
// Step 4. Finding the lowest and highest price values, and the time values of the clarified extreme points: //--- determining the highest and lowest price and time values with the ArrayMaximum() and ArrayMinimum() functions int Max_M15_1=ArrayMaximum(High_1_15,0,96); int Max_M15_2=ArrayMaximum(High_2_15,0,96); int Min_M15_1=ArrayMinimum(Low_1_15,0,96); int Min_M15_2=ArrayMinimum(Low_2_15,0,96); |
Wir haben schließlich die folgenden Trendlinienkoordinaten bestimmt:
1. Für die Support-Linie
MQL4 | MQL5 |
---|---|
|
|
2. Für die Resistance-Linie
MQL4 | MQL5 |
---|---|
|
|
4. Das Kreieren von Objekten und Editieren ihrer Eigenschaften Das Neuzeichnen von Linien
Sobald wir die Koordinaten der Linie kennen, müssen wir nur noch die grafischen Objekte generieren:
MQL4 |
---|
//--- creating the support line ObjectCreate(0,"TL_Support",OBJ_TREND,0,LowestBarTime_2_m15,LowerPrice_2_m15[LowestPrice_2_m15], LowestBarTime_1_m15,LowerPrice_1_m15[LowestPrice_1_m15]); ObjectSet("TL_Support",OBJPROP_COLOR,Support_Color); ObjectSet("TL_Support",OBJPROP_STYLE,Support_Style); ObjectSet("TL_Support",OBJPROP_WIDTH,Support_Width); //--- creating the resistance line ObjectCreate(0,"TL_Resistance",OBJ_TREND,0,HighestBarTime_2_m15,UpperPrice_2_m15[HighestPrice_2_m15], HighestBarTime_1_m15,UpperPrice_1_m15[HighestPrice_1_m15]); ObjectSet("TL_Resistance",OBJPROP_COLOR,Resistance_Color); ObjectSet("TL_Resistance",OBJPROP_STYLE,Resistance_Style); ObjectSet("TL_Resistance",OBJPROP_WIDTH,Resistance_Width); |
MQL5 |
---|
//--- creating the support line ObjectCreate(0,"TL_Support",OBJ_TREND,0,Low_2_15_time[Min_M15_2],Low_2_15[Min_M15_2],Low_1_15_time[Min_M15_1],Low_1_15[Min_M15_1]); ObjectSetInteger(0,"TL_Support",OBJPROP_RAY_RIGHT,true); ObjectSetInteger(0,"TL_Support",OBJPROP_COLOR,Support_Color); ObjectSetInteger(0,"TL_Support",OBJPROP_STYLE,Support_Style); ObjectSetInteger(0,"TL_Support",OBJPROP_WIDTH,Support_Width); //--- creating the resistance line ObjectCreate(0,"TL_Resistance",OBJ_TREND,0,High_2_15_time[Max_M15_2],High_2_15[Max_M15_2],High_1_15_time[Max_M15_1],High_1_15[Max_M15_1]); ObjectSetInteger(0,"TL_Resistance",OBJPROP_RAY_RIGHT,true); ObjectSetInteger(0,"TL_Resistance",OBJPROP_COLOR,Resistance_Color); ObjectSetInteger(0,"TL_Resistance",OBJPROP_STYLE,Resistance_Style); ObjectSetInteger(0,"TL_Resistance",OBJPROP_WIDTH,Resistance_Width); |
Ich habe also die notwendigen Linien eingezeichnet und ihre Parameter auf Basis der Eingabeparameter spezifiziert.
Nun gilt es, die Trendlinien rot zu färben.
Wenn sich die Situation des Marktes verändert - wenn beispielsweise ein neuer Extrempunkt auftaucht - können wir die existierende Linie ganz einfach entfernen.
MQL4 |
---|
//--- redrawing the support line //--- writing the values of the support line time coordinates into the variables datetime TL_TimeLow2=ObjectGet("TL_Support",OBJPROP_TIME2); datetime TL_TimeLow1=ObjectGet("TL_Support",OBJPROP_TIME1); //--- if the line coordinates don't match the current coordinates if(TL_TimeLow2!=LowestBarTime_1_m15 && TL_TimeLow1!=LowestBarTime_2_m15) { //--- remove the line ObjectDelete(0,"TL_Support"); } //--- redrawing the resistance line //--- writing the values of the resistance line time coordinates into the variables datetime TL_TimeUp2=ObjectGet("TL_Resistance",OBJPROP_TIME2); datetime TL_TimeUp1=ObjectGet("TL_Resistance",OBJPROP_TIME1); //--- if the line coordinates don't match the current coordinates if(TL_TimeUp2!=HighestBarTime_1_m15 && TL_TimeUp1!=HighestBarTime_2_m15) { //--- remove the line ObjectDelete(0,"TL_Resistance"); } |
MQL5 |
---|
//--- redrawing the support line //--- writing the values of the support line time coordinates into the variables datetime TL_TimeLow2=(datetime)ObjectGetInteger(0,"TL_Support",OBJPROP_TIME,0); datetime TL_TimeLow1=(datetime)ObjectGetInteger(0,"TL_Support",OBJPROP_TIME,1); //--- if the line coordinates don't match the current coordinates if(TL_TimeLow2!=Low_2_15_time[Min_M15_2] && TL_TimeLow1!=Low_1_15_time[Min_M15_1]) { //--- remove the line ObjectDelete(0,"TL_Support"); } //--- redrawing the resistance line //--- writing the values of the resistance line time coordinates into the variables datetime TL_TimeUp2=(datetime)ObjectGetInteger(0,"TL_Resistance",OBJPROP_TIME,0); datetime TL_TimeUp1=(datetime)ObjectGetInteger(0,"TL_Resistance",OBJPROP_TIME,1); //--- if the line coordinates don't match the current coordinates if(TL_TimeUp2!=High_2_15_time[Max_M15_2] && TL_TimeUp1!=High_1_15_time[Max_M15_1]) { //--- remove the line ObjectDelete(0,"TL_Resistance"); } |
5. Überprüfung der Ladehistorie von Balken
Während der Testphase habe ich bemerkt, dass die Linien nicht immer korrekt gezeichnet wurden.
Zuerst nahm ich an, dass es sich ganz einfach um einen Bug im Code handeln würde. Oder das meine Lösung einfach nicht funktioniert. Später begriff ich, dass das Problem durch ein unzureichendes Laden der Balkenhistorie für einen kleineren Zeitraum (bei mir: M15) hervorgerufen wurde. Um andere Benutzer vor diesem Fehler zu bewahren, habe ich mich entschieden, das Programm zusätzlich überprüfen zu lassen, ob ein Balken für M15 existiert.
Zu diesem Zwecke habe ich mir die Fähigkeiten der MQL4-Funktion iBarShift() zunutze gemacht, die ich ursprünglich im Abschnitt „Bestimmung der Preis- und Zeitwerte der Fraktale" verwendet habe.
Falls kein Balken gefunden wird, gibt die Funktion iBarShift() -1 zurück. Wir können daher folgende Warnung ausgeben:
MQL4 |
---|
//--- checking the bars history loading //--- if at least one bar is not found on M15 if(UpperFractal_1_m15==-1 || UpperFractal_2_m15==-1 || LowerFractal_1_m15==-1 || LowerFractal_2_m15==-1) { Alert("The loaded history is insufficient for the correct work!"); } |
In MQL5 habe ich die Funktion Bars() verwandt, die einen leeren Wert zurückgibt, wenn die Zeitseriendaten im Terminal nicht generiert worden sein sollten:
//--- checking the bars history loading //--- 1. determining the number of bars on a specified timeframe int High_M15_1=Bars(Symbol(),PERIOD_M15,UpFractalTime_1[0],UpFractalTime_1_15); int High_M15_2=Bars(Symbol(),PERIOD_M15,UpFractalTime_2[0],UpFractalTime_2_15); int Low_M15_1=Bars(Symbol(),PERIOD_M15,LowFractalTime_1[0],LowFractalTime_1_15); int Low_M15_2=Bars(Symbol(),PERIOD_M15,LowFractalTime_2[0],LowFractalTime_2_15); //--- 2. check if the loaded history is insufficient for the correct line drawing //--- if at least one bar is not found if(High_M15_1==0 || High_M15_2==0 || Low_M15_1==0 || Low_M15_2==0) { Alert("The loaded history is insufficient for the correct work!"); } |
6. Signale von Trendlinien-Breakthroughs, Push Notifications
Um das Puzzle zu vervollständigen, habe ich mich entschieden, ein Signal für Trendlinen-Breakthroughs zu implementieren. Die Trendlinie wird durch die Extrempunkte des Zeitrahmen des Tages gezeichnet. Um allerdings den Breakthrough vorher zu erkennen, muss der Balken höher oder niedriger als die H4-Trendlinie geschlossen werden.
Allgemein gesprochen lässt sich dieser Prozess in drei Schritte untergliedern:
- Bestimmung des Schluss- und des Trendlinienpreises des Balkens;
- Bestimmung der Bedingungen, die zum Durchbrechen der Trendlinie erfüllt sein müssen;
- Versendung einer Push Notification, die den Breakthrough ankündigt.
MQL4 |
---|
// 1. Getting the price parameters of the trend line //--- determining the closing price of a bar with index 1 double Price_Close_H4=iClose(NULL,240,1); //--- determining the time of a bar with index 1 datetime Time_Close_H4=iTime(NULL,240,1); //--- determining the bar index on H4 int Bar_Close_H4=iBarShift(NULL,240,Time_Close_H4); //--- determining the price of the line on H4 double Price_Resistance_H4=ObjectGetValueByShift("TL_Resistance",Bar_Close_H4); //--- determining the price of the line on H4 double Price_Support_H4=ObjectGetValueByShift("TL_Support",Bar_Close_H4); |
// 2. Conditions for trend line breakthroughs //--- for breaking through the support line bool breakdown=(Price_Close_H4<Price_Support_H4); //--- for braking through the resistance line bool breakup=(Price_Close_H4>Price_Resistance_H4); |
// 3. Delivering the push notifications if(breakdown==true) { //--- send no more than one notification per 4 hours int SleepMinutes=240; static int LastTime=0; if(TimeCurrent()>LastTime+SleepMinutes*60) { LastTime=TimeCurrent(); SendNotification(Symbol()+"The price has broken through the support line"); } } if(breakup==true) { //--- send no more than one notification per 4 hours SleepMinutes=240; LastTime=0; if(TimeCurrent()>LastTime+SleepMinutes*60) { LastTime=TimeCurrent(); SendNotification(Symbol()+"The price has broken through the resistance line"); } } |
MQL5 |
---|
// 1. Getting the price parameters of the trend line double Close[]; CopyClose(Symbol(),PERIOD_H4,TimeCurrent(),10,Close); //--- setting the array indexing order ArraySetAsSeries(Close,true); //--- datetime Close_time[]; CopyTime(Symbol(),PERIOD_H4,TimeCurrent(),10,Close_time); //--- setting the array indexing order ArraySetAsSeries(Close_time,true); //--- double Price_Support_H4=ObjectGetValueByTime(0,"TL_Support",Close_time[1]); double Price_Resistance_H4=ObjectGetValueByTime(0,"TL_Resistance",Close_time[1]); |
// 2. Conditions for trend line breakthroughs bool breakdown=(Close[1]<Price_Support_H4); bool breakup=(Close[1]>Price_Resistance_H4); |
Um einen Breakthrough zu identifizieren, habe ich die MQL4-Funktion ObjectGetValueByShift() und die MQL5-Funktion ObjectGetValueByTime() verwendet.
Ich hätte womöglich ganz einfach eine 1 anstelle von Bar_Close_H4 als Parameter für ObjectGetValueByShift() einstellen können, allerdings entschied ich mich dazu, zuerst den H4-Index zu bestimmen. Was die Limitierung der Zahl der gesendeten Nachrichten angeht, so habe ich mich der Lösung bedient, auf die ich in diesem Forenthread hier gestoßen bin. Ich möchte dem entsprechenden Autor an dieser Stelle meinen Dank aussprechen.
7. Der praktische Nutzen von Trendlinien fürs Trading
Der einfachste und simpelste Weg: Identifizieren Sie einen Breakthrough, warten Sie auf den Pullback und betreten Sie danach den Markt.
Idealerweise sollten Sie in etwa Folgendes erhalten:
Abb. 3. Trendlinien-Breakthrough
Sie können Ihr Vorstellungsvermögen bemühen und versuchen, die Formationen zu identifizieren, beispielsweise die Muster der technischen Analyse wie zum Beispiel ein Dreieck:
Abb. 4. Dreiecksmuster
In den Bildern oben wurden die Linien nicht durch einen kleinen Zeitrahmen verdeutlicht.
Fazit
Damit möchte ich diesen Artikel beenden. Ich hoffe, Sie fanden ihn zumindest ein wenig nützlich. Der Artikel richtete sich an Anfänger und Amateure, so wie ich einer bin.
Während des Schreibens dieses Artikels habe ich eine ganze Menge gelernt und erfahren: das Schreiben bedeutsamer Kommentare über Codezeilen als auch meinen Sinneswandel ausgehend von einer komplexen/umständlichen Lösung zur Klarstellung von Extrempunkten hinzu einer ungleich simpleren.
Seien Sie für das Lesen dieses Artikels ganz herzlich bedankt. Über Feedback würde ich mich sehr freuen.
Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/1201





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