
Elder-Ray (Bulls Power und Bears Power)
Einführung
Dieses System wurde von Alexander Elder in seinem Buch "Trading for a Living" beschrieben. Es basiert auf den Indikatoren Bulls Power und Bears Power und dem Trendindikator Gleitender Durchschnitt (EMA — exponentieller gleitender Durchschnitt)
Das System ist beides einfach und doch komplex:
- Es ist einfach, wenn wir es wörtlich nehmen: Wir kaufen, wenn ein Trend nach oben geht (EMA) und Bears Power ist unter Null, aber steigt;
- Es ist komplex, wenn wir genauer hinschauen und uns auch das Diagramm ansehen, in dem EMA und Bears Power gestartet werden: Es stellt sich heraus, dass es nicht so einfach ist, wie es scheint, da es nur wenige solcher Bedingungen gibt.
In diesem Artikel werden wir alle Phasen von einfach bis komplex durchlaufen und zwei Arten von Handelssystemen überprüfen:
- Alle Indikatoren auf demselben Chart (und damit auf einem einzigen Zeitrahmen);
- In Kombination mit dem System "Triple Choice".
Der EA dieses Artikels ist nur für die Arbeit auf einem Netting-Konten gedacht.
Kernpunkte
Um die Idee hinter dem Handelssystem zu verstehen, ist es notwendig, jedes Element von Elder-Ray zu verstehen: Preis, EMA, Hochs und Tiefs von Bulls Power und Bears Power jeder Bar, sowie die Stärke von Bulls und Bears.
- Preis — aktuelle Vereinbarung über den Wert einer Finanzanlage. Alle Käufe werden getätigt, während der Preisanstieg erwartet wird, während alle Verkäufe in Erwartung eines Preisverfalls getätigt werden. Ein Handel kann nur dann durchgeführt werden, wenn es eifrige Käufer und Verkäufer gibt.
- EMA — exponentieller gleitender Durchschnitt. Er spiegelt die durchschnittliche Vereinbarung über einen Finanzanlage für einen bestimmten Zeitraum wider. So ist beispielsweise die EMA(13) auf D1 eine durchschnittliche Vereinbarung über den Finanzanlage der letzten 13 Tage. Warum ist es besser, einen exponentiellen als einen einfachen gleitenden Durchschnitt zu verwenden? A. Elder beantwortete diese Frage in Abschnitt 4.2 ("Moving Averages") seines Buches. Kurz gesagt, die EMA ist empfindlicher gegenüber Trendänderungen als ein einfacher Durchschnitt.
- Bulls Power Maximum zeigt die maximale Stärke von Bulls einer bestimmten Bar. Wenn der Preis steigt, machen die Bullen Gewinn, daher kaufen die Bullen, bis der Preis das maximale Niveau erreicht. Bulls Power Maximum ist ein Moment, in dem die Bullen den Preis nach oben treiben wollen, aber sie haben kein Geld mehr.
- Bears Power Minimum zeigt die maximale Stärke der Bären einer bestimmten Bar. Bären machen Gewinn, wenn der Preis sinkt und verkaufen daher, bis der Preis sein Minimum erreicht. Bears Power Minimum ist ein Moment, in dem Bären den Preis weiter nach unten bewegen wollen, aber nicht mehr dazu in der Lage sind.
- Bulls Power zeigt die Fähigkeit von Bullen, den Preis über die durchschnittliche Vereinbarung der Finanzanlage zu erhöhen. In der Regel liegt die Stärke der Bullen über Null. Wenn er unter Null ist, dann bedeutet das, dass die Bullen in Panik sind und kurz davor stehen, ihre Kraft zu verlieren.
- Bears Power spiegelt die Fähigkeit der Bären wider, den Preis unter die durchschnittliche Vereinbarung der Finanzanlage zu senken. Normalerweise liegt die Stärke der Bären unter Null. Wenn sie über Null ist, dann sind die Bullen zu stark, und die Bären sind dabei, ihre Kraft zu verlieren.
Option 1: Alle Indikatoren auf einem einzigen Chart
Wir werden Futures und Aktien im Zeitrahmen von D1 untersuchen. Alle drei Indikatoren (Bulls Power, Bears Power und EMA) werden auf einem einzigen Chart platziert. Der Glättungslänge aller Indikatoren beträgt 13.
Kaufregel
- Trend steigt (gemäß EMA);
- Bears Power ist kleiner Null, aber steigt;
- Ein Pending-Buy-Stop-Order wird über dem Maximum der letzten zwei Tage platziert, während ein Sicherheits-Stop-Loss unter dem letzten Minimum platziert wird.
CAT, Tagesbars Kaufsignale
Verkaufsregel
- Trend fällt (gemäß EMA);
- Bulls Power ist größer Null und fällt;
- Ein Pending-Sell-Stop-Order wird unter dem Minimum der letzten zwei Tage platziert, während ein Sicherheits-Stop-Loss über dem letzten Maximum platziert wird.
CAT, Tagesbars Verkaufssignale
Handelsregeln
Betrachtet man die Bilder 1 und 2, so zeigt sich, dass in der Option "Alle Indikatoren auf einem einzigen Chart" die Kauf- und Verkaufssignale bei einem Rücksetzer während eines stabilen Trends ausgelöst werden. Es gibt einige derartige günstige Momente, zumal der analysierte Zeitrahmen D1 ist. Daher müssen wir in der Option "Alle Indikatoren auf einem einzigen Chart" eine sehr große Anzahl von Instrumenten analysieren, um die Häufigkeit von Transaktionen auf einem Handelskonto zu erhöhen.
Die D1-Charts haben auch einen erheblichen Vorteil: Die Analyse der Steigung des EMA sowie der Indikatoren Bulls Power und Bears Power kann nur einmal täglich durchgeführt werden — wenn eine neue Bar erscheint. Genau so soll das EA funktionieren: W wir warten bei jedem angegebenen Symbol auf eine neue Bar auf D1 und suchen dann nach möglichen Eröffnungsmöglichkeiten.
Da Futures und Aktien nur im Netting-Modus gehandelt werden, können hier nicht gegenläufige Positionen (Hedging) eingesetzt werden, aber wir können das Positionsvolumen erhöhen. Der EA kann nur mit dem aktuellen Symbol oder mit mehreren in der Textdatei gespeicherten Symbolen handeln. Während beim aktuellen Symbol alles klar ist, kann die Auswahl mehrerer Symbole zu folgenden Problemen führen:
- Wir müssen circa hundert Symbole eines Marktes angeben (z.B. nur Wertpapiere);
- Wir müssen viele Symbole aus verschiedenen Märkten (z.B. Futures und Wertpapiere) angeben.
Wie wählt man alle Symbole eines Marktes aus? Angenommen, wir haben das Symbol "CAT" mit folgendem Pfad: "Börsen\USA\NYSE/NASDAQ(SnP100)\CAT".
Angenommen, dieses Symbol passt zu uns, und wir möchten alle anderen Instrumente dieses Bereichs "\NYSE/NASDAQ(SnP100)\" auswählen. In diesem Fall können wir folgendes tun:
- Wir öffnen den Chart dieses Symbols;
- Starten das Skript (nennen wir es Symbols on the specified path.mq5), dem der Symbolpfad übergeben wird (im obigen Beispiel für das Symbol "CAT" ist es "Stock Markets\USA\NYSE/NASDAQ(SnP100)") und wir speichern alle Symbole dieses Pfads in der Textdatei. Die Textdatei soll im Verzeichnis Common gespeichert werden;
- Bleibt nur noch, den Namen der Textdatei in den EA-Einstellungen festzulegen.
Die Implementierung des Skripts Symbols on the specified path.mq5 ist im Folgenden beschrieben.
Erstellen des EAs. Option 1: Alle Indikatoren auf einem einzigen Chart
Symbols on the specified path.mq5 — Skript, das zum Abrufen der Textdatei mit den Symbolen verwendet werden soll.
HINWEIS: nur der Text (in Englisch) "Alles ist in Ordnung. Es gab keine Fehler" in der Registerkarte Experten garantiert, dass das Skript erfolgreich durchgelaufen ist, und die erzeugte Datei mit Symbolen kann vom EA verwendet werden!
Um den Code von Dateioperationen zu verkürzen, wird die Klasse CFileTxt verbunden, und die Arbeit mit der Textdatei wird von m_file_txt — CFileTxt Klassenobjekt durchgeführt. Das Skript führt folgende sieben Schritte durch:
//+------------------------------------------------------------------+ //| Symbols on the specified path.mq5 | //| Copyright © 2018, Vladimir Karputov | //| http://wmua.ru/slesar/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2018, Vladimir Karputov" #property link "http://wmua.ru/slesar/" #property version "1.002" #property script_show_inputs //--- #include <Files\FileTxt.mqh> CFileTxt m_file_txt; // Objekt der Textdatei //--- Eingabeparameter input string InpFileName="Enter a unique name.txt"; // Dateiname //+------------------------------------------------------------------+ //| Script Programm Start Funktion | //+------------------------------------------------------------------+ void OnStart() { //--- SCHRITT 1 string current_path=""; if(!SymbolInfoString(Symbol(),SYMBOL_PATH,current_path)) { Print("ERROR: SYMBOL_PATH"); return; } //--- SCHRITT 2 string sep_="\\"; // Ein Separator als Zeichen ushort u_sep_; // Der Zahlencode des Separatorzeichens string result_[]; // Ein Array für die Zeichenketten //--- Abfrage des Separator-Zeichens u_sep_=StringGetCharacter(sep_,0); //--- Aufteilen der Zeichenkette in Teile int k_=StringSplit(current_path,u_sep_,result_); //--- SCHRITT 3 //--- Ausgabe der erhaltenen Zeichenketten if(k_>0) { current_path=""; for(int i=0;i<k_-1;i++) current_path=current_path+result_[i]+sep_; } //--- SCHRITT 4 string symbols_array[]; int symbols_total=SymbolsTotal(false); for(int i=0;i<symbols_total;i++) { string symbol_name=SymbolName(i,false); string symbol_path=""; if(!SymbolInfoString(symbol_name,SYMBOL_PATH,symbol_path)) continue; if(StringFind(symbol_path,current_path,0)==-1) continue; int size=ArraySize(symbols_array); ArrayResize(symbols_array,size+1,10); symbols_array[size]=symbol_name]; } //--- SCHRITT 5 int size=ArraySize(symbols_array); if(size==0) { PrintFormat("ERROR: On path \"%s\" %d symbols",current_path,size); return; } PrintFormat("On path \"%s\" %d symbols",current_path,size); //--- SCHRITT 6 if(m_file_txt.Open(InpFileName,FILE_WRITE|FILE_COMMON)==INVALID_HANDLE) { PrintFormat("ERROR: \"%s\" file in the Data Folder Common folder is not created",InpFileName); return; } //--- SCHRITT 7 for(int i=0;i<size;i++) m_file_txt.WriteString(symbols_array[i]+"\r\n"); m_file_txt.Close(); Print("Everything is fine. There are no errors"); //--- } //+------------------------------------------------------------------+
Algorithmus des Skripts:
- SCHRITT 1: SYMBOL_PATH (Pfad im Symbolbaum) ist für das aktuelle Symbol definiert;
- SCHRITT 2: Der erhaltene Pfad wird mit dem Separator "\" in Teilzeichenketten unterteilt;
- SCHRITT 3: Den aktuellen Pfad ohne die letzte Teilzeichenkette neu zusammensetzen, da er den Symbolnamen enthält;
- SCHRITT 4: Schleife durch alle verfügbaren Symbole; wenn der Pfad des Symbols im Symbolbaum mit dem aktuellen übereinstimmt, wählen Sie den Symbolnamen aus und fügen Sie ihn dem erkannten Symbolarray hinzu;
- SCHRITT 5: Überprüfen der Größe des erkannten Symbolarrays;
- SCHRITT 6: Erstellen der Datei;
- SCHRITT 7: Wir schreiben unser Array der erkannten Symbole in die Datei und schließen sie.
Elder-Ray 1 — EA (oder mehrere EAs) mit den Versionsnummern 1.xxx, die nach der Option 1 handeln werden: alle Indikatoren auf einem einzigen Chart.
So stellen wir das Positionsvolumen ein — das Mindestvolumen kann unterschiedlich sein
Führen wir ein einfaches Experiment durch: Wir überprüfen das Mindestvolumen von Futures und Wertpapieren: Wir Gehen alle Symbole durch, die sich über den gleichen Pfad wie das aktuelle finden lassen (ähnlich wie das Skript Symbols on the specified path.mq5), aber innerhalb der in der Datei gesicherten Symbole und zeigen Statistiken mit den Mindestvolumina an.
Gets minimal volume.mq5 — Skript zur Anzeige von Statistiken mit dem Mindestvolumina der Symbolgruppe. Das Skript durchläuft die Symbolgruppe und sammelt Statistiken (Mindestvolumen, um eine Position zu schließen und Zähler) in einem zweidimensionalen Array:
//--- SCHRITT 4 /* symbols_array[][2]: [*][minimal volume to close a deal] [*][counter] */
Der Code des ganzen Skripts:
//+------------------------------------------------------------------+ //| Gets minimal volume.mq5 | //| Copyright © 2018, Vladimir Karputov | //| http://wmua.ru/slesar/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2018, Vladimir Karputov" #property link "http://wmua.ru/slesar/" #property version "1.000" //+------------------------------------------------------------------+ //| Script Programm Start Funktion | //+------------------------------------------------------------------+ void OnStart() { //--- SCHRITT 1 string current_path=""; if(!SymbolInfoString(Symbol(),SYMBOL_PATH,current_path)) { Print("ERROR: SYMBOL_PATH"); return; } //--- SCHRITT 2 string sep_="\\"; // Ein Separator als Zeichen ushort u_sep_; // Der Zahlencode des Separatorzeichens string result_[]; // Ein Array für die Zeichenketten //--- Abfrage des Separator-Zeichens u_sep_=StringGetCharacter(sep_,0); //--- Aufteilen der Zeichenkette in Teile int k_=StringSplit(current_path,u_sep_,result_); //--- SCHRITT 3 //--- Ausgabe der erhaltenen Zeichenketten if(k_>0) { current_path=""; for(int i=0;i<k_-1;i++) current_path=current_path+result_[i]+sep_; } //--- SCHRITT 4 /* symbols_array[][2]: [*][minimal volume to close a deal] [*][counter] */ double symbols_array[][2]; int symbols_total=SymbolsTotal(false); for(int i=0;i<symbols_total;i++) { string symbol_name=SymbolName(i,false); string symbol_path=""; if(!SymbolInfoString(symbol_name,SYMBOL_PATH,symbol_path)) continue; if(StringFind(symbol_path,current_path,0)==-1) continue; double min_volume=0.0; if(!SymbolInfoDouble(symbol_name,SYMBOL_VOLUME_MIN,min_volume)) continue; int size=ArrayRange(symbols_array,0); bool found=false; for(int j=0;j<size;j++) { if(symbols_array[j][0]==min_volume) { symbols_array[j][1]=symbols_array[j][1]+1; found=true; continue; } } if(!found) { ArrayResize(symbols_array,size+1,10); symbols_array[size][0]=min_volume; symbols_array[size][1]=1.0; } } //--- SCHRITT 5 int size=ArrayRange(symbols_array,0); if(size==0) { PrintFormat("ERROR: On path \"%s\" %d symbols",current_path,size); return; } //--- SCHRITT 6 for(int i=0;i<size;i++) PrintFormat("Minimal volume %.2f occurs %.1f times",symbols_array[i][0],symbols_array[i][1]); Print("Everything is fine. There are no errors"); //--- } //+------------------------------------------------------------------+
Algorithmus des Skripts:
- SCHRITT 1: SYMBOL_PATH (Pfad im Symbolbaum) ist für das aktuelle Symbol definiert;
- SCHRITT 2: Der erhaltene Pfad wird mit dem Separator "\" in Teilzeichenketten unterteilt;
- SCHRITT 3: Den aktuellen Pfad ohne die letzte Teilzeichenkette neu zusammensetzen, da er den Symbolnamen enthält;
- SCHRITT 4: Schleife über alle verfügbaren Symbole; wenn der Pfad des Symbols im Symbolbaum mit dem aktuellen übereinstimmt, erhalten wir das Mindestvolumen des Symbols und führen eine Suche im Array der Symbole durch. Wenn ein solcher Wert bereits vorhanden ist, erhöhen wir den Zähler. Wenn es keinen solchen Wert gibt, schreiben wir ihn in das Array hinzu und setzen den Zähler auf "1.0";
- SCHRITT 5: Überprüfen der Größe des erkannten Symbolarrays;
- SCHRITT 6: Anzeigen der Statistik.
Das Ergebnis der Einführung von Wertpapieren:
Gets minimal volume (CAT,D1) Minimal volume 1.00 occurs 100.0 times
und von Futures:
Gets minimal volume (RTSRIU8,D1) Minimal volume 1.00 occurs 77.0 times
- auf den beiden Märkten ist die Losgröße gleich — 1,0.
Machen wir das System nicht unnötig kompliziert und legen "1.0" als Mindestvolumen fest.
Darstellung der angewandten Indikatoren
Wenn wir einen visualisierten Test im Tester starten, sehen wir die vom EA verwendeten Indikatoren. Wenn der EA jedoch auf dem Chart des Terminals gestartet wird, werden die Indikatoren nicht angezeigt. In diesem Handelssystem möchte ich diese Indikatoren auf dem Chart zur optischen Kontrolle der Arbeit des EA sehen. Es sollte so aussehen:
Wie man sehen kann, habe ich hier für alle Indikatoren benutzerdefinierte Farb- und Linienbreiteneinstellungen verwendet (natürlich erfolgte dies manuell). Für die automatische Darstellung der auf dem Terminalchart verwendeten Indikatoren müssen wir die Indikatoren Moving Average, Bulls Power und Bears Power etwas umschreiben. Ich habe bereits eine ähnliche Sache im Code Custom Moving Average Input Color implementiert — die Indikatorfarbe wurde in die Eingaben aufgenommen: Dieser Eingabeparameter steht beim Erstellen eines Indikators aus einem EA zur Verfügung. Jetzt müssen wir nur noch drei weitere ähnliche Indikatoren entwickeln.
Man kann diese Indikatoren (Custom Moving Average Inputs, Custom Bulls Power Inputs und Custom Bears Power Inputs) aus der CodeBase herunterladen. Kopieren Sie die heruntergeladenen Indikatoren im Stammverzeichnis von [data folder]\MQL5\Indikatoren\.
Elder-Ray 1.001.mq5 — Visualisierung der verwendeten Indikatoren. Jeder kann Farbe und Linienstärke einstellen. Es funktioniert sowohl im Strategie-Tester als auch beim Start des EA auf dem Chart:
Wie wurde das umgesetzt?
Die Hauptbedingung ist das Vorhandensein der Indikatoren Custom Moving Average Inputs, Custom Bulls Power Inputs und Custom Bears Power Inputs in[data folder]\MQL5\Indikatoren\
Das Aussehen und die Periodenlänge der Indikatoren wird in den Eingabeparametern festgelegt und drei Variablen für die Arbeit mit Indikatoren deklariert werden, in denen die Handles der Indikatoren gespeichert werden (handle_iCustom_MA, handle_iCustom_Bulls und handle_iCustom_Bears).
//+------------------------------------------------------------------+ //| Elder-Ray 1.mq5 | //| Copyright © 2018, Vladimir Karputov | //| http://wmua.ru/slesar/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2018, Vladimir Karputov" #property link "http://wmua.ru/slesar/" #property version "1.000" //--- //--- enum ENUM_INPUT_SYMBOLS { INPUT_SYMBOLS_CURRENT=0, // aktuelles Symbol INPUT_SYMBOLS_FILE=1, // Textdatei }; //--- Eingabeparameter input ENUM_INPUT_SYMBOLS InpInputSymbol = INPUT_SYMBOLS_FILE; // arbeitet mit ... input uint InpNumberMinLots = 1; // Höhe des Mindestvolumens //--- Eingabeparameter des nutzerspezifischen gleitenden Durchschnitts input int Inp_MA_ma_period = 13; // MA: Glättungslänge input int Inp_MA_ma_shift = 0; // MA: horizontaler Versatz input ENUM_MA_METHOD Inp_MA_ma_method = MODE_EMA; // MA: Glättungstyp input ENUM_APPLIED_PRICE Inp_MA_applied_price = PRICE_CLOSE; // MA: Preistyp input color Inp_MA_Color = clrChartreuse; // MA: Farbe input int Inp_MA_Width = 2; // MA: Breite //--- Eingabeparameter von Bulls Power Inputs input int Inp_Bulls_ma_period = 13; // Bulls Power: Glättungslänge input color Inp_Bulls_Color = clrBlue; // Bulls Power: Farbe input int Inp_Bulls_Width = 2; // Bulls Power: Breite //--- Eingabeparameter von Bears Power Inputs input int Inp_Bears_ma_period = 13; // Bears Power: Glättungslänge input color Inp_Bears_Color = clrRed; // Bears Power: Farbe input int Inp_Bears_Width = 2; // Bears Power: Breite int handle_iCustom_MA; // Variable des Handles für den iCustom-Indikator int handle_iCustom_Bulls; // Variable des Handles für den iCustom-Indikator int handle_iCustom_Bears; // Variable des Handles für den iCustom-Indikator //+------------------------------------------------------------------+ //| Initialisierungsfunktion des Experten | //+------------------------------------------------------------------+ int OnInit()
In OnInit() erstellen wir Handles der benutzerdefinierten Indikatoren (iCustom wird verwendet), und die erstellten Indikatoren werden auf dem Chart gestartet (mittels ChartIndicatorAdd).
//+------------------------------------------------------------------+ //| Initialisierungsfunktion des Experten | //+------------------------------------------------------------------+ int OnInit() { //--- Erstellen des Handles des Indikators iCustom handle_iCustom_MA=iCustom(Symbol(),Period(),"Custom Moving Average Inputs", Inp_MA_ma_period, Inp_MA_ma_shift, Inp_MA_ma_method, Inp_MA_Color, Inp_MA_Width, Inp_MA_applied_price); //--- wenn die Erstellung fehlschlug if(handle_iCustom_MA==INVALID_HANDLE) { //--- Grund des Fehlers und die Ausgabe der Fehlernummer PrintFormat("Failed to create handle of the iCustom indicator (\"Custom Moving Average Inputs\") for the symbol %s/%s, error code %d", Symbol(), EnumToString(Period()), GetLastError()); //--- Der Indikator wurde zu früh beendet return(INIT_FAILED); } //--- Erstellen des Handles des Indikators iCustom handle_iCustom_Bulls=iCustom(Symbol(),Period(),"Custom Bulls Power Inputs", Inp_Bulls_ma_period, Inp_Bulls_Color, Inp_Bulls_Width); //--- wenn die Erstellung fehlschlug if(handle_iCustom_Bulls==INVALID_HANDLE) { //--- Grund des Fehlers und die Ausgabe der Fehlernummer PrintFormat("Failed to create handle of the iCustom indicator (\"Custom Bulls Power Inputs\") for the symbol %s/%s, error code %d", Symbol(), EnumToString(Period()), GetLastError()); //--- Der Indikator wurde zu früh beendet return(INIT_FAILED); } //--- Erstellen des Handles des Indikators iCustom handle_iCustom_Bears=iCustom(Symbol(),Period(),"Custom Bears Power Inputs", Inp_Bears_ma_period, Inp_Bears_Color, Inp_Bears_Width); //--- wenn die Erstellung fehlschlug if(handle_iCustom_Bears==INVALID_HANDLE) { //--- Grund des Fehlers und die Ausgabe der Fehlernummer PrintFormat("Failed to create handle of the iCustom indicator (\"Custom Bears Power Inputs\") for the symbol %s/%s, error code %d", Symbol(), EnumToString(Period()), GetLastError()); //--- Der Indikator wurde zu früh beendet return(INIT_FAILED); } ChartIndicatorAdd(0,0,handle_iCustom_MA); int windows_total=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL); ChartIndicatorAdd(0,windows_total,handle_iCustom_Bulls); ChartIndicatorAdd(0,windows_total+1,handle_iCustom_Bears); //--- return(INIT_SUCCEEDED); }
Ressourcen sparen. Elder-Ray 1.010.mq5
Es können etwa hundert analysierte Symbole einer einzelnen Gruppe vorhanden sein. So wird die Frage der RAM-Bedarf relevant, da auf jedem Chart drei Indikatoren laufen sollen. Wie beim Mindestvolumen ist es am besten, den Ressourcenverbrauch des EA zu überprüfen. Gleichzeitig werden wir auch einen kleinen Fortschritt bei der Zusammenstellung unseres EA machen, indem wir den Code zum Lesen der Symbolnamen einer Gruppe aus der Textdatei hinzufügen und mit ihnen arbeiten.
Die Klasse CFileTxt (wir haben sie bereits im Skript Symbols on the specified path.mq5 verwendet) ist im EA enthalten. Ihr Objekt m_file_txt ist für den Zugriff auf die Textdatei und das Lesen von Daten aus der Datei verantwortlich. Wir integrieren auch die Klasse CSymbolInfo. Ihr Objekt m_symbol ist dafür verantwortlich, die Existenz eines Symbols zu überprüfen und es in das Fenster Market Watch aufzunehmen. Warum habe ich CSymbolInfo gewählt, anstatt die Funktion über SymbolInfoInteger und SymbolSelect zu implementieren? Alles ist einfach: In der Klasse CSymbolInfo ist der gesamte Code zum Überprüfen, Hinzufügen oder Informieren von Fehlern innerhalb der Klasse verborgen, und wir müssen nur die folgenden drei Zeichenketten dem EA hinzufügen:
if(!m_symbol.Name(name)) // bestimme Symbolnamen { m_file_txt.Close(); return(INIT_FAILED); }
An dieser Stelle sollten wir uns daran erinnern, dass alle Symbole eines EAs mit mehreren Währungen dem Fenster Market Watch hinzugefügt werden sollten: Die benötigten Symbole in der Marktübersicht auswählen für Multi-Währungs Expert Advisor mit mehreren Währungen aktivieren.
So arbeitet das EA nach folgendem Algorithmus: Eine Textdatei wird in OnInit() geöffnet, ein Symbol wird gelesen und es wird sofort versucht, die drei benutzerdefinierte Indikatoren (Custom Moving Average Inputs, Custom Bulls Power Inputs und Custom Bears Power Inputs) für das gelesene Symbol mit dem aktuellen Zeitrahmen zu erstellen. Wenn dieser Versuch fehlschlägt (z.B. aufgrund der unzureichenden Anzahl von Bars zum Erstellen der benutzerdefinierte gleitenden Durchschnitts), fahren wir in der Schleife weiter fort. Wenn die Indikatoren erstellt werden, schreiben wir den Symbolnamen in m_symbols_array, während die Handles der drei Indikatoren dem dreidimensionalen m_handles_array übergeben werden. Somit enthalten beide Arrays in der ersten Dimension synchron die Symbolnamen und die Handle des jeweiligen Symbols:
//--- if(m_file_txt.Open(InpFileName,FILE_READ|FILE_COMMON)==INVALID_HANDLE) { PrintFormat("ERROR: \"%s\" file in the Data Folder Common folder is not open: %d",InpFileName,GetLastError()); return(INIT_FAILED); } //--- Objekt der Symbolinfo. ODER der Textdatei if(InpInputSymbol==INPUT_SYMBOLS_FILE) { //--- Lesen der Daten aus der Datei int counter=0; while(!m_file_txt.IsEnding()) { counter++; Print("Iteration ",counter); string name=m_file_txt.ReadString(); if(!m_symbol.Name(name)) // bestimme Symbolnamen { m_file_txt.Close(); return(INIT_FAILED); } int MA,Bulls,Bears; if(!CreateHandles(name,Period(),MA,Bulls,Bears)) continue; //return(INIT_FAILED); int size=ArraySize(m_symbols_array); ArrayResize(m_symbols_array,size+1,10); ArrayResize(m_handles_array,size+1,10); m_symbols_array[size]=name; m_handles_array[size][0]=MA; m_handles_array[size][1]=Bulls; m_handles_array[size][2]=Bears; } m_file_txt.Close(); } else { if(!m_symbol.Name(Symbol())) // Festlegen des Symbolnamens return(INIT_FAILED); } //--- ChartIndicatorAdd(0,0,handle_iCustom_MA);
Die Handles der Indikatoren werden in CreateHandles() erstellt.
Jetzt wurde der Speicherverbrauch über TERMINAL_MEMORY_USED und visuell im Task-Manager von Windows 10 gemessen. Um den Speicherbedarf schrittweise zu definieren, wurden in der Version 1.010 einige Zeichenketten bewusst deaktiviert (auskommentiert). In der endgültigen Version 1.010 wurden alle Zeichenketten zum Hinzufügen von Symbolen und zum Erstellen von Indikatoren nicht auskommentiert.
- Der EA wird wie gewohnt gestartet — durch sein Starten auf dem Chart:
- Der Start des Terminals (Symbole aus der Textdatei wurden noch nicht in das Fenster Market Watch aufgenommen) — TERMINAL_MEMORY_USED 345 MB, Task-Manager von 26 bis 90 MB;
- Nach dem Hinzufügen von etwa hundert Symbolen zum Fenster Market Watch — TERMINAL_MEMORY_USED 433 MB, Aufgabenmanager + 10 MB;
- Nach dem Erstellung von drei Indikatoren pro Symbol — TERMINAL_MEMORY_USED 5523 MB, Task-Manager 300 MB.
- Den Tester starten (keine Visualisierung) — TERMINAL_MEMORY_USED 420 MB, im Task-Manager — 5 GB.
Fazit: TERMINAL_MEMORY_USED zeigt den Gesamtbedarf von RAM und Festplattenspeicher an. Da der RAM-Bedarf im Normalbetrieb 300 MB nicht überschreitet, ist es nicht notwendig, Ressourcen zu sparen.
Trend (EMA) ist..
Das Hauptziel des EAs ist die Definition der Trendrichtung (EMA). Ein Trend kann nicht durch eine einzelne Bar. Wir brauchen die Daten mehrerer Bars. Markieren wir diesen Parameter als "bars". Nachfolgend finden sieht man Wertpapiercharts — CAT, MCD und V. Der Trend ist wie folgt zu definieren: "+1" für Aufwärtstrend, "0" für keinen Trend und "-1" für Abwärtstrend.
Der Chart von "CAT" zeigt den Trend "0" (4 bullische und 4 bearische Bars, während die Veränderung der restlichen Bars unbedeutend ist), "MCD" zeigt den Trend "-1" (8 bearish Bars, während sich andere im ungewissen Zustand befinden). Schließlich zeigt "V" den Trend "0" an (6 Aufwärtsbars, während 2 oder 3 Abwärtsbars gibt). Möglicherweise benötigen wir einen Parameter 'different' — die minimale Differenz zwischen den Indikatorwerten der benachbarten Bars.
Definietion des Trends. Elder-Ray 1.020.mq5
Trend Existenzbedingungen: Der EMA mehrerer Bars sollten in eine bestimmte Richtung gehen. Die beiden zusätzlichen Parameter sollten wahrscheinlich danach überprüft werden:
- different — Mindestabstand zwischen den Indikatorwerten benachbarter Bars;
- trend percentage — Mindestprozentsatz der Indikatorwerte in eine Richtung (auf dem Screenshot: CAT Symbol — EMA Indikator ist entgegengesetzt des Segments der Bars gerichtet, während bei MCD alle (oder fast alle) EMA Indikatorwerte dieselbe Richtung haben).
Ergänzungen und Löschungen in der Version 1.020:
- Der Parameter different ist nicht implementiert — der Mindestabstand zwischen den Indikatorwerten benachbarter Bars;
- "-" Die Enumeration ENUM_INPUT_SYMBOLS — der EA soll nur mit Symbolen aus der Textdatei arbeiten;
- "+" Der Parameter Anzahl der Bars zur Identifizierung des Trends — Anzahl der Bars zur Identifizierung eines Trends durch EMA;
- "+" Der Parameter minimum percentage of the trend — Mindestqualität des Trends (bestimmte Richtung);
- "+" m_prev_bars Array — zum Speichern der vorherigen Baröffnungszeit;
- "+" 60 Sekunden Timer — Prüfung auf eine neue Bar.
Der Block zum Erfassen einer neuen Bar und zum Definieren der Trendrichtung.
In OnTimer() durchlaufen wir das Array der Symbole (m_symbols_array), das alle 60 Sekunden aus der Textdatei geladen wird und fangen eine neue Bar eines Symbols aus dem Array ab. Abfrage von ausreichenden EMA-Indikatorwerten, um einen Trend im Array ema_array zu erkennen. Führen wir die Berechnung durch: Anzahl der Bars, um die der Indikator nach oben und unten bewegte. Ausdrucken des erkannten Musters.
//+------------------------------------------------------------------+ //| Timer Funktion | //+------------------------------------------------------------------+ void OnTimer() { //--- int size=ArraySize(m_symbols_array); for(int i=0;i<size;i++) { //--- wir arbeiten nur, wenn einen Neue Bar erscheint datetime PrevBars=m_prev_bars[i]; datetime time_0=iTime(m_symbols_array[i],Period(),0); if(time_0==PrevBars) continue; m_prev_bars[i]=time_0; double ema_array[]; ArraySetAsSeries(ema_array,true); /* m_handles_array[*][MA][Bulls][Bears] */ if(!iMAGetArray(m_handles_array[i][0],0,InpBarsEMA+2,ema_array)) continue; int upwards=0; int downward=0; for(int j=1;j<InpBarsEMA+1;j++) { if(ema_array[j]>ema_array[j+1]) upwards++; else if(ema_array[j]<ema_array[j+1]) downward++; } if((double)upwards>InpBarsEMA*InpMinTrendPercentage/100.0) Print("On ",m_symbols_array[i]," trend UP!"); else if((double)downward>InpBarsEMA*InpMinTrendPercentage/100.0) Print("On ",m_symbols_array[i]," trend DOWN!"); else Print("On ",m_symbols_array[i]," trend NONE!"); } }
Ergebnisse der Trendsuche. Einstellungen: Anzahl der Bars zur Identifizierung des Trends — 6, Mindestprozentsatz des Trends — 75%. Vergessen wir nicht, dass die Bar Null, wenn eine neue Bar erscheint, hierbei nicht berücksichtigt wird:
Einstellungen der Pending-Orders (Buy-Stop oder Sell-Stop). Elder-Ray 1.030.mq5
Ist es möglich, den Fehler von zu wenig Geld bei der Eröffnung einer Position zu vermeiden? Da wir mit Pending-Orders arbeiten, lautet die Antwort "Nein". Es gibt vielleicht halbherzige Maßnahmen, aber nichts kann garantiert werden. Der Hauptgrund ist, dass niemand weiß, zu welchem Zeitpunkt eine Pending-Order aktiviert wird und ob sie überhaupt aktiviert wird.
Nun, da der EA weiß, wie man einen Trend definiert, müssen wir die Regeln für Kaufen und Verkaufen verwenden, um Punkte zu finden, die geeignet sind, eine Pending-Order zu setzen. Für KAUFEN gibt es eine einfache Überprüfung: Bears Power der Bar #1 sollte kleiner als Null und größer als Bears Power der Bar #2 sein. Für VERKAUFEN ist die Bedingung umgekehrt: Bulls Power der Bar #1 sollte größer Null sein und kleiner als Bears Power der Bar #2.
Alexander Elder beschrieb die Strategie, wies darauf hin, dass für die Eröffnung einer Kaufposition ein schützender Stop-Loss unter dem letzten Tief platziert werden sollte, während für die Eröffnung einer Verkaufsposition ein Stop-Loss über dem letzten Hoch platziert werden sollte. Das Konzept vom "Letzten" ist ziemlich verschwommen, also habe ich die beiden Optionen überprüft:
- Festlegung eines Stop-Loss durch die Preise der Bar #1 und
- Eine Suche nach dem nächstgelegenen Extremum.
Die Option 1 erwies sich als unbrauchbar — Stop-Loss wurde zu oft ausgelöst. Deshalb habe ich die Option 2 (Suche nach dem nächsten Extremum) im Elder-Ray 1.030.mq5 EA-Code implementiert.
Die Suche nach dem nächstgelegenen Extremum
Die Funktion sucht nach dem nächstgelegenen Extremum:
Wurde kein Extremum gefunden oder gab es einen Fehler wird 'false' zurück gegeben:
//+------------------------------------------------------------------+ //| Finde das nächstgelegene Extremum | //+------------------------------------------------------------------+ bool NearestExtremum(ENUM_SERIESMODE type,double &price) { if(type==MODE_LOW) { //--- Suche des nächstgelegenen Minimums double low_array[]; ArraySetAsSeries(low_array,true); int copy=CopyLow(m_symbol.Name(),Period(),0,100,low_array); if(copy==-1) return(false); double low=DBL_MAX; for(int k=0;k<copy;k++) { if(low_array[k]<low) low=low_array[k]; else if(low_array[k]>low) break; } if(low!=DBL_MAX) { price=low; return(true); } } else if(type==MODE_HIGH) { //--- Suche des nächstgelegenen Maximums double high_array[]; ArraySetAsSeries(high_array,true); int copy=CopyHigh(m_symbol.Name(),Period(),0,100,high_array); if(copy==-1) return(false); double high=DBL_MIN; for(int k=0;k<copy;k++) { if(high_array[k]>high) high=high_array[k]; else if(high_array[k]<high) break; } if(high!=DBL_MIN) { price=high; return(true); } } //--- return(false); }
Ergänzungen und Löschungen in der Version 1.030:
- "+" Handelsklasse CPositionInfo (und m_position ist deren Objekt);
- "+" Handelsklasse CTrade (und m_trade ist deren Objekt);
- "+" Handelsklasse COrderInfo (und m_order ist deren Objekt);
- "+" Trailing-Stop (Parameter Trailing Stop und Trailing Step);
- "+" magic number — eindeutige EA-Kennung;
- "+" OnInit() — check the account type: if this is a hedging account, disable trading and unload with the error;
- OnInit() — Reihenfolge der Darstellung geändert: Wenn der Strategie-Tester gestartet wird und das aktuelle Symbol (das Symbol, mit dem der EA gestartet wird) in der Textdatei vorhanden ist, werden dem aktuellen Symbol keine Indikatoren hinzugefügt (ChartIndicatorAdd wird nicht angewendet);
- OnTimer() — Code zur Bestätigung des Signals und Handelsoperationen hinzugefügt, um Pending-Orders Buy-Stop und Sell-Stop zu setzen;
- OnTradeTransaction() — hinzufügen des Kompensationsmechanismus, wenn es zu einer Positionsumkehr oder einem teilweisen Schließung kam;
- "+" wenn der Kompensationsalgorithmus aktiviert ist, wird KEIN Stop-Loss in OnTradeTransaction() gesetzt. Stattdessen wird das Trailing verbessert: Wird bei der Überprüfung von Positionen eine Position ohne Stop-Loss erkannt, wird ein Stop-Loss nach der Regel des nächstgelegenen Extrempunkts gesetzt;
- "+" hinzufügen der Variablen m_magic_compensation — Identifikator für Handelskompensationen hinzugefügt.
Um Situationen zu bewältigen, in denen eine Pending Order entgegen der aktuellen Position ausgelöst wird, müssen wir drei typische Situationen berücksichtigen, nachdem die Pending-Order Buy-Stop ausgelöst wurde:
# | Offene Position, Volumen | Ausgelöste Pending-Order, Volumen | Resultierende Position, Volumen | Hinweis zum Auslösemoment der Pending-Order | Magicnummer der vorherigen Position | Kompensationsalgorithmus (NB: Magicnummer wurde vor der Kompensation auf m_magic_compensation gesetzt) | Neue Magicnummer der Position |
---|---|---|---|---|---|---|---|
1 | Sell 1.0 | Buy Stop 3.0 | Buy 2.0 | Positionsumkehr (DEAL_ENTRY_INOUT Richtung des Deals) | m_magic | Zusätzlich offene Kaufvolumen 3.0 — 2.0 = 1.0 | m_magic_compensation |
2 | Sell 1.0 | Buy Stop 1.0 | --- | Position vollständig geschlossen (DEAL_ENTRY_OUT Richtung des Deals) | m_magic | Suche nach einer Position. Gibt es keine Position, wird ein Kaufposition mit dem Volumen 1.0 eröffnet | m_magic_compensation |
3 | Sell 2.0 | Buy Stop 1.0 | Sell 1.0 | Teilweises Schließen einer Position (DEAL_ENTRY_OUT Richtung des Deals) | m_magic | Suche nach einer Position. Gibt es eine offene Position, entgegengesetzt zum Kauf, wird eine Kaufposition mit dem Volumen 1.0 + 1.0 = 2.0 eröffnet | m_magic_compensation |
Für jeden der drei Fälle habe ich einen Ausdruck der Deals und Aufträge erstellt (Test auf einem realen Netting-Konto sowie im Tester). Um einen Bericht über Deals und Orders zu erstellen, habe ich den Code aus dem Skript History Deals and Orders verwendet.
#1: Sell 1.0 -> Buy Stop 3.0
Sell 1.0, Buy Stop 3.0 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |1 |0 |2016.12.08 00:00:00 |1481155200000 |DEAL_TYPE_BALANCE |DEAL_ENTRY_IN |0 |DEAL_REASON_CLIENT |0 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |0.00 |0.00000 |0.00 |0.00 |50000.00 | | | Order 0 wurde in der Handelshistorie im Zeitintervall 2010.08.07 11:06:20 und 2018.08.10 00:00:00 gefunden Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |2 |2 |2016.12.08 00:00:00 |1481155200100 |DEAL_TYPE_SELL |DEAL_ENTRY_IN |15489 |DEAL_REASON_EXPERT |2 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |79.31 |0.00 |0.00 |0.00 |V | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |2 |2016.12.08 00:00:00 |ORDER_TYPE_SELL |ORDER_STATE_FILLED |2016.12.08 00:00:00 |2016.12.08 00:00:00 |1481155200100 |1481155200100 |ORDER_FILLING_FOK |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |15489 |ORDER_REASON_EXPERT |2 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |1.00 |0.00 |79.31 |0.00 |0.00 |79.39 |0.00 |Symbol |Comment |Extarnal id |V | | Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |3 |3 |2016.12.08 17:27:37 |1481218057877 |DEAL_TYPE_BUY |DEAL_ENTRY_INOUT |15489 |DEAL_REASON_EXPERT |2 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |3.00 |79.75 |0.00 |0.00 |-0.44 |V | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |3 |2016.12.08 14:30:00 |ORDER_TYPE_BUY_STOP |ORDER_STATE_FILLED |2016.12.08 14:30:00 |2016.12.08 17:27:37 |1481207400100 |1481218057877 |ORDER_FILLING_RETURN |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |15489 |ORDER_REASON_EXPERT |2 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |3.00 |0.00 |79.74 |75.17 |0.00 |79.74 |0.00 |Symbol |Comment |Extarnal id |V | | Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |4 |4 |2016.12.09 23:59:00 |1481327940000 |DEAL_TYPE_SELL |DEAL_ENTRY_OUT |0 |DEAL_REASON_CLIENT |2 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |2.00 |79.13 |0.00 |0.00 |-1.24 |V |end of test | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |4 |2016.12.09 23:59:00 |ORDER_TYPE_SELL |ORDER_STATE_FILLED |2016.12.09 23:59:00 |2016.12.09 23:59:00 |1481327940000 |1481327940000 |ORDER_FILLING_FOK |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |0 |ORDER_REASON_CLIENT |2 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |2.00 |0.00 |79.13 |0.00 |0.00 |79.13 |0.00 |Symbol |Comment |Extarnal id |V |end of test |
#2: Sell 1.0 -> Buy Stop 1.0
Sell 1.0, Buy Stop 1.0 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |1 |0 |2016.12.08 00:00:00 |1481155200000 |DEAL_TYPE_BALANCE |DEAL_ENTRY_IN |0 |DEAL_REASON_CLIENT |0 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |0.00 |0.00000 |0.00 |0.00 |50000.00 | | | Order 0 wurde in der Handelshistorie im Zeitintervall 2010.08.07 11:06:20 und 2018.08.10 00:00:00 gefunden Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |2 |2 |2016.12.08 00:00:00 |1481155200100 |DEAL_TYPE_SELL |DEAL_ENTRY_IN |15489 |DEAL_REASON_EXPERT |2 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |79.31 |0.00 |0.00 |0.00 |V | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |2 |2016.12.08 00:00:00 |ORDER_TYPE_SELL |ORDER_STATE_FILLED |2016.12.08 00:00:00 |2016.12.08 00:00:00 |1481155200100 |1481155200100 |ORDER_FILLING_FOK |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |15489 |ORDER_REASON_EXPERT |2 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |1.00 |0.00 |79.31 |0.00 |0.00 |79.39 |0.00 |Symbol |Comment |Extarnal id |V | | Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |3 |3 |2016.12.08 17:27:37 |1481218057877 |DEAL_TYPE_BUY |DEAL_ENTRY_OUT |15489 |DEAL_REASON_EXPERT |2 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |79.75 |0.00 |0.00 |-0.44 |V | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |3 |2016.12.08 14:30:00 |ORDER_TYPE_BUY_STOP |ORDER_STATE_FILLED |2016.12.08 14:30:00 |2016.12.08 17:27:37 |1481207400100 |1481218057877 |ORDER_FILLING_RETURN |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |15489 |ORDER_REASON_EXPERT |2 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |1.00 |0.00 |79.74 |75.17 |0.00 |79.74 |0.00 |Symbol |Comment |Extarnal id |V | |
#3: Sell 2.0 -> Buy Stop 1.0
Sell 2.0, Buy Stop 1.0 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |1 |0 |2016.12.08 00:00:00 |1481155200000 |DEAL_TYPE_BALANCE |DEAL_ENTRY_IN |0 |DEAL_REASON_CLIENT |0 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |0.00 |0.00000 |0.00 |0.00 |50000.00 | | | Order 0 wurde in der Handelshistorie im Zeitintervall 2010.08.07 11:06:20 und 2018.08.10 00:00:00 gefunden Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |2 |2 |2016.12.08 00:00:00 |1481155200100 |DEAL_TYPE_SELL |DEAL_ENTRY_IN |15489 |DEAL_REASON_EXPERT |2 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |2.00 |79.31 |0.00 |0.00 |0.00 |V | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |2 |2016.12.08 00:00:00 |ORDER_TYPE_SELL |ORDER_STATE_FILLED |2016.12.08 00:00:00 |2016.12.08 00:00:00 |1481155200100 |1481155200100 |ORDER_FILLING_FOK |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |15489 |ORDER_REASON_EXPERT |2 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |2.00 |0.00 |79.31 |0.00 |0.00 |79.39 |0.00 |Symbol |Comment |Extarnal id |V | | Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |3 |3 |2016.12.08 17:27:37 |1481218057877 |DEAL_TYPE_BUY |DEAL_ENTRY_OUT |15489 |DEAL_REASON_EXPERT |2 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |79.75 |0.00 |0.00 |-0.44 |V | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |3 |2016.12.08 14:30:00 |ORDER_TYPE_BUY_STOP |ORDER_STATE_FILLED |2016.12.08 14:30:00 |2016.12.08 17:27:37 |1481207400100 |1481218057877 |ORDER_FILLING_RETURN |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |15489 |ORDER_REASON_EXPERT |2 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |1.00 |0.00 |79.74 |75.17 |0.00 |79.74 |0.00 |Symbol |Comment |Extarnal id |V | | Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |4 |4 |2016.12.09 23:59:00 |1481327940000 |DEAL_TYPE_BUY |DEAL_ENTRY_OUT |0 |DEAL_REASON_CLIENT |2 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |79.13 |0.00 |0.00 |0.18 |V |end of test | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |4 |2016.12.09 23:59:00 |ORDER_TYPE_BUY |ORDER_STATE_FILLED |2016.12.09 23:59:00 |2016.12.09 23:59:00 |1481327940000 |1481327940000 |ORDER_FILLING_FOK |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |0 |ORDER_REASON_CLIENT |2 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |1.00 |0.00 |79.13 |0.00 |0.00 |79.13 |0.00 |Symbol |Comment |Extarnal id |V |end of test |
Unten ist noch ein weiterer Fall von einem realen Konto und in Echtzeit (nicht im Tester): die Marktorder Kaufen mit dem Volumen von 2,0 (Buy Trading Order generiert zwei Deals mit dem Volumen von 1,0 — 20087494 und 20087495), dann wurde ein Sell-Limit mit dem Volumen von 2,0 platziert, um den Gewinn mitzunehmen und die Position zu schließen. Etwas später wurde dieses Verkaufslimit in zwei Malen geschlossen (Deals 20088091 und 20088145). Der Ausdruck:
Buy 2.0, Sell limit 2.0 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |20087494 |29080489 |2018.08.10 07:23:34 |1533885814000 |DEAL_TYPE_BUY |DEAL_ENTRY_IN |0 |DEAL_REASON_CLIENT |29080489 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |14595 |-0.10 |0.00 |0.00 |RTSGZU8 | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |29080489 |2018.08.10 07:23:34 |ORDER_TYPE_BUY |ORDER_STATE_FILLED |2018.08.10 07:23:34 |2018.08.10 07:23:34 |1533885814000 |1533885814000 |ORDER_FILLING_RETURN |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |0 |ORDER_REASON_CLIENT |29080489 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |2.00 |0.00 |0 |0 |0 |14588 |0 |Symbol |Comment |External id |RTSGZU8 | |13_31861873584 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |20087495 |29080489 |2018.08.10 07:23:34 |1533885814000 |DEAL_TYPE_BUY |DEAL_ENTRY_IN |0 |DEAL_REASON_CLIENT |29080489 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |14595 |-0.10 |0.00 |0.00 |RTSGZU8 | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |29080489 |2018.08.10 07:23:34 |ORDER_TYPE_BUY |ORDER_STATE_FILLED |2018.08.10 07:23:34 |2018.08.10 07:23:34 |1533885814000 |1533885814000 |ORDER_FILLING_RETURN |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |0 |ORDER_REASON_CLIENT |29080489 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |2.00 |0.00 |0 |0 |0 |14588 |0 |Symbol |Comment |External id |RTSGZU8 | |13_31861873584 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |20088091 |29080662 |2018.08.10 08:03:08 |1533888188000 |DEAL_TYPE_SELL |DEAL_ENTRY_OUT |0 |DEAL_REASON_CLIENT |29080489 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |14626 |-0.10 |0.00 |0.46 |RTSGZU8 | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |29080662 |2018.08.10 07:27:19 |ORDER_TYPE_SELL_LIMIT |ORDER_STATE_FILLED |2018.08.10 07:27:19 |2018.08.10 08:05:42 |1533886039000 |1533888342000 |ORDER_FILLING_RETURN |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |0 |ORDER_REASON_CLIENT |29080489 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |2.00 |0.00 |14626 |0 |0 |14624 |0 |Symbol |Comment |External id |RTSGZU8 | |13_31862155871 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |20088145 |29080662 |2018.08.10 08:05:42 |1533888342000 |DEAL_TYPE_SELL |DEAL_ENTRY_OUT |0 |DEAL_REASON_CLIENT |29080489 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |14626 |-0.10 |0.00 |0.46 |RTSGZU8 | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |29080662 |2018.08.10 07:27:19 |ORDER_TYPE_SELL_LIMIT |ORDER_STATE_FILLED |2018.08.10 07:27:19 |2018.08.10 08:05:42 |1533886039000 |1533888342000 |ORDER_FILLING_RETURN |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |0 |ORDER_REASON_CLIENT |29080489 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |2.00 |0.00 |14626 |0 |0 |14624 |0 |Symbol |Comment |External id |RTSGZU8 | |13_31862155871
Tipps zum Testen von 1.xxx
- Versuchen Sie, Wertpapiere von ungefähr gleichem Wert in der Textdatei zu halten.
- Beim Testen in der Textdatei ist es sinnvoll, es bei einer kleinen Anzahl von Symbolen zu belassen. Der perfekteste Fall ist, es bei einem einzelnen Symbol zu belassen und einen Test nur damit durchzuführen.
Option 2: in Kombination mit dem System "Triple Choice".
In der Option 1 (alle Indikatoren auf einem einzigen Chart) verwendete der Trendindikator den gleichen Zeitrahmen. In der Option 2 läuft der Trendindikator mit einem höheren Zeitrahmen. Somit wird nur ein neuer Parameter hinzugefügt — Trendzeitrahmen (Trend timeframe).
Die Option 2 ist im ES Elder-Ray 2.000.mq5 implementiert.
Dateien, die an den Artikel besprochen wurden:
Name | Dateityp | Beschreibung |
---|---|---|
Symbols on the specified path.mq5 | Skript | Bildet eine Textdatei mit Symbolen einer Gruppe und sichert sie im Verzeichnis Common |
Gets minimal volume.mq5 | Skript | Darstellung der Statistik der Mindestvolumina der Gruppen. |
Elder-Ray 1.001.mq5 | Expert Advisor | Zeigt die Darstellung der verwendeten Indikatoren |
Elder-Ray 1.010.mq5 | Expert Advisor | Beginnt die Arbeit mit der Textdatei Start und erstellt die Indikatoren der Symbole der Datei. Der EA soll den Speicherbedarf darstellen |
Elder-Ray 1.020.mq5 | Expert Advisor | Definition des Trends. Prüfen der Gültigkeit der Trenddefinition |
Elder-Ray 1.030.mq5 | Expert Advisor | Laufzeitversion der Option 1: Alle Indikatoren auf einem einzigen Chart |
Elder-Ray 2.000.mq5 | Expert Advisor | Option 2: in Kombination mit dem System "Triple Choice". |
Schlussfolgerung
Das Handelssystem Elder-Ray (Bulls Power and Bears Power) ist praktikabel genug, insbesondere in Kombination mit dem System "Triple Choice", wenn der EMA-Trendindikator auf einem höheren Zeitrahmen berechnet wird als Bulls Power und Bears Power.
Beim Testen des EA sollten wir bedenken, dass die vorbereitete Textdatei bis zu 100 Symbole enthalten kann. In Anbetracht dieser Zahl können Sie bis zu 10 Minuten für den Start des Tests benötigen, sowie bis zu 5 GB Speicher während des Tests.
Unabhängig von Ihrem Vertrauen in die EA, werden Sie sicherlich in den Prozess eingreifen wollen, wie ich es beim Schreiben des Artikels und Testen der EA-Versionen getan habe:
Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/5014





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