MQL4 Trading Baukasten – Dein eigenes Handelssystem in 30 Minuten selber schreiben

Die Vorarbeiten - eine neue Datei im Metaeditor erstellen

Wähle bitte File -> New aus, um eine neue Datei zu erstellen. Der MQL4-Assistent unterstützt Dich dabei. Er wird die Datei als MQ4-Datei erstellen und bereits einige vorgefertigte Bestandteile einfügen - so musst Du nicht immer alles selber schreiben!

Metaeditor - neue Datei für das Forex System

Wir erstellen eine neue Datei im MetaEditor

Im folgenden Dialog wählen wir "Expert Advisor aus"

Expert Advisor für MT4 erstellen

Neuer Expert Advisor und dann WEITER

Jetzt benenne Dein Testhandelssystem mit "ForexTradingBausatz1"

Der ExpertAdvisor wird benannt

Vergib einen Namen und lösche den Rest

Jetzt löschen wir über Edit -> Delete den kompletten Inhalt des Programmcodes, denn wir wollen mit einer leeren Datei starten

ExpertAdvisor Code löschen

Der Inhalt der Datei wird gelöscht

So, das waren die ersten zwei Minuten. Jetzt geht es Zeile für Zeile weiter. Kopiere die Inhalte der einzelnen Zeilen und füge sie nacheinander ein, oder schreibe sie ab.

Hier kommt Zeile 1

int start() // das hier ist die Startfunktion, die bei jeder Kursveränderung aufgerufen wird. 

oder

void OnTick() // gleiche Startfunktion nach neuer Konvention

Auch wenn Du auf Deinem Bildschirm jetzt einen Zweizeiler siehst, es handelt sich um eine einzelne Zeile.

Was macht Zeile 1?

Diese Codezeile macht nichts anderes als eine Funktion mit dem Namen start (oder OnTick) zu beschreiben, die keine Parameter braucht. Diese Funktion wird vom Metatrader immer dann aufgerufen, wenn eine Kursveränderung stattfindet. Alles hinter // sind Kommentartexte, die man für das Programm weglassen kann und die nur für Menschen die Lesbarkeit verbessern sollen.

Dein MetaEditorfenster sollte jetzt so aussehen

erste Zeile des Programms im Meta-Editor

Erste Zeile im MetaEditor

 Zeile 2 sieht so aus

  { // Klammer auf, die Funktion startet

Eine öffnende geschweifte Klammer sagt dem Programm, dass die Funktion jetzt startet

Zeile 3 ist nur ein Kommentar

// ++++++++                  Wir berechnen die grobe Trendrichtung: ist der aktuelle Kurs höher als vor 10 Kerzen?

Kommentare sind dem Expert Advisor egal. Früher habe ich sie oft weggelassen um Zeit zu sparen. Hinterher zahlt man die Zeit immer doppelt drauf, denn man weiß irgendwann nicht mehr, warum man bestimmte Sachen gemacht hat.

Kommen wir zu Zeile 4

double Durchschnitt = iMA(NULL, 0, 14, 5, 0, 0, 0); //packe den Durchschnitt der letzten 14 Kerzen in die DOUBLE-Variable Durchschnitt

double ist ein Variablentyp und kann Zahlen mit Nachkommastellen aufnehmen.

iMA berechnet einen "gleitenden Durchschnittswert", also ob im Durchschnitt der Kurs sinkt oder fällt. Wenn Du iMA im MetaEditor eingibst und F1 drückst, bekommst Du die Dokumentation dazu angezeigt.

Kursberechnung mit gleitendem Durchschnitt

Wir berechnen die aktuelle Kursrichtung

 Zeile 5 macht nochmal das gleiche für den "alten Durchschnitt"

double AlterDurchschnitt = iMA(NULL, 0, 14, 5, 0, 0, 10); // packe den Durchschnitt der 14 Kerzen ab der zehntletzten Kerze in die Double-Variable AlterDurchschnitt

In Zeile 5 hat sich nur der letzte Parameter geändert. Dort steht eine 10, weil wir den Durchschnitt berechnen wollen, wie er vor 10 Kerzen war.

Zeile 6 Trendrichtung berechnen

double TrendRichtung=Durchschnitt - AlterDurchschnitt; // zieh den AltenDurchschnitt vom aktuellen Durchschnitt ab und pack ihn in TrendRichtung

Wir ziehen den alten Durchschnitt vom aktuellen Durchschnitt ab und packen das Ergebnis in die double-Variable TrendRichtung

Zeile 7 Trendrichtung auf den Bildschirm schreiben

Comment ("TrendRichtung = "+ TrendRichtung); // Schreibe die aktuelle Trendrichtung auf den Bildschirm

Die Comment-Funktion sorgt dafür, dass der berechnete Trendwert später rechts oben im Chart angezeigt wird. So kannst Du kontrollieren, ob Dein Forex Trading System richtig rechnet...

Zeile 8 ist wieder ein Kommentar

 // ++++++++ Wir prüfen, ob der Trend rauf geht und die Anzahl offener Trades für das Währungspaar 0 ist. Falls beides stimmt, kaufen wir

Zeile 9 - Prüfen ob der Trend positiv ist

if (TrendRichtung > 0.005) // wenn es rauf geht

In Zeile 9 prüfen wir ob der berechnete Wert "Trendrichtung" größer ist als "0.005". Man achte darauf, einen Punkt statt eines Kommas zu benutzen. Den Wert kannst Du später ändern, wenn Dein Handelssystem im Test zu früh oder zu spät kauft

Zeile 10 - Prüfen, ob wir schon offene Trades haben

 if((OffeneTradesDieserWaehrung(Symbol())==0)) // und keine Trades für dieses Währungspaar offen sind

Das ist so ein Fall, bei dem man richtig Mist bauen kann! Wenn Du vergisst, zu prüfen ob Du schon gekauft hast, kann Dein System Dich innerhalb weniger Sekunden ruinieren, weil es unbegrenzt neue Trades eingeht. Wir rufen eine Funktion auf, die alle Trades durchgeht und überprüft, ob es sich um das gleiche Währungspaar handelt. Nur wenn die Anzahl offener Trades für dieses Währungspaar 0 ist, wird weitergemacht.

Zeile 11 - Nur im Testbetrieb weitermachen

 if(IsTesting()) // NUR wenn wir im Backtesting sind

Auch Zeile 11 ist eine Absicherung, damit nicht versehentlich im Echtbetrieb gekauft wird.

Zeile 12 - Kaufen wenn alle Bedingungen erfüllt sind

 OrderSend (Symbol(),OP_BUY,0.01,Ask,3, (Ask-0.0030),(Ask+0.0030), NULL,NULL,0,Green); // kaufe zum Marktpreis und setze Stoploss und Takeprofit auf 30 Punkte

Nur wenn der Trend aufwärts geht, wir keine offenen Trades für dieses Währungspaar haben und wir uns im Testbetrieb befinden, dann wird eine Position eröffnet. Es handelt sich dabei um einen KAUF mit 30 Punkten Stop Loss und 30 Punkten Take Profit. Diese beiden Werte und der Kaufkurs werden später so im Chart als Linien angezeigt

Der Kaufkurs, Stop-Loss und Take-Profit im Forexchart

Take Profit, Stop Loss und Kaufkurs als Linien im Chart

 Zeile 13 bis 17 - Die gleichen Prüfungen für die andere Richtung

// ++++++++ Wir prüfen, ob der Trend runter geht und die Anzahl offener Trades für das Währungspaar 0 ist. Falls beides stimmt, verkaufen wir
 if (TrendRichtung < -0.005) // wenn es runter geht
 if((OffeneTradesDieserWaehrung(Symbol())==0)) // und keine Trades für dieses Währungspaar offen sind
 if(IsTesting()) // NUR wenn wir im Backtesting sind
 OrderSend (Symbol(),OP_SELL,0.01,Bid,3, (Bid+0.0030), (Bid-0.0030), NULL, NULL,0,Red); // kaufe zum Marktpreis und setze Stoploss und Takeprofit auf 30 Punkte

Unser Forex Trading System soll nicht nur handeln können, wenn der Preis rauf geht, sondern auch wenn er sinkt. Die Zeilen 13-17 prüfen die gleichen Bedingungen ab wie die Zeilen 8-12, allerdings in die andere Richtung. Verkauft wird nur, wenn der Kurs sinkt, keine offenen Trades existieren und wir uns im Testbetrieb befinden

Zeile 18 - Ende der Funktion

 } // Klammer zu, die Funktion start() wird beendet

Das war es schon mit der Hauptfunktion start(). Immer wenn eine Preisänderung auftritt, wird der Code ausgeführt. Allerdings brauchen wir noch eine kleine Zusatzfunktion, die die einzelnen offenen Trades durchgeht und prüft, ob wir nicht schon gekauft oder verkauft haben. Andernfalls würde mit jeder Kursänderung eine neue Position eröffnet, wenn die Mindestkursstärke gegeben ist. Siehe Bild

Forex Trading ohne Grenzen

Das Handelsystem eröffnet ohne Prüfung auf vorhandene Trades grenzenlos neue Positionen

 

 Zeile 19 - bleibt leer

Die Zeile 19 lassen wir leer, um die beiden Funktionen optisch voneinander zu trennen

 Zeile 20 - Die Funktion zur Prüfung offener Trades

 int OffeneTradesDieserWaehrung(string Waehrungspaar) // Funktion berechnet eine Ganzzahl der offenen Trades eines Währungspaares

Hier deklarieren wir die Funktion OffeneTradesDieserWaehrung, die einen Parameter für die Währung entgegen nimmt. In den Zeilen 10 und 15 rufen wir diese Funktion auf und übergeben mit Symbol() das aktuelle Währungspaar von dem Chart, auf dem unser ForexTradingBausatz gerade läuft.

Zeile 21 - Die Funktion wird geöffnet

{ // Klammer auf, die Funktion startet

Zeile 22 - Anzahl vor dem Zählen auf Null setzen

  int AnzahlOffeneTrades=0; // setze den Zählwert auf Null und fange bei Null an zu zählen

Da wir vor jedem Handel erneut prüfen möchten, ob wir bereits für dieses Währungspaar einen Buy oder Sell abgesetzt haben, setzen wir die Zählvariable für die Anzahl offener Trades am Anfang auf 0

Zeile 23 - Gehe alle offenen Trades mit einer Zählschleife durch

   for(int i=OrdersTotal() -1; i >= 0; i--) // Nimm die Gesamtanzahl offener Trades und zieh jeweils 1 ab, bis wir bei 0 sind.

Hier zählen wir von der Anzahl der offenen Trades, die uns unser Konto mit der Funktion OrdersTotal() liefert runter, bis keine offenen Trades mehr übrig sind

Zeile 24 - Klammer auf für die Zählschleife

 { // Klammer auf, prüfe die offenen Trades

Unsere Zählschleife bekommt eigene Klammmern. So lange noch offene Trades geprüft werden müssen, werden alle Befehle innerhalb dieser Klammern ausgeführt

Zeile 25 - Prüfe eine Order nach der anderen

      OrderSelect(i,SELECT_BY_POS,MODE_TRADES); // Prüfe jede Order der Trades

So lange offene Trades gefunden werden werden sie für die Überprüfung ausgewählt

Zeile 26 - AnzahlOffenerTrades erhöhen, wenn das Währungspaar gleich ist

      if(OrderSymbol()== Waehrungspaar) AnzahlOffeneTrades++; // wenn es das aktuelle Währungspaar ist, addiere die Order zu den offenen Trades

Hier wird geprüft, ob das Währungspaar auf dem Chart mit dem Währungspaar einer offenen Order übereinstimmt. Falls ja, wird der Zähler für AnzahlOffeneTrades erhöht. Sobald dieser Zähler größer als 0 ist, kauft unser Handelssystem nichts mehr nach...

Zeile 27 - Klammer zu, die Schleife für die Prüfung ist beendet

 } // Klammer zu, alle offenen Trades wurden geprüft

Zeile 28 - Wir geben den Wert zurück, ob offene Transaktionen für das aktuelle Währungspaar gefunden wurden

 return (AnzahlOffeneTrades); //liefere die Anzahl für offene Trades dieses Währungspaares zurück

Mit return (AnzahlOffeneTrades) wird unser Ergebnis zu der Frage, wie viele offene Trades existieren und ob ein neuer Trade aufgemacht werden soll wieder an die Zeilen 10 und 15 zurückgeschickt

Zeile 29 - Geschafft, die letzte Klammer, das Programm ist fertig!

} // Klammer zu, Funktion OffeneTradesDieserWaehrung ist beendet

Das war es schon. In unter 30 Programmzeilen hast Du ein Forex Trading System geschrieben, das auf mehreren Währungspaaren im Metatrader unabhängig von Dir Positionen eröffnet, bei Unterschreitung Deiner Schmerzgrenze den Stoploss auslöst, wenn der Trade in die falsche Richtung läuft und den Gewinn einer Position einsackt, wenn die Linie für den Take Profit erreicht wird.

Dein Programmierfenster im MetaEditor sollte jetzt so aussehen

Erster Bausatz für das Forex Trading

Dein MQL4 Trading Baukasten ist fertig!

 

Wenn alle Zeilen korrekt eingefügt wurden, drücke F5 oder klicke auf COMPILE

In der Toolbox im unteren Bereich sollte jetzt folgende Nachricht auftauchen:

Compiling 'ForexTradingBausatz1.mq4'...
0 error(s), 0 warning(s)

Öffne den Metatrader und drücke STRG + R oder klicke auf  Ansicht -> Strategietester

Wir öffnen den Strategie-Tester

Metatrader Strategietester öffnen

In Deinem Strategietester-Fenster wähle bitte alle Werte so aus, wie hier angezeigt. Dann klicke auf Anfangswert um mit dem Test zu starten. Nachdem die Daten für den Test gesammelt wurden (siehe Fusszeile im Metatrader "Sammeln M1") kannst Du den Test starten.

Klick zum Start auf den Play-Knopf rechts neben dem Schieberegler für die Geschwindigkeit

Forex trading Bausatz starten

Starte den Test für Deinen Forex Trading Bausatz

 

Ein paar Worte zum Abschluss

Natürlich könntest Du mit diesem System bereits echtes Geld handeln. Aber ich habe bewusst eine Überprüfung eingebaut, damit es nur im Backtesting funktioniert. Es soll als Grundlage dienen, um weitere Funktionen zu ergänzen. Dazu gehört eine Notfallsicherung, die dafür sorgt, dass Du im Ernstfall die Bremse ziehen kannst. Dazu gehört eine kontinuierliche Überprüfung, ob alle Positionen auch einen gültigen Stop Loss haben. Es kann nämlich immer mal vorkommen, dass bei der Übermittlung von Forex-Orderaufträgen Fehler auftreten. Und natürlich könnte ich den kompletten Quelltext auch zusammenhängend als Datei zur Verfügung stellen. Aber ich habe die einzelnen Zeilen bewusst getrennt, damit die grundlegende Funktionsweise jeder einzelnen Zeile klarer wird.  Es ist aber kein Problem, die einzelnen Zeilen zu kopieren und selbst im MetaEditor zusammenzusetzen.

Viel Spass beim Testen!