English Русский 中文 Español 日本語 Português
Besonderheiten von Expert Advisors

Besonderheiten von Expert Advisors

MetaTrader 4Beispiele | 4 November 2015, 13:41
1 389 0
MetaQuotes
MetaQuotes

Das Schreiben und Testen von Experten im Handelssystem MetaTrader hat einige Besonderheiten.

  • Bevor man eine Position eröffnet, muss man überprüfen, ob es verfügbares Geld auf dem Konto gibt. Wenn das Geld nicht ausreichend ist, wird die Aufgabe "Positioneröffnung"misslingen. Dabei muss der "FreeMargin"-Wert beim Testen mindestens 1000 betragen, denn der Preis eines Lots macht beim Testen 1000 aus.

  • if(AccountFreeMargin() < 1000) return(0); // kein Geld - beenden
  • Den Zugang zu historischen Daten kann man durch die indizierten und vorgegebenen Arrays Time, Open, Low, High, Close und Volume bekommen. Der Index nimmt in diesen Arrays historisch bedingt vom Ende zum Beginn zu. D.h die letzten Daten haben den Index 0. Der Index 1 bedeutet Daten mit der Verschiebung um eine Periode zurück, der Index 2 - zwei Perioden zurück, 3 - drei Perioden zurück usw.

  • // wenn Close auf dem vorherigen Balken weniger als  
    // Close auf dem Balken vor diesem Balken ist
    if(Close[1] < Close[2]) return(0);
  • Man kann auch den Zugang zu historischen Daten über andere Zeitintervallen sowie andere Währungspaare bekommen. Um diese Daten zu erhalten, muss man zuerst ein eindimensionales Array definieren und anhand der Funktion "ArrayCopySeries" kopieren. Dabei kann man beim Funktionsaufruf weniger Parameter mitteilen und voreingestellte Parameter nicht angeben.

  • double eur_close_m1[];
    int number_copied = ArrayCopySeries(eur_close_m1, MODE_CLOSE, 
                                        "EURUSD", PERIOD_M1);
  • Beim Schreiben eines Expert Advisors, wie beim Schreiben jedes beliebigen Programms, muss man manchmal zusätzliche Debug-Informationen ausgeben. Die Programmiersprache MQL4 gibt mehrere Möglichkeiten für die Ausgabe dieser Informationen.


    • Die Funktion "Alert" öffnet ein Dialogfenster, das die vom Nutzer angegebenen Daten enthält.

      Alert("FreeMargin grows to ", AccountFreeMargin(), "!");
    • Die Funktion "Comment" zeigt die vom Nutzer angegebenen Daten in der linken oberen Ecke des Charts an. Die Reihenfolge der Symbole "\n" wird für den Zeilenvorschub genutzt.

      Comment("FreeMargin is ", AccountFreeMargin(), ".");
    • Die Funktion "Print" listet die vom Nutzer angegebenen Daten im Systemprotokoll auf.

      Print("FreeMargin is ", AccountFreeMargin(), ".");
  • Die Funktion "GetLastError" lässt Informationen über Fehler in Programmen erhalten und ist sehr hilfreich. z.B. Eine Orderoperation liefert immer die Ticketnummer. Beträgt die Ticketnummer 0 (ein Fehler trat auf), ruft man die Funktion "GetLastError" auf, um zusätzliche Informationen zu bekommen:

    int iTickNum = 0
    int iLastError = 0;
    ...
    iTickNum = OrderSend(Symbol(), OP_BUY, g_Lots, Ask, 3, 0, 
                         Ask + g_TakeProfit * g_Points);
    if(iTickNum <= 0) 
      {
        iLastError = GetLastError();
        if(iLastError != ERR_NO_ERROR) 
            Alert("Some Message");  }
    Man sollte nicht vergessen, dass der Aufruf der Funktion "GetLastError" den Code des letzten Fehlers anzeigt und seinen Wert auf Null setzt. Deswegen liefert der erneute darauf folgende Aufruf dieser Funktion immer den Wert 0.
  • Wie bestimmt man den Beginn des nächsten Balkens? (Das braucht man, um zu erfahren, dass der vorangehende Balken gerade eben endete.) Dafür gibt es mehrere Möglichkeiten.


    Die erste beruht auf der Überprüfung der Balkenanzahl:

    static int prevbars = 0;
    ...
    if(prevbars == Bars) return(0);
    prevbars = Bars;
    ...

    Dieses Verfahren kann erfolglos sein, während man die Historie lädt. D.h. die Balkenanzahl hat sich verändert, der vorangehende Balkenist noch nicht vollendet. In diesem Fall kann man die Überprüfung auf den Werteunterschied=1 erweitern.

    Das nächste Verfahren basiert darauf, dass sich der Wert "Volume" aufgrund der Tickanzahl für jeden Balken bildet. Der erste Tick bedeutet, dass der Wert "Volume" des bildenden Balkens 1 beträgt:

    if( Volume[0] > 1) return(0);
    ...

    Wenn sich die Preisticks zu intensiv verändern, kann dieses Verfahren scheitern. Denn es liegt daran, dass die eingehenden Preisticks in einem separaten Thread bearbeitet werden. Wenn dieser Thread besetzt ist, während ein weiterer Tick eingeht, wird dieser Tick nicht bearbeitet, um die Rechnerkapazität nicht zu überfordern! In diesem Fall kann man auch die Überprüfung vertiefen und den gespeicherten vorangehenden Wert "Volume" zu nutzen.
    Das dritte Verfahren beruht auf der Eröffnungszeit des Balkens:

    static datetime prevtime=0;
    ...
    if(prevtime == Time[0]) return(0);
    prevtime = Time[0];
    ...

    Das ist das zuverlässigste Verfahren. Es funktioniert unter allen Umständen.

  • Beispiel mit dem Dateityp "CSV":

    int h1;
    h1 = FileOpen("my_data.csv", MODE_CSV | MODE_WRITE, ";");
    if(h1 < 0)
      {
       Print("Unable to open file my_data.csv");
       return(false);
      }
    FileWrite(h1, High[1], Low[1], Close[1], Volume[1]);  
    FileClose(h1);

    Einige Erläuterungen zum Code. Zuerst die CSV-Datei öffnen. Tritt bei der Öffnung der Datei ein Fehler auf, wird das Programm beendet. Wenn die Datei erfolgreich geöffnet wurde, wird ihr Inhalt gelöscht, Daten werden in die Datei gespeichert und die Datei wird anschließend geschlossen. Wenn man den Inhalt der Datei speichern will, ist der Öffnungsmodus MODE_READ zu nutzen:

    int h1;
    h1 = FileOpen("my_data.csv", MODE_CSV | MODE_WRITE | MODE_READ, ";");
    if(h1 < 0)
      {
       Print("Unable to open file my_data.csv");
       return(false);
      }
    FileSeek(h1, 0, SEEK_END);
    FileWrite(h1, High[1], Low[1], Close[1], Volume[1]);  
    FileClose(h1);

    In diesem Fall ist der Satz am Ende der Datei zu finden. Dafür haben wir nach der Eröffnung der Datei die Funktion "FileSeek" genutzt.

Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/1494

Pause zwischen Trades Pause zwischen Trades
In diesem Artikel geht es darum, wie man eine Pause zwischen Trades einlegt, wenn mehrere Expert Advisors in einem MT 4 Terminal arbeiten. Die Zielgruppe des Artikels bilden Nutzer, die bereits Grundkenntnisse über das Terminal und Programmieren in MQL4 haben.
Schlafen oder nicht schlafen? Schlafen oder nicht schlafen?
Eine alternative Nutzung der Sleep() Funktion bei der Realisierung von Pausen zwischen den Aktionen des Expert Advisors wird vorgeschlagen. Dieser Ansatz, wenn er berücksichtigt wird, ermöglicht eine intelligente Nutzung der Maschinenzeit.
Was Zahlen im Bericht über den Expertentest bedeuten Was Zahlen im Bericht über den Expertentest bedeuten
Anhand von Berichten kann man sowohl unterschiedliche Expert Advisors als auch Arbeitsergebnisse eines und denselben Experten mit verschiedenen Parametern miteinander vergleichen. Dieser Artikel erläutert, wie man solche Berichte liest und ihre Ergebnisse interpretiert.
Die gleichzeitige Anzeige der einigen Indikatoren-Signale von vier Timeframes Die gleichzeitige Anzeige der einigen Indikatoren-Signale von vier Timeframes
Beim manuellen Handel, im Unterschied mit einem mechanischen Handel, muss der Trader ständig auf die Werte einiger Indikatoren beachten. Wenn es die Indikatoren zum Beispiel, zwei oder drei gibt, und für den Handel eine Timeframe gewählt ist, so ist es gar keine unkomplizierte Aufgabe. Und wie man sonst so machen soll, wenn es die Indikatoren - fünf oder sechs gibt, und die Handelsstrategie verpflichtet, die Signale auf einigen Timeframes zu berücksichtigen?