Checkliste zur Konvertierung von EAs von MT4 nach MT5
Die Programmiersprachen für MetaTrader 4 (MT4) und MetaTrader 5 (MT5), MQL4 und MQL5, sind überraschend unterschiedlich voneinander und nicht vollständig kompatibel. Wer einen Expert Advisor (EA) für MT4 hat und diesen im MT5 verwenden will, muss daher zuvor im Quellcode ein paar Veränderungen vornehmen.
Außerdem muss er sicherstellen, dass er ein so genanntes “Hedge”-Konto im MT5 eröffnet hat. Ob Dein Konto “Standard” oder “Hedge” ist, erfragst Du am besten beim Broker.
Wenn Du dies nicht selbst tun kannst oder willst: Suche Dir bitte in unserem EA-Programmierer-Verzeichnis einen Programmierer (m/w/d) Deiner Wahl aus, trete mit ihm in Kontakt und erwähne dabei, dass Du ihn über das EA-Programmierer-Verzeichnis von mindful FX gefunden hast.
Hier in diesem Blog-Artikel findest Du meine Checkliste für Konvertierungen von MT4 nach MT5 (für “Hedge”-Konten). Die mq4-Datei muss zur mq5-Datei werden, unter Beachtung der folgenden wichtigsten Schritte.
Die folgende Auflistung stellt nicht den Anspruch auf Vollständigkeit, stellt aber die am häufigsten auftretenden Änderungen dar. Damit kann die überwältigende Mehrzahl der EA-Programme vergleichsweise schnell und unkompliziert von MT4 auf MT5 umgestellt werden.
Checkliste für MQL4-nach-MQL5-Konvertierungen von Expert Advisors
Schritt 1: Include Dateien einfügen
Im ersten Schritt fügen wir zwei Include-Dateien in den Code ein:
#include "mql4_to_mql5.mqh" #include "mt4orders.mqh"
Diese Einfügung nehmen wir unter den EA properties (#property) und oberhalb der Eingabevariablen vor.
Die Datei mql4_to_mql5.mqh beinhaltet Konvertierungscode für MT4-Funktionen, die nicht in MT5 verfügbar sind oder dort anders gehandhabt werden. Beispiele dafür sind MarketInfo(…), Zeitabrufe wie beispielsweise TimeDay() oder Minute() und AccountFreeMarginCheck().
Die Datei mt4orders.mqh macht hingegen die MT4-Orderverwaltungslogik mit MT5 kompatibel.
Schritt 2: Include Dateien hinterlegen
Die originale Version der beiden Include Dateien findest Du in der mql5.com-Codebasis unter https://www.mql5.com/de/code/16006 kostenlos downloadbar.
Oder Du lädst sie hier von meiner Website runter, leicht (aber entscheidend) weiterentwickelt.
Hinterlege sie (entzippt!) in Deinem MT5 Dateiordner in den Unterordnern “Include” und “Experts”.
Diese rufst Du auf, indem Du im MT5 oder im MQL5-Editor auf den Menüpunkt Datei -> Dateiordner öffnen -> MQL5 -> Include bzw. Experts klickst.
Schritt 3: Indikator-Abfragen in die MT5-Logik umwandeln
Indikatoren werden in MQL5 anders abgefragt als in MQL4.
Du musst zunächst eine so genannte “Handle”, also eine Art Zugangsschlüssel definieren. Damit steuert MT5 Deinen Indikatorzugriff. Es handelt sich hierbei um eine ganze Zahl. Z.B. so:
int handle_ATR = INVALID_HANDLE; // für Average True Range
INVALID_HANDLE ist dabei der Standardwert, mit dem die Variable belegt wird.
Dann belegst Du die Handle-Variable mit dem Zugangsschlüssel zum Indikator auf einem Symbol und auf einem Timeframe:
handle_ATR = iATR (_Symbol, PERIOD_CURRENT, ATR_Perioden);
ATR_Perioden sei dabei eine Eingabevariable.
Danach fragst Du den jeweils aktuellen oder historischen Indikatorwert ab. Das geht so, indem Du den gewünschten Ausschnitt der Indikatorzeitreihe in eine Array-Variable kopierst:
double werte_ATR[1];
Wir definieren die Array-Variable als Zahl mit Nachkommastellen (double), mit einer Arraystelle (‘1’ in den eckigen Klammern)
CopyBuffer (handle_ATR, 0, 1, 1, werte_ATR);
Der Indikator-Zugriff erfolgt auf Buffer 0 ab Kerze 1, es wird 1 Wert kopiert, und zwar in den eben definierten Array werte_ATR.
double atr = werte_ATR[0];
Dann belegen wir eine einfache Double-Variable mit dem Wert, der auf Arraystelle 0 (also der ersten und einzigen Arraystelle) abgelegt ist.
WICHTIG ZU WISSEN: Wenn Du mehr als eine Arraystelle aus dem Indikator in Deine Array-Variable kopierst, ist die Reihenfolge der Werte nun zeitlich von links nach rechts sortiert: der älteste Wert (z.B. aus MT4-Kerzen-Shift 2) befindet sich an Arraystelle 0, der jüngste hingegen an der höchsten Arraystelle (z.B. aus MT4-Kerzen-Shift 1).
Schritt 3 B: Besonderheiten im Heiken Ashi Indikator
Beim Heiken Ashi Indikator, der durch iCustom(…) abgefragt wird, gibt es drei Besonderheiten. Die eine bezieht sich auf den Speicherort, die zweite auf den Indikator Datei Namen, die dritte auf die Indikator-Buffer-Nummern.
Die allgemeine Vorgehensweise der Konvertierung von MQL4 auf MQL5 ist ansonsten so wie unter Schritt 3 beschrieben.
In MT4 wird der Heiken Ashi Indikator folgendermaßen abgefragt, am Beispiel des Close-Preises der Heiken Ashi Kerze:
double HA_Close_1 = iCustom ( _Symbol, PERIOD_CURRENT, "Heiken Ashi", 3, 1 );
Dabei bezieht sich der dritte Parameter auf den Indikatornamen, der vierte auf die Ordnungsnummer des Buffers der Indikator-Close-Preise, und der fünfte auf den Kerzenshift.
Im MT5 ist der Heiken Ashi Indikator standardmäßig allerdings nicht direkt im Indicators-Ordner abgespeichert, sondern in einem weiteren Unterordner namens “Examples”. Daher lautet im MT5 die korrekte iCustom-Nutzung:
int handle_HA = iCustom(_Symbol, Timeframe, "Examples\\Heiken_Ashi");
Außerdem ist beim MT5 ein Unterstrich im Dateinamen des Indikators vorhanden, während im MT4 die beiden Wörter mit Leerzeichen getrennt sind!
Wir erinnern uns, dass Buffer und Kerzenshift später im CopyBuffer(…)-Abruf geschieht:
double werte_HA_Close[2]; // Definition des Arrays, der 2 Heiken Ashi Schlusskurse enthalten soll
CopyBuffer (handle_HA, 3, 1, 2, werte_HA_Close); // Indikator-Buffer-Abruf und Speicherung in Array
In CopyBuffer ist der zweite Parameter die Ordnungsnummer des Buffers. Der Heiken Ashi Close Preis ist in Buffer Nummer 3 zu finden, sowohl in MT4 als auch in MT5.
Alle anderen Heiken Ashi Kerzenpunkte haben allerdings abweichende Buffer zugewiesen:
Open → MT4: 2 → MT5: 0
High → MT4: 1 bei Aufwärts-, 0 bei Abwärtskerzen → MT5: 1 (egal, ob Aufwärts- oder Abwärtskerze)
Low → MT4: 0 bei Aufwärts-, 1 bei Abwärtskerzen → MT5: 2 (egal, ob Aufwärts- oder Abwärtskerze)
Close → MT4: 3 → MT5: 3
Schritt 3 C: Besonderheiten beim Bollinger Bänder Indikator
Auch bei den Bollinger Bändern gibt es ein paar entscheidende Unterschiede. Auch hier sind die Buffer Ordnungsnummern im MT5 anders belegt als in MT4, und es werden abweichende Enumerierungs-Bezeichnungen für diese Buffer Ordnungsnummern verwendet. Außerdem wäre es in MT5 möglich, das mittlere Band aus einem Buffer aufzurufen.
Ein Beispiel, wie die Bollinger Bänder in MQL5 abrufbar wären, findest Du im folgenden Code-Block:
//---------------
double Bollinger_Upper;
double Bollinger_Mid;
double Bollinger_Lower;
void calcBollingers(int bar)
{
int handle_Boll = INVALID_HANDLE;
handle_Boll = iBands(_Symbol, Timeframe, Periode, Versatz, Abweichungen, AnwendenAuf);
double werte_Boll_Lo[1];
double werte_Boll_Up[1];
CopyBuffer(handle_Boll, UPPER_BAND, bar, 1, werte_Boll_Up);
CopyBuffer(handle_Boll, LOWER_BAND, bar, 1, werte_Boll_Lo);
Bollinger_Lower=werte_Boll_Lo[0];
Bollinger_Upper=werte_Boll_Up[0];
Bollinger_Mid=(Bollinger_Lower+Bollinger_Upper)/2;
}
//---------------
Schritt 4: Ticketnummer-haltende Integer-Variablen auf Long-Variablen umstellen
Ticketnummern aus Trades werden in MQL4 als Integer gespeichert. In MQL5 müssen wir dafür eine Long-Variable verwenden. Long-Variablen sind ebenfalls ganzzahlig, belegen aber mehr Speicherplatz (8 statt 4 Byte mit je 64 statt 32 Bit) und können damit höhere Zahlen (im positiven wie im negativen Bereich) halten. Die höchste Zahl einer Integer-Variable ist 2 147 483 647, während die Long-Variable Zahlen bis zu 9 223 372 036 854 775 807 (9 Trillionen statt “nur” 2 Milliarden) repräsentieren kann.
in der Praxis ist das ganz einfach. Was vorher z.B.
int Ticketnummer_BUY=0;
war, schreibt sich jetzt
long Ticketnummer_BUY=0;
Schritt 5: Teilschließungen anpassen
Teilschließungen werden im MT5 anders gehandhabt als im MT4. Die originale Ordernummer bleibt der Restorder erhalten anstelle dass eine neue Ticketnummer vergeben wird.
Es gibt verschiedene Wege, dies zu lösen. Ich nutze dazu gerne Chartobjekte. In der Schleife durch alle Positionen sieht der EA nach, ob ein Objekt mit dem Namen TEILSCHLIESSUNGGEMACHT+[TicketNummer] besteht. Wenn ja, ist die Teilschließung erledigt und der EA darf keine mehr machen bei dieser Position. Im Code würde das so aussehen:
string PARTIALCLOSEDONE="PARTIALCLOSEDONE";
vor dem Loop durch die Positionen zu platzieren,
string pcname = PARTIALCLOSEDONE+(string)OrderTicket();
im Loop vor der Teilschließungsabfrage platzieren,
if ( ObjectFind ( 0, pcname ) < 0 ) …
stellt dann die Abfrage nach dem Objekt dar. Wenn ObjectFind() einen negativen Wert zurückgibt, gibt es ein solches Objekt noch nicht auf dem Chart. Dann kann ich in die Teilschließung selbst gehen und den Schwellenwert-Gewinn und die Teilschließungslots berechnen. Wenn die Orderschließung selbst geklappt hat, wird das Objekt ins Chart platziert:
if ( OrderTeilgeschlossen ) ObjectCreate(0, pcname, OBJ_ARROW, 0, TimeCurrent(), Bid);
Schritt 6: Chart-Objekt-Abrufe anpassen
In MetaTrader 4 werden zum Beispiel die zwei Preise oder zwei Daten einer Trendlinie in unterschiedlichen Eigenschaften vorgehalten:
ObjectSetInteger ( 0, name, OBJPROP_TIME1, time1); // Time 1 anpassen
ObjectSetInteger ( 0, name, OBJPROP_TIME2, time2); // Time 2 anpassen
In MT5 werden sie in ein und der selben Eigenschaft vorgehalten, aber mit einem Modifier, also einer Platzierung innerhalb der Eigenschaft versehen.
Dafür wird ein weiterer Parameter verwendet:
ObjectSetInteger ( 0, name, OBJPROP_TIME, 0, time1); // Time 1 anpassen
ObjectSetInteger ( 0, name, OBJPROP_TIME, 1, time2); // Time 2 anpassen
Dabei entspricht der Modifier 0 dem ersten Wert der Objekt-Eigenschaft (z.B. “OPPROP_TIME” oder “OBJPROP_PRICE”), der Modifier 1 dem zweiten Wert, der Modifier 2 dem dritten Wert usw.
Schritt 7: Chart-Objekt-Funktionen prüfen
Wer im MetaTrader 4 den weiteren Verlauf des EA-Codes vom Erfolg einer Chart-Objekt-Funktion abhängig gemacht hat, könnte im MT5 auf Schwierigkeiten stoßen.
Ein Beispiel in MQL4:
if ( ObjectCreate (0, name, OBJ_ARROW, 0, TimeCurrent(), Bid) )
… dann tue dies und das.
Ein MT4-Programm läuft erst und nur dann in die if-then-Ausführung weiter, wenn der Pfeil wirklich platziert werden konnte. Denn ObjectCreate() gibt in MT4 True zurück, wenn der Pfeil im Chart erstellt werden konnte, und False, wenn nicht (z.B. weil es das Objekt schon gab auf dem Chart).
Ein MT5-Programm läuft aber quasi immer in die wenn-dann-Ausführung weiter. Denn ObjectCreate() gibt in MT5 True zurück, wenn die Objekt-Kreierung in die Objekt-Bearbeitungs-Schleife aufgenommen werden konnte - was so gut wie immer der Fall ist, auch wenn es das Objekt schon gab und daher in der Abarbeitung des Objekt-Stapels nicht mehr platziert werden kann.
Dein MQL5-EA muss daher so umprogrammiert werden, dass Du zuerst nachschaust, ob das Objekt sich schon im Chart befindet. Wenn nein, dann nutze ObjectCreate() und führe die weiteren Aktionen aus, die eben bei Objekt-Kreierung ebenso geschehen sollen.
Schritt 8: Weitere Objekt-Funktionen anpassen
Während im MetaTrader 4 die ObjectsTotal()-Funktion ohne Parameter abgerufen werden kann, muss in MQL5 darauf verwiesen werden, aus welchem Chart die Anzahl der vorhanden Objekte abgerufen wird.
Wenn es sich um den EA-Chart handelt, können wir durch Parameter-Mitgabe “0” den aktuellen Chart beschreiben:
ObjectsTotal ( 0 )
Die ObjectsTotal()-Funktion wird zum Beispiel in oder für Prüf-Loops verwendet, in denen die vorhandenen Objekte abgefragt werden.
Ähnlich Anpassungen müssen u.a. in ObjectName() vorgenommen werden.
Wenn Du im MQL4-Code ObjectType() verwendest, musst Du dies in MQL5 ObjectGetInteger() aufrufen, um den Objekttyp abzufragen:
ObjectGetInteger ( 0, name, OBJPROP_TYPE )
Eventuell findest Du in den Fehlermeldungen des Kompilierberichts noch weitere ähnliche Situationen. Du löst sie logisch analog.
Schritt 9: Array-Funktionen anpassen
Manche Array-Funktionen müssen angepasst werden.
Allen voran hat ArraySort( ) in MQL5 nur einen Parameter, und zwar den Array selbst. Es wird generell aufsteigend sortiert, so dass der Array-Zugriff nach Sortierung ggfls. angepasst werden muss.
Einfach und wirkungsvoll
Diese Checkliste enthält die allerwichtigsten Konvertierungsweisheiten. Sie stellt keinen Anspruch auf Vollständigkeit. Aber sicherlich 95% aller Deiner MT4-EAs kannst Du hiermit nach MT5 überführen.
Damit hast Du schnell Deine EAs auf MT5 zur Verfügung, perfekt funktionell!
Weitere Schritte werde ich mit der Zeit ergänzen. Wenn Du welche kennst, die mit auf die Liste müssten, schreibe sie bitte unten ins Kommentarfeld. Dann haben wir alle etwas davon - gemeinsam sind wir stärker!
MT5-EAs im mindful FX EA-Shop
Unser online EA-Shop füllt sich mit immer mehr MT5-Versionen unserer Expert Advisors. Jüngst hinzugekommen:
Willst Du alle unsere EAs kostenlos haben?
Bevor Du im Webshop stöbern gehst, schaue Dir bitte unseren EA Trader School Selbstlernkurs an. Darin helfen mein Team und ich allen Teilnehmern dabei, es zu langfristiger, kontanter Profitabilität zu schaffen; mit EAs generell und mit den mFX-EAs im Speziellen.
Wenn Du’s ernst meinst mit dem EA Trading und endlich EAs profitabel nutzen willst, ist die EA Trader School wie gemacht für Dich.
Netter Gimmick dabei: EA Trader School Teilnehmer (wir nennen sie liebevoll “KPEATen”, was für konstant profitable EA Trader steht) erhalten alle unsere EAs, Indikatoren und Skripte kostenlos. Und zwar mit Dauerlizenzen; also nicht nur für 12 Monate, sondern lebenslang! Sowohl die MT4- als auch die MT5-Versionen.
Klick auf das Logo der EA Trader School rechts, um zur Info- und Bewerbungsseite zu gelangen.
Allerbeste Tradingerfolge wünscht Dir
Cristof Ensslin von mindful FX, Dein EA-Trader-Coach.