English Русский 中文 Español 日本語 Português 한국어 Français Italiano Türkçe
Ein Beispiel für ein Handelssystem auf der Grundlage des Indikators Heiken-Ashi

Ein Beispiel für ein Handelssystem auf der Grundlage des Indikators Heiken-Ashi

MetaTrader 5Beispiele | 8 März 2016, 10:05
3 817 0
Dmitry Voronkov
Dmitry Voronkov

Einleitung

Als Kerzendiagramme vor über zwei Jahrzehnten in den USA in Erscheinung traten, revolutionierten sie das Verständnis der Arbeit von Bullen und Bären in den westlichen Märkten. Kerzen wurden zu einem beliebten Handelsinstrument und die Händler begannen, mit ihnen zu arbeiten, um die Lesbarkeit von Diagrammen zu erleichtern. Doch die Interpretation von Kerzen kann unterschiedlich sein.

Eine dieser Methoden, die das traditionelle Kerzendiagramm verändert und seine Wahrnehmung erleichtert, ist die Heikin-Ashi-Technologie.

1. "Nani Desu Ka?"*

Die erste Publikation zu diesem Thema erschien 2004 in der Februar-Ausgabe der Fachzeitschrift "Technical Analysis of STOCKS & COMMODITIES", in der Dan Valcu einen Artikel mit dem Titel "Using the Heikin Ashi Technique" (Verwendung der Heikin-Ashi-Technik) veröffentlichte (Link zum Originalartikel).

Auf seiner Webseite weist der Autor darauf hin, dass er im Sommer 2003 die Ichimoku-Technologie studierte und, wie es so oft geschieht, zufällig auf einige Diagramme stieß, in denen er einen klar sichtbaren Markttrend erkannte. Diese erwiesen sich als Heikin-Ashi-Diagramme oder, genauer gesagt, veränderte Kerzen.

Diese Analysemethode wurde von einem japanischen Händler entwickelt, der sehr erfolgreich wurde und diese Methode bis heute nutzt. Zu seiner großen Überraschung fand der Autor keine weiteren Informationen in Büchern oder dem Internet, also beschloss er, die Methode durch die Veröffentlichung in einer Fachzeitschrift allen Händlern zur Verfügung zu stellen.

Die Heikin-Ashi-Methode (das japanische Wort heikin bedeutet "Mitte" oder "Balance" und ashi bedeutet "Fuß" oder "Balken") ist ein visuelles Werkzeug für die Bewertung von Trends, ihrer Richtung und ihrer Stärke. Sie ist kein "Heiliger Gral" des Handels, doch sie ist definitiv ein gutes und benutzerfreundliches Instrument zum Visualisieren von Trends.

Betrachten wir die Berechnung des Werts der OHLC-Kerze:

Schließung des aktuellen Balkens: haClose = (Open+High+Low+Close)/4
Öffnung des aktuellen Balkens: haOpen = (haOpen[vorher] + haClose[vorher])/2
Maximalwert des aktuellen Balkens: haHigh = Max(High, haOpen, haClose)
Mindestwert des aktuellen Balkens: haLow = Min(Low, haOpen, haClose)

Die Werte "Open", "High", "Low" und "Close" beziehen sich auf den aktuellen Balken. Das Präfix "ha" steht für die entsprechenden modifizierten Heikin-Ashi-Werte.

Um die Wahrnehmung der Marktinformationen zu erleichtern, modifiziert die Heikin-Ashi-Methode das traditionelle Kerzendiagramm, indem sie sogenannte synthetische Kerzen erstellt, die Unregelmäßigkeiten aus dem herkömmlichen Diagramm entfernt und somit ein besseres Gesamtbild von Trends und Konsolidierungen schafft. Wenn Sie das mithilfe dieser Methode erstellte Kerzendiagramm ansehen, erhalten Sie einen guten Überblick über den Markt und dessen Kraft:

Abbildung 1. Auf der linken Seite sehen Sie das herkömmliche Kerzendiagramm (a), auf der rechten (b) das Heikin-Ashi-Diagramm

Abb. 1 zeigt den Unterschied zwischen herkömmlichen japanischen Kerzen und Heikin-Ashi-Kerzen. Das Unterscheidungsmerkmal dieser Diagramme ist, dass in einem Aufwärtstrend die Mehrheit der weißen Kerzen keinen Schatten hat. In einem Abwärtstrend hat die Mehrheit der schwarzen Kerzen keinen oberen Schatten. Das Heikin-Ashi-Diagramm weist keine Unterbrechungen auf, also öffnet eine neue Kerze auf dem Niveau der Mitte der vorherigen.

Die Kerzen im Heikin-Ashi-Diagramm zeigen den Trend besser an als herkömmliche Kerzen. Wenn sich der Trend abschwächt, werden die Körper der Kerzen kleiner und die Schatten größer. Die Farbveränderung der Kerzen ist ein Signal zum Kaufen / Verkaufen. Es ist am bequemsten, das Ende einer Korrekturbewegung auf Basis dieser Diagramme zu bestimmen.

Dieser Indikator ist ein Bestandteil von MetaTrader 5 und Sie finden ihn im Ordner "Indicators\Examples\Heiken_Ashi.mq5". Vor dem Anhängen des Indikators an das Diagramm empfehle ich, das Diagramm linear zu machen. Wählen Sie außerdem in den Eigenschaften des Diagramms in der Registerkarte "General" (Allgemein) die Option "from the top graph" (vom oberen Diagramm) ab.

Ich möchte abermals betonen, dass die Heikin-Ashi-Methode kein "Heiliger Gral" ist. Als Beweis versuche ich, ein einfaches Handelssystem (HS) nur mithilfe dieser Technik zu erstellen.

Dazu müssen wir mithilfe der Programmiersprache MQL5 und der Klassen der Standardbibliothek einen simplen Expert Advisor erstellen und ihn mithilfe des Strategietesters des MetaTrader-5-Terminals auf historischen Daten testen.

2. Algorithmus des Handelssystems

Wir erstellen den Algorithmus ohne unnötige Komplexität, indem wir die sechs Grundregeln des Heikin-Ashi-Verfahrens nutzen, die Dan Valcu auf der folgenden Seite darlegt: http://www.educofin.com/

  1. Aufsteigender Trend – blaue Kerze haClose>haOpen
  2. Absteigender Trend – rote Kerze haClose<haOpen
  3. Starker aufsteigender Trend – blaue Kerze ohne Low haOpen==haLow
  4. Starker absteigender Trend – rote Kerze ohne High haOpen==haHigh
  5. Konsolidierung – Abfolge von Kerzen mit kleinen Körpern (einer beliebigen Farbe) und langen Schatten
  6. Trendänderung – Kerze mit kleinem Körper und langen Schatten der entgegengesetzten Farbe. Das ist nicht immer ein verlässliches Signal und kann manchmal nur Teil einer Konsolidierung sein (5).

Ein Trend (1, 2) ist einfach zu verstehen: Wenn wir uns in einer Transaktion befinden, halten wir einfach die Position und verschieben den Stopp um 1-2 Punkte unter / über die vorherige Kerze.

Bei einem starken Trend (3, 4) verschieben wir den Stopp ebenfalls.

Eine Konsolidierung (5) und eine Trendänderung (6) schließen die Position (falls Sie nicht durch den Stopp geschlossen wird), allerdings müssen wir entscheiden, ob wir eine entgegengesetzte Position öffnen. Um diese Entscheidung treffen zu können, müssen wir irgendwie bestimmen, ob eine Konsolidierung oder Umkehrung stattfindet. Wir werden einen Filter brauchen, der auf Indikatoren, der Analyse von Kerzen oder einer grafischen Analyse aufbaut.

Die Aufstellung einer gewinnbringen Strategie gehört nicht zu den Zielen unseres Beitrags, aber wer weiß, was wir als Ergebnis erzielen. Deshalb halten wir fest, dass wir beim Erscheinen einer Kerze der entgegengesetzten Farbe die Position schließen und eine neue mit entgegengesetzter Richtung öffnen.

Also sieht unser Algorithmus so aus:

  1. Hat sich eine Kerze der entgegengesetzten Farbe geformt, schließen wir die vorherige Position, falls wir eine haben, und öffnen eine Position bei der Öffnung einer neuen Kerze. Dabei legen wir einen Stopp 2 Punkte unter/über dem Minimum/Maximum der vorherigen Kerze fest.
  2. Bei einem Trend verschieben wir den Stopp 2 Punkte unter/über das Minimum/Maximum der vorherigen Kerze.
  3. Bei einem starken Trend tun wir das gleiche wie bei einem Trend, d. h. wir verschieben den Stopp.

Insgesamt ist alles ziemlich einfach und für den Leser hoffentlich verständlich. Nun setzen wir dies in der MQL5-Sprache um.

3. Programmieren des Expert Advisors in MQL5

Um einen Expert Advisor zu erstellen, brauchen wir nur einen Eingabeparameter: die Größe des Postens, die beiden Ereignis-Handler-Funktionen OnInit() und OnTick() und unsere eigene Funktion CheckForOpenClose().

Zur Festlegung der Eingabeparameter in MQL5 nutzen wir Input-Variablen.

//--- input parameters
input double Lot=0.1;    // Port size

Die Funktion OnInit() ist der Ereignis-Handler Init. Init-Ereignisse werden sofort nach dem Laden des Expert Advisors generiert.

Im Code dieser Funktion verbinden wir den Indikator mit dem Expert Advisor. Wie ich bereits erwähnt habe, ist in MetaTrader 5 standardmäßig der Indikator Heiken_Ashi.mq5 enthalten.

Sie fragen sich vielleicht, warum das alles so komplex ist, wenn wir doch über die Formeln zur Berechnung des Indikators verfügen und die Werte im Code des Expert Advisors berechnen können. Ich gebe zu, dass das möglich wäre, aber wenn Sie einen davon genau betrachten:

haOpen=(haOpen[vorher]+haClose[vorher])/2

sehen Sie, dass er die vorherigen Werte nutzt, was ein wenig unpraktisch ist und uns das Leben unnötig schwer macht. Deshalb nutzen wir anstatt unabhängiger Berechnungen die Möglichkeiten von MQL5, um unseren benutzerdefinierten Indikator zu verbinden, insbesondere die Funktion iCustom.

Dafür fügen wir die folgende Zeile zum Körper der Funktion OnInit() hinzu:

   hHeiken_Ashi=iCustom(NULL,PERIOD_CURRENT,"Examples\\Heiken_Ashi");

und wir erhalten die globale Variable hHeikin_Ashi, ein Handle des Indikators Heiken_Ashi.mq5, das wir im Folgenden brauchen werden.

Die Funktion OnTick() ist der Handler des Ereignisses NewTick(), das mit dem Erscheinen eines neuen Ticks generiert wird.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- check the ability of trading and the calculated number of bars
   if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
      if(BarsCalculated(hHeiken_Ashi)>100)
        {
         CheckForOpenClose();
        }
//---
  }

Die Funktion TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) prüft, ob Handel erlaubt ist. Mithilfe der Funktion BarsCalculated (hHeiken_Ashi) prüfen wir die Menge der berechneten Daten für den angefragten Indikator, in unserem Fall Heiken_Ashi.mq5.

Sind beide Bedingungen erfüllt, wird unsere Funktion CheckForOpenClose() ausgeführt, in der der Hauptteil der Arbeit stattfindet. Sehen wir sie uns näher an.

Da die Bedingungen unseres HS festlegen, dass die Einrichtung von Ordern bei der Öffnung einer neuen Kerze stattfindet, müssen wir bestimmen, ob eine neue Kerze geöffnet wurde. Dafür gibt es viele Möglichkeiten. Die einfachste ist, das Volumen von Ticks zu überprüfen. Wenn das Tick-Volumen gleich eins ist, deutet dies auf die Öffnung eines neuen Balkens hin und Sie sollten die Bedingungen des HS ansehen und Order herausgeben.

Wir setzen dies auf die folgende Art um:

//--- process the orders only after receiving the first tick of the new candlestick 
   MqlRates rt[1];
   if(CopyRates(_Symbol,_Period,0,1,rt)!=1)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return;
     }
   if(rt[0].tick_volume>1) return;

Erstellen Sie ein Variablen-Array des Typen MqlRates mit der Größe eines Elements. Rufen Sie darin mithilfe der Funktion CopyRates() die Werte des letzten Balkens ab. Prüfen Sie anschließend das Tick-Volumen. Wenn es größer als eins ist, beenden Sie die Funktion. Andernfalls fahren Sie mit den Berechnungen fort.

Als Nächstes deklarieren wir mithilfe der Direktive #define einige mnemotechnische Konstanten:

//--- to check the conditions we need the last three bars
#define  BAR_COUNT   3
//--- the number of indicator buffer for storage Open
#define  HA_OPEN     0
//--- the number of the indicator buffer for storage High
#define  HA_HIGH     1
//--- the number of indicator buffer for storage Low
#define  HA_LOW      2
//--- the number of indicator buffer for storage Close
#define  HA_CLOSE    3

Dann erklären wir das Array:

double   haOpen[BAR_COUNT],haHigh[BAR_COUNT],haLow[BAR_COUNT],haClose[BAR_COUNT];

und rufen mithilfe der Funktion CopyBuffer() die Werte des Indikators in den jeweiligen Arrays ab.

   if(CopyBuffer(hHeiken_Ashi,HA_OPEN,0,BAR_COUNT,haOpen)!=BAR_COUNT
      || CopyBuffer(hHeiken_Ashi,HA_HIGH,0,BAR_COUNT,haHigh)!=BAR_COUNT
      || CopyBuffer(hHeiken_Ashi,HA_LOW,0,BAR_COUNT,haLow)!=BAR_COUNT
      || CopyBuffer(hHeiken_Ashi,HA_CLOSE,0,BAR_COUNT,haClose)!=BAR_COUNT)
     {
      Print("CopyBuffer from Heiken_Ashi failed, no data");
      return;
     }

Ich möchte Ihre Aufmerksamkeit darauf lenken, wie Daten in den Variablen des Arrays gespeichert werden.

Der (historisch) "älteste" Balken wird im ersten Element des Arrays (Null) gespeichert.

Der "jüngste" (aktuelle) Balken im letzten, BAR_COUNT-1 (Abb. 2).

Abbildung 2. Reihenfolge der Kerzen und Werte der Indizes des Arrays

Abbildung 2. Reihenfolge der Kerzen und Werte der Indizes des Arrays

Somit haben wir die OHLC-Heikin-Ashi-Werte abgerufen und es müssen nur noch die Bedingungen für die Öffnung oder Beibehaltung einer Position überprüft werden.

Sehen wir uns die Verarbeitung des Verkaufssignals im Detail an.

Wie ich bereits erwähnt habe, haben wir die Werte von drei Heikin-Ashi-Kerzen erhalten. Der aktuelle Wert befindet sich in den Zellen mit der Nummer [BAR_COUNT-1=2] und wird von uns nicht benötigt. Die vorherigen Werte befinden sich in den Zellen [BAR_COUNT-2=1] und frühere Balken in [BAR_COUNT-3=0] (siehe Abb. 2). Basierend auf diesen zwei Balken prüfen wir die Bedingungen für den Abschluss des Handels.

Danach müssen wir das Instrument auf offene Positionen überprüfen. Dazu nutzen wir die Klasse CPositionInfo aus den Handelsklassen der Standardbibliothek. Mithilfe dieser Klasse können wir Informationen über offene Positionen abrufen. Mithilfe der Methode Select(_Symbol) bestimmen wir das Vorhandensein von offenen Positionen auf unserem Instrument. Falls sie vorhanden sind, nutzen wir die Methode Type() zur Bestimmung des Typen der offenen Positionen.

Wenn wir zu diesem Zeitpunkt eine offene Position zum Kauf haben, müssen wir sie schließen.

Dafür nutzen wir die Methoden der Klasse CTrade aus der Standardklassenbibliothek, die für die Durchführung von Handelstätigkeiten ausgelegt ist.

Mithilfe der Methode PositionClose(const string symbol,ulong deviation) schließen wir den Kauf. Dabei ist das Symbol der Name des Instruments und der zweite Parameter deviation die zulässige Abweichung vom Schließungspreis.

Dann überprüfen wir die Kombination der Kerzen in Übereinstimmung mit unserem HS. Da wir die Richtung der neu entstandenen Kerzen bereits geprüft haben (mit dem Index [BAR_COUNT-2]), müssen wir nur die Kerze davor überprüfen (mit dem Index [BAR_COUNT-3]) und die Schritte zum Öffnen der Position durchführen.

     //--- check if there is an open position, and if there is, close it
      if(posinf.Select(_Symbol))
        {
         if(posinf.Type()==POSITION_TYPE_BUY)
           {
            //            lot=lot*2;
            trade.PositionClose(_Symbol,3);
           }
        }
      //--- check and set Stop Loss level
      double stop_loss=NormalizeDouble(haHigh[BAR_COUNT-2],_Digits)+_Point*2;
      double stop_level=SymbolInfoDouble(_Symbol,SYMBOL_ASK)+SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point;
      if(stop_loss<stop_level) stop_loss=stop_level;
      //--- check the combination: the candle with the opposite color has formed
      if(haOpen[BAR_COUNT-3]<haClose[BAR_COUNT-3])
        {
         if(!trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,lot,SymbolInfoDouble(_Symbol,SYMBOL_BID),stop_loss,0))
            Print(trade.ResultRetcodeDescription());
        }
      else
      if(posinf.Select(_Symbol))
        {
         if(!trade.PositionModify(_Symbol,stop_loss,0))
            Print(trade.ResultRetcodeDescription());
        }

Hier müssen Sie auf den Gebrauch der drei Methoden der Klasse CTrade achten:

  • Die Methode PositionOpen(symbol, order_type, volume, price, sl, tp, comment) wird zum Öffnen einer Position verwendet, wobei das Symbol der Name des Instruments ist, order_type der Typ der Order, volume die Größe des Postens, price der Kaufpreis, sl Stopp, tp Gewinn und comment ein Kommentar.
  • Die Methode PositionModify(symbol, sl, tp) wird zum Ändern des Werts von Stopp und Gewinn verwendet, wobei Symbol der Name des Instruments ist, sl Stopp und tp Gewinn. Ich möchte Ihre Aufmerksamkeit darauf lenken, dass Sie vor der Verwendung dieser Methode das Vorhandensein von offenen Positionen prüfen sollten.
  • Die Methode ResultRetcodeDescription() wird zum Abrufen der Beschreibung des Fehlercodes in Form einer Zeile verwendet.

Bei der Berechnung der Variable stop_loss ist der Wert haHigh[BAR_COUNT-2] eine Berechnung, die aus dem Indikator stammt und mithilfe der Funktion NormalizeDouble(haHigh[BAR_COUNT-2], _Digits) normalisiert werden muss, um korrekt genutzt werden zu können.

Damit ist die Verarbeitung des Signals zum Verkauf abgeschlossen.

Zum Kauf nutzen wir das gleiche Prinzip.

Hier sehen Sie den vollständigen Code des Expert Advisors:

//+------------------------------------------------------------------+
//|                                           Heiken_Ashi_Expert.mq5 |
//|                                               Copyright VDV Soft |
//|                                                 vdv_2001@mail.ru |
//+------------------------------------------------------------------+
#property copyright "VDV Soft"
#property link      "vdv_2001@mail.ru"
#property version   "1.00"

#include <Trade\AccountInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>

//--- the list of global variables
//--- input parameters
input double Lot=0.1;    // Lot size
//--- indicator handles
int      hHeiken_Ashi;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   hHeiken_Ashi=iCustom(NULL,PERIOD_CURRENT,"Examples\\Heiken_Ashi");
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- trading should be allowed and number of bars calculated>100
   if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
      if(BarsCalculated(hHeiken_Ashi)>100)
        {
         CheckForOpenClose();
        }
//---
  }
//+------------------------------------------------------------------+
//| Checking of the position opening conditions                      |
//+------------------------------------------------------------------+
void CheckForOpenClose()
  {
//--- process orders only when new bar is formed
   MqlRates rt[1];
   if(CopyRates(_Symbol,_Period,0,1,rt)!=1)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return;
     }
   if(rt[0].tick_volume>1) return;

//--- to check the conditions we need the last three bars
#define  BAR_COUNT   3
//--- number of the indicator buffer for storage Open
#define  HA_OPEN     0
//--- number of the indicator buffer for storage High
#define  HA_HIGH     1
//--- number of the indicator buffer for storage Low
#define  HA_LOW      2
//--- number of the indicator buffer for storage Close
#define  HA_CLOSE    3

   double   haOpen[BAR_COUNT],haHigh[BAR_COUNT],haLow[BAR_COUNT],haClose[BAR_COUNT];

   if(CopyBuffer(hHeiken_Ashi,HA_OPEN,0,BAR_COUNT,haOpen)!=BAR_COUNT
      || CopyBuffer(hHeiken_Ashi,HA_HIGH,0,BAR_COUNT,haHigh)!=BAR_COUNT
      || CopyBuffer(hHeiken_Ashi,HA_LOW,0,BAR_COUNT,haLow)!=BAR_COUNT
      || CopyBuffer(hHeiken_Ashi,HA_CLOSE,0,BAR_COUNT,haClose)!=BAR_COUNT)
     {
      Print("CopyBuffer from Heiken_Ashi failed, no data");
      return;
     }
//---- check sell signals
   if(haOpen[BAR_COUNT-2]>haClose[BAR_COUNT-2])// bear candlestick 
     {
      CPositionInfo posinf;
      CTrade trade;
      double lot=Lot;
     //--- check if there is an open position, and if there is, close it
      if(posinf.Select(_Symbol))
        {
         if(posinf.Type()==POSITION_TYPE_BUY)
           {
            //            lot=lot*2;
            trade.PositionClose(_Symbol,3);
           }
        }
      //--- check and set Stop Loss level
      double stop_loss=NormalizeDouble(haHigh[BAR_COUNT-2],_Digits)+_Point*2;
      double stop_level=SymbolInfoDouble(_Symbol,SYMBOL_ASK)+SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point;
      if(stop_loss<stop_level) stop_loss=stop_level;
      //--- check the combination: the candle with the opposite color has formed
      if(haOpen[BAR_COUNT-3]<haClose[BAR_COUNT-3])
        {
         if(!trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,lot,SymbolInfoDouble(_Symbol,SYMBOL_BID),stop_loss,0))
            Print(trade.ResultRetcodeDescription());
        }
      else
      if(posinf.Select(_Symbol))
        {
         if(!trade.PositionModify(_Symbol,stop_loss,0))
            Print(trade.ResultRetcodeDescription());
        }
     }
//---- check buy signals
   if(haOpen[BAR_COUNT-2]<haClose[BAR_COUNT-2]) // bull candle
     {
      CPositionInfo posinf;
      CTrade trade;
      double lot=Lot;
     //--- check if there is an open position, and if there is, close it
      if(posinf.Select(_Symbol))
        {
         if(posinf.Type()==POSITION_TYPE_SELL)
           {
            //            lot=lot*2;
            trade.PositionClose(_Symbol,3);
           }
        }
      //--- check and set Stop Loss level
      double stop_loss=NormalizeDouble(haLow[BAR_COUNT-2],_Digits)-_Point*2;
      double stop_level=SymbolInfoDouble(_Symbol,SYMBOL_BID)-SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point;
      if(stop_loss>stop_level) stop_loss=stop_level;
      //--- check the combination: the candle with the opposite color has formed
      if(haOpen[BAR_COUNT-3]>haClose[BAR_COUNT-3])
        {
         if(!trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,lot,SymbolInfoDouble(_Symbol,SYMBOL_ASK),stop_loss,0))
            Print(trade.ResultRetcodeDescription());
        }
      else
      if(posinf.Select(_Symbol))
        {
         if(!trade.PositionModify(_Symbol,stop_loss,0))
            Print(trade.ResultRetcodeDescription());
        }

     }
  }
//+------------------------------------------------------------------+

Den vollständigen Text des Expert Advisors finden Sie ebenfalls in der angehängten Datei Heiken_Ashi_Expert.mq5. Kopieren Sie sie in den Ordner .. \MQL5\Experts und führen Sie MetaEditor über das Menü "Tools -> Editor MetaQuotes Language" oder mithilfe der Taste "F4" aus. Öffnen Sie als Nächstes im Fenster "Navigator" die Registerkarte "Experts" und laden Sie die Datei Heiken_Ashi_Expert.mq5 durch einen Doppelklick darauf in das Bearbeitungsfenster herunter und kompilieren Sie sie mit "F7".

Wenn alles richtig ausgeführt wurde, wird in der Registerkarte "Expert Advisors" im Fenster "Navigator" die Datei Heiken_Ashi_Expert erstellt. Der Indikator Heiken_Ashi.mq5 muss auf die gleiche Weise kompiliert werden. Er befindet sich im Ordner \MQL5\Indicators\Examples\.

4. Testen des Handelssystems mit historischen Daten

Um die Funktionsfähigkeit unseres Handelssystems zu überprüfen, nutzen wir den Strategietester in MetaTrader 5, der Teil der Handelsplattform ist. Der Tester wird über das Terminal-Menü "View -> Strategy Tester" (Ansicht -> Strategietester) oder mit der Tastenkombination "Strg+R" ausgeführt. Sobald er gestartet ist, sehen wir die Registerkarte "Settings" (Einstellungen) (Abbildung 3). 

 Abbildung 3.  Einstellungen des Strategietesters

Abbildung 3.  Einstellungen des Strategietesters

Konfiguration des Expert Advisors: Wählen Sie unseren Expert Advisor aus einer Liste, geben Sie den Testzeitraum von Anfang 2000 bis Ende 2009 an, die Höhe der anfänglichen Einlage beträgt 10.000 USD, deaktivieren Sie die Optimierung (weil wir nur einen Eingabeparameter haben und nur die Funktionsfähigkeit des HS überprüfen möchten).

Die Tests werden unter Verwendung von zwei Währungspaaren durchgeführt. Ich habe beschlossen, die Währungspaare EURUSD und GBPUSD zu verwenden.

Für die Tests habe ich beschlossen, die folgenden Zeiträume zu nutzen: H3, H6 und H12. Warum? Weil ich das HS auf Zeiträumen testen wollte, die im MetaTrader4-Terminal nicht vorhanden waren.

Fahren wir also fort. Wir wählen die Testwährung EURUSD, den Testzeitraum H3 und klicken auf "Start". Nach dem Abschluss des Tests sehen wir im Tester-Fenster zwei neue Registerkarten: "Results" (Ergebnisse) (Abb. 4) und "Graph" (Diagramm) (Abb. 5).

Abbildung 4. Ergebnisse des Strategietests für EURUSD H3

Abbildung 4. Ergebnisse des Strategietests für EURUSD H3

Anhand der Testergebnisse (Abb. 4) erkennen Sie, dass das HS für den Zeitraum von Anfang 2000 bis Ende 2009 mit den festgelegten Parametern einen Verlust von -2560,60 USD erzeugte.

Das Diagramm (Abb. 5) zeigt die Verteilung von Gewinnen und Verlusten mit der Zeit, was uns die Gelegenheit gibt, die Leistung des HS mit der Zeit zu überprüfen und Systemfehler zu analysieren.

 Abbildung 5. Registerkarte "Graph" des Strategietesters (EURUSD H3)

Abbildung 5. Registerkarte "Graph" des Strategietesters (EURUSD H3)

Ich hätte fast vergessen, zu erwähnen, dass die Registerkarte "Results" standardmäßig einen einfachen Bericht erzeugt. Zusätzlich haben wir die Möglichkeit, Transaktionen, Order und eine Berichterstattung in Dateien anzusehen.

Platzieren Sie dafür einfach den Cursor über der Registerkarte, klicken Sie mit der rechten Maustaste darauf und wählen Sie den entsprechenden Menüpunkt:

Abbildung 6. Kontextmenü der Registerkarte "Results" des Strategietesters

Abbildung 6. Kontextmenü der Registerkarte "Results" des Strategietesters

Hier sehen Sie das Testergebnis über einen sechsstündigen Zeitraum (H6):

 Abbildung 7. Registerkarte "Results" des Strategietesters (EURUSD H6)

Abbildung 7. Registerkarte "Results" des Strategietesters (EURUSD H6)

über einen zwölfstündigen Zeitraum (H12).

 Abbildung 8.  Registerkarte "Results" des Strategietesters (EURUSD H12)

Abbildung 8.  Registerkarte "Results" des Strategietesters (EURUSD H12)

Es sieht so aus, als wäre unsere Strategie für ein Währungspaar wie EURUSD nicht sehr wirksam. Wir können allerdings feststellen, dass die Variationen des Arbeitszeitraums sich deutlich auf das Ergebnis auswirkt.

Wir erweitern unseren Test auf das Währungspaar GBPUSD, um unsere letzten Schlüsse über die Wirksamkeit unseres HS ziehen zu können.

 Abbildung 9.  Registerkarte "Results" des Strategietesters (GBPUSD H3)

Abbildung 9.  Registerkarte "Results" des Strategietesters (GBPUSD H3)

 Abbildung 10.  Registerkarte "Results" des Strategietesters (GBPUSD H6)

Abbildung 10.  Registerkarte "Results" des Strategietesters (GBPUSD H6)


 Abbildung 11.  Registerkarte "Results" des Strategietesters (GBPUSD H12)

Abbildung 11.  Registerkarte "Results" des Strategietesters (GBPUSD H12)

 Abbildung 12.  Registerkarte "Results" des Strategietesters (GBPUSD H12)

Abbildung 12.  Registerkarte "Graph" des Strategietesters (GBPUSD H12)

Nach der Analyse der Testergebnisse stellen wir fest, dass bei der Verwendung eines Währungspaars wie GBPUSD unser System in zwei unterschiedlichen Fällen positive Ergebnisse aufzeigt. Über einen zwölfstündigen Zeitraum haben wir einen beträchtlichen Gewinn von 8903,23 USD gemacht, obwohl dieser über neun Jahre eingegangen ist.

Wer interessiert ist, kann andere Währungspaare testen. Ich nehme an, dass das Ergebnis besser ausfällt und der verwendete Zeitraum länger sein sollte, je unbeständiger das Paar ist.

Fazit

Zusammenfassend möchte ich betonen, dass dieses Handelssystem kein "Heiliger Gral" ist und nicht für sich allein verwendet werden kann.

Wenn wir aber die Umkehrsignale mit zusätzlichen Signalen (Kerzenanalyse, Wellenanalyse, Indikatoren, Trends) von den Konsolidierungssignalen trennen, kann es bei einigen unbeständigen Handelsinstrumenten ziemlich nützlich sein, auch wenn es wahrscheinlich keine "krassen" Gewinne einbringt.

__________________________________ 
* "Nani Desu Ka?" - Was ist das?  (Japanisch)

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

Beigefügte Dateien |
Simulink: ein Leitfaden für Expert Advisor-Entwickler Simulink: ein Leitfaden für Expert Advisor-Entwickler
Ich bin kein professioneller Programmierer, deshalb ist das Prinzip "vom Einfachen zum Komplexen" bei der Arbeit an Entwicklungen von Handelssystemen für mich von äußerster Wichtigkeit. Was genau heißt "einfach" für mich? Zunächst heißt das die Anschaulichkeit des Erzeugungsprozesses eines Systems und die Logik seiner Funktionsweise. Und es heißt auch möglichst wenig handgeschriebener Code. In diesem Beitrag versuche ich ein Handelssystem auf Grundlage des Matlab-Pakets zu erzeugen und zu testen und anschließend einen Expert Advisor für MetaTrader 5 zu schreiben. Im Testvorgang werden die historischen Daten von MetaTrader 5 eingesetzt.
Virtual Order Manager zum Verwalten von Ordern innerhalb der positionszentrischen Umgebung von MetaTrader 5 Virtual Order Manager zum Verwalten von Ordern innerhalb der positionszentrischen Umgebung von MetaTrader 5
Diese Klassenbibliothek kann einem Expert Advisor in MetaTrader 5 hinzugefügt werden, damit dieser orderzentrisch geschrieben werden kann, weitestgehend ähnlich zu MetaTrader 4, im Vergleich zum positionsbasierten Ansatz von MetaTrader 5. Dies geschieht durch die Verwaltung von virtuellen Ordern im MetaTrader 5 Client Terminal und die Aufrechterhaltung eines Schutzstopps des Brokers für jede Position, um vor Katastrophenfällen zu schützen.
Fehler finden und Protokollierung Fehler finden und Protokollierung
Der MetaEditor 5 verfügt über ein Feature zur Fehlersuche. Doch Wenn Sie Ihre MQL5 Programme schreiben, möchten Sie oft nicht nur einzelne Werte anzeigen, sondern alle Meldungen sehen können, die während des Tests und der Online-Arbeit auftauchen. Wenn die Inhalte der Protokolldatei groß sind, dann liegt es nahe, die rasche und schnelle Abfrage der benötigten Meldung zu automatisieren In diesem Beitrag geht es um das Finden von Fehlern in den MQL5 Programmen sowie um Methoden der Protokollierung. Darüber hinaus werden wir die Protokollierung in Dateien vereinfachen und LogMon kennen lernen, ein einfaches Programm zur bequemen Ansicht von Protokollen.
Anlegen eines mehrw&#228;hrungsf&#228;higen Indikators unter Verwendung zahlreicher Indikatorzwischenspeicher Anlegen eines mehrw&#228;hrungsf&#228;higen Indikators unter Verwendung zahlreicher Indikatorzwischenspeicher
Seit Kurzem erfreut sich die Clusteranalyse am Devisenmarkt zunehmenden Interesses. MQL5 eröffnet neue Möglichkeiten zur Untersuchung der Bewegungstendenzen von Währungspaaren (Kürzeln). Eine wesentliche Eigenschaft von MQL5, die diese Programmiersprache von ihrer Vorgängerin MQL4 abhebt, ist die Möglichkeit der Verwendung einer unbegrenzten Zahl von Zwischenspeichern (Puffern) für Indikatoren. In diesem Beitrag wird ein Beispiel für die Erstellung eines mehrwährungsfähigen Indikators vorgestellt.