Handeln nach den Ebenen von DiNapoli

Dmitriy Zabudskiy | 29 Dezember, 2017


Einführung

Genau wie in unserem wirklichen Leben entwickelt sich der Markt ständig weiter. Etwas, das gestern noch perfekt funktionierte, versagt auf einmal. Es gibt jedoch einige fundamentale Strategien, die im Laufe der Zeit zwar geringfügige Korrekturen erfuhren, sich aber nicht grundsätzlich veränderten. Eine dieser sind die "Ebenen nach DiNapoli", eine nach ihrem Schöpfer benannte Strategie. Es ist einen vereinfachte Version der Fibonacci Retracements

Ausgangspunkte der Strategie sind die Fibonacci-Zahlen 38,2% und 61,8%. Als Take-Profit werden akzeptiert: COP (Contracted Objective Point, Mindestziel), 61,8%, OP (Objective Point, normales Ziel), 100%, XOP (Expanded Objective Point, erweitertes Ziel), 161,8%. Alle Abstände sind in Prozent der Trendlänge angegeben (siehe Abb. 1).

Abb. 1. Die “Ebenen des DiNapoli” für EURUSD H4

Abb. 1. Die Ebenen des DiNapoli für EURUSD H4

In Abbildung 1 werden die Ebenen mittels der Fibonacci-Werkzeuge ermittelt, die Teil des MetaTrader 5 Standardpakets sind - Fibonacci retracements (rote Farbe) und expansions (blaue Farbe). Außerdem zeigt die Abbildung, wie die Ebenen aufgebaut sind. Die Senkrechte, die durch zwei Pfeilen markiert ist, hat eine Länge von 61,8%, der durch den Trend (rote Abwärtslinie) und der Preisspanne abwärts ermittelt wurde und den COP-Wert bildet.

Für die Positionseröffnung gibt es vier Möglichkeiten: "Bushes", "Bonsai", "Minesweeper A" und "Minesweeper B". Die ersten beiden sind die aggressivsten. Ihre Positionseröffnung erfolgt bei der ersten Korrektur. Die letzten beiden Szenarien implizieren die Eröffnung einer Position nach der zweiten Korrektur. Weitere Unterschiede zwischen diesen Möglichkeiten bestehen in der Platzierung des Stop-Loss. Diese Methoden sind im Artikel "Das Handelssystem DiNapoli" ausführlich beschrieben, deshalb wird das hier nicht weiter erörtert.

Mit der obigen Abbildung wollten wir nur ein klassisches Bild der DiNapoli-Ebenen zeigen, die erwähnte Strategiegrundlage. Wie man sieht, ist die beste Option in den Markt einzusteigen, die Ebene von 61,8% (die rote Kursmarkierung), aber diese Preisebene wird nicht immer erreicht. Daher begannen einige Händler, bereits bei bei 38,2% zu verkaufen: Dies wird durch eine Abwärtskerze um 20:00 Uhr unterstützt. Solche Positionseröffnungen sind typisch für den aggressiven Handel nach der Methode "Bushes". Derzufolge setzt ein Händler den Stop auf eine höhere Ebene als diejenige, auf der die Position eröffnet wurde. Das Schließen der Position erfolgt auf der COP-Ebene (61,8%). Sie ist in der Abbildung mit der blauen Preisangabe gekennzeichnet.

Es sieht recht einfach aus, aber in der Praxis werden die beschriebenen Ebenen aufgrund des wechselnden Trendverhaltens nicht immer ausgelöst. Um den Trend genauer bestimmen zu können, bietet der Autor zusätzlich zu den Ebenen Indikatoren an: Ein gleitender Durchschnitt (MA) und den Stochastik Oszillator. Auf dieser Grundlage schlage ich vor, eine profitable Strategie zu entwickeln und sie in einem Expert Advisor umzusetzen.


Strategiebildung mit den Standardmitteln des MetaTrader 5

Für eine effektive Handelsstrategie mit den DiNapoli-Ebenen müssen eine große Anzahl von Faktoren funktionieren. Daher ist die Realisierung sehr komplex und interessant. Auch gibt es Schwierigkeiten in der Organisation des Handels: Durch diese Strategie muss man manchmal lange auf einen geeigneten Zeitpunkt warten, um eine Position zu eröffnen. Eine kontinuierliche, manuelle Überwachung ist eine schwierige Aufgabe für einen Händler, so dass sich in eine maschinelle Umsetzung geradezu anbietet.

Ich werde versuchen, die Strategie, die als Grundlage für unsere Expert Advisor dient, möglichst einfach und verständlich zu erläutern und im Expert Advisor umzusetzen.

Abb. 2. Die DiNapoli-Ebenen mit den Hilfsindikatoren für EURUSD H4 (Aufwärtstrend)

Abb. 2. Die DiNapoli-Ebenen mit den Hilfsindikatoren für EURUSD H4 (Aufwärtstrend)

Abb. 2 zeigt die DiNapoli-Ebenen mit den Hilfsindikatoren für EURUSD H4. Folgendes ist zu sehen: Die DiNapoli-Ebenen, der Indikator Stochastik (8,3,3) und zwei gleitenden Durchschnitte, verschoben um 5 Kerzen und den Periodenlängen 25 (rot) und 7 (blau).

Aber eines nach dem anderen. In der Grafik sehen wir einen Aufwärtstrend mit einem darüber gelegten Raster der Fibonacci-Ebenen 23,6%, 38,2%, 50%, 61,8%. Hier gibt es mehr Ebenen als bei der klassischen Version: Die Praxis hat gezeigt, dass der Preis von jeder abprallen kann. 

Bei einer Korrektur wird die Erweiterung der Fibonacci-Ebenen überlagert: So entstehen die COP- und OP-Ebenen. Sowohl in diesem Fall als auch in der Strategie im Allgemeinen sind diese Ebenen jedoch unbedeutend. Hier werden sie ausschließlich für die Bestimmung der Take-Profits verwendet (später wird es im Code zu sehen sein).

Letztendlich beruht die Eröffnung auf vier Regeln. Die Abbildung zeigt, dass, wenn man die Trendwende gleich zu Beginn erkennt und eine Position im Punkt 23,6% eröffnet, sie Gewinn abwirft; allerdings wird der Rückgang sehr signifikant sein. Tatsächlich ist das unbefriedigend, deshalb werden wir weiter nach einem verlässlicheren Einstiegspunkt suchen. 

  • Regel eins: Die Positionseröffnung ist auf den DiNapoli-Ebenen von 23,6% bis 61,8% möglich. Das ist ein ziemlich große Spannbreite, und deshalb sollten wir zur zweiten Regel kommen.

Der folgende Signalfilter ist der Indikator Stochastik (mit den Parametern 8,3,3,3) mit zwei Ebene, 30 und 70.

  • Regel zwei: Kaufen, wenn die Signal- und die Hauptlinie der Stochastik unter 30 liegen, und Verkaufen, wenn sie über 70 liegen.

Bestimmen wir jetzt den Trend. Dafür verwenden wir die gleitenden Durchschnitte (verschoben um 5, Periodenlänge 25). Es stellt sich heraus, dass der Kauf möglich ist, wenn der Preis über der Trendlinie ist, während er unter ihr für einen Verkauf sein sollte. Aber auch das ist ein ziemlich großer Bereich, und um ihn zu reduzieren, führen wir einen weiteren gleitenden Durchschnitt ein (verschoben um 5, Periodenlänge 7). Aber trotz der Verwendung kann der Bereich zu groß bleiben. In solchen Fällen führen wir eine zusätzliche Einschränkung ein: Es ist erlaubt, Positionen nur in der "oberen Hälfte" der Differenz zu eröffnen, näher an der Linie mit der Periodenlänge 25.

  • Regel drei: Kaufe in der zweiten Hälfte des Zeitintervalls, näher an der Linie mit der Periodenlänge 25, während die Linie mit einem kleineren Periodenlänge darüber liegt.
  • Regel vier: Verkaufe in der zweiten Hälfte des Zeitintervalls, näher an der Linie mit der Periodenlänge von 25, wenn die Linie mit einem kleineren Periodenlänge darunter liegt.

Angenommen, die oben genannten Bedingungen haben sich ergeben und wir haben eine Position eröffnet. Strellen wir jetzt die Regeln für das Schließen auf. Dazu werden wir die durch die Erweiterung der von Fibonacci gebildeten Ebenen sowie die Stochastik verwenden.

  • Regel fünf: Schließe eine Position, wenn der Preis eines der DiNapoli-Ziel (COP, OP, XOP) erreicht, oder die Stochastik ein Signal zum Schließen gibt.

In den Abbildungen 2 und 3 sind die Bereiche, auf die diese Regeln zutreffen, in gelben Rechtecken dargestellt.

Abb. 3. Die DiNapoli-Ebenen mit den Hilfsindikatoren für EURUSD H4 (Abwärtstrend)

Abb. 3. Die DiNapoli-Ebenen mit den Hilfsindikatoren für EURUSD H4 (Abwärtstrend)

Wie man sieht, sind die resultierenden Regeln logisch und verständlich. Allerdings gibt es noch keine Take-Profits und Stop-Loss' und das Nachziehen des Stopps auf Breakeven fehlt noch. All dies wird nachstehend erörtert.


Programmieren der Strategie

Eingabeparameter

Zuerst wird die Klasse CTrade (Trade.mqh) eingebunden. Dann werden die Parameter der DiNapoli-Ebenen festgelegt - für die minimalen und maximalen Eröffnungspreise. Der Standard ist, wie oben beschrieben: 23,6% bis 61,8%. Aber für verschiedene Währungspaare können sie variieren und verschiedenen Grenzen haben.

Die folgenden Parameter sind für Take-Profit und Stop-Loss. Stop-Loss wird gemäß der Ebenen vom Höchstpreis platziert. In den Abbildungen 2 und 3 sind sie rot dargestellt. Take-Profit wird vom Eröffnungspreis ermittelt.

Das heißt, wenn der Kaufpreis z. B. auf der Ebene 50% liegt, befinden sich Stop-Loss auf 70% und Take-Profit auch auf 70%. Das bedeutet, dass, wenn man davon ausgeht, dass 100% 100 Punkte sind, Stop-Loss um 20 Punkte unter dem Kaufpreis ist, während Take-Profit um bis zu 70 Punkte über ihm. Dies muss bei der Optimierung des EA berücksichtigt werden. Des Weiteren müssen wir definieren, ob die Verfolgung oder der Übergang zum Breakeven erfolgen soll. Nach den aktuellen Parametern im Code, wenn der Preis um 400 Punkte überschritten wird, wird Stop Loss auf die Gewinnseite um 10 Punkte verschoben.

Des Weiteren müssen wir definieren, ob der Stopp nachgezogen oder auf Breakeven verschoben werden soll. Gemäß den aktuellen Parametern im Code, wird Stop-Loss, nachdem der Preis 400 Punkte in Richtung des Gewinns überschritten hat, um 10 Punkte verschoben.

Die übrigen Parameter benötigen keine Kommentare.

//+------------------------------------------------------------------+
//|                                               Dinapoli_v1.01.mq5 |
//|                                                          Aktiniy |
//|                                            https://www.mql5.com/ |
//+------------------------------------------------------------------+
#property copyright "Aktiniy"
#property link      "https://www.mql5.com/"
#property version   "1.01"
#include<Trade\Trade.mqh>
//--- Eingabeparameter
//--- Fibo-Zahlen
input double   percent_min_enter=23.6;      // Kleinster Eröffnungspreis in Prozent
input double   percent_max_enter=61.8;      // Größter Eröffnungspreis in Prozen
input double   percent_for_tp=60;           // Prozentsatz für möglichen Take-Profit
input double   percent_for_sl=70;           // Prozentsatz für möglichen Stop-Loss
input int      trailing_sl=400;             // Umschalten auf Breakeven bei Erreichen dieser Schwelle
input int      trailing_profit=10;          // Breakeven-Ebene in 'points'
//--- Aufträge
input long     magic_number=65758473787389; // Magicnummer
input double   order_volume=0.01;           // Lotgröße
input int      order_deviation=100;         // Abweichung bei der Positionseröffnung
//--- Stochastik
input int      stochastic_k=8;              // Indikator Stochastik “Periode %К"
input int      stochastic_d=3;              // Indikator Stochastik “Verlangsamung"
input int      stochastic_slowing=3;        // Indikator Stochastik “Periode %D"
input double   stochastic_up_level=70;      // Indikator Stochastik “Obere Ebene"
input double   stochastic_down_level=30;    // Indikator Stochastik "Untere Ebene"
//--- MA Rot 25 5
input int      ma_red_period=25;            // Indikator MA ROT “Periodenlänge"
input int      ma_red_shift=5;              // Indikator MA ROT “Verschub"
//--- MA BLAU 7 5
input int      ma_blue_period=7;            // Indikator MA BLAU “Periodenlänge"
input int      ma_blue_shift=5;             // Indikator MA BLAU “Verschub"
//--- Variablen
CTrade trade;
int stochastic_handle=0;
char answer_stochastic=0;
int ma_red_handle=0;
int ma_blue_handle=0;
char answer_ma=0;
int fractals_handle=0;


Abschließend werden die Variablen für die Handles der Indikatoren und den Ergebnissen der Signalfunktionen angelegt.

Initialisierung

Unten ist eine kleine Initialisierungsfunktion. Hier wird CTrade angelegt und die Handles der Indikatoren erstellt.

//+------------------------------------------------------------------+
//| Initialisierungsfunktion des Experten                            |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   trade.SetExpertMagicNumber(magic_number);
   trade.SetDeviationInPoints(order_deviation);
   trade.SetTypeFilling(ORDER_FILLING_FOK);
   trade.SetAsyncMode(false);

   stochastic_handle=iStochastic(_Symbol,_Period,stochastic_k,stochastic_d,stochastic_slowing,MODE_SMA,STO_LOWHIGH);
   ma_red_handle=iMA(_Symbol,_Period,ma_red_period,ma_red_shift,MODE_SMA,PRICE_CLOSE);
   ma_blue_handle=iMA(_Symbol,_Period,ma_blue_period,ma_blue_shift,MODE_SMA,PRICE_CLOSE);
   fractals_handle=iFractals(_Symbol,_Period);
//---
   return(INIT_SUCCEEDED);
  }


Vor der Hauptfunktion wenden wir uns aber noch dem Ermitteln der Signale zu.

Die Signale der Stochastik

//+------------------------------------------------------------------+
//| Die Signale der Stochastik                                       |
//+------------------------------------------------------------------+
void Stochastic(char &answer)                                                                          // 0 - kein Signal; 1 - Aufwärtssignal; 2 - Abwärtssignal
  {
   answer=0;                                                                                           // Antwort
   double stochastic_line_main[3];
   double stochastic_line_signal[3];
   int line_main=CopyBuffer(stochastic_handle,0,0,3,stochastic_line_main);
   int line_signal=CopyBuffer(stochastic_handle,1,0,3,stochastic_line_signal);
   if(line_main!=3 || line_signal!=3)
     {Alert("Error of copy iStochastic: main line=",line_main,", signal line=",line_signal);}          // Prüfen der Daten der Stochastik

   if(stochastic_line_main[1]>stochastic_up_level && stochastic_line_signal[1]>stochastic_up_level)
     {answer=2;}                                                                                       // Verkaufsgelegenheit
   if(stochastic_line_main[1]<stochastic_down_level && stochastic_line_signal[1]<stochastic_down_level)
     {answer=1;}                                                                                       // Kaufgelegenheit
  }


Letztendlich ist das ganz einfach: Es werden die letzten drei Werte des Indikators kopiert, und der letzte von ihnen wird mit den in den Einstellungen voreingestellten Werten verglichen. Die Funktion weist die Ergebnis in einer Variablen zu.

Die Signale der MAs

//+------------------------------------------------------------------+
//| Die Signale der MAs                                              |
//+------------------------------------------------------------------+
void MA(char &answer,                                               // 0 - Kein Signal; 1 - Kaufsignal; 2 - Verkaufssignal
        double &line_blue,
        double &line_red,
        double ask,
        double bid)
  {
   answer=0;                                                        // Antwort
   double ma_red[3];
   double ma_blue[3];
   int red=CopyBuffer(ma_red_handle,0,0,3,ma_red);
   int blue=CopyBuffer(ma_blue_handle,0,0,3,ma_blue);
   if(red!=3 || blue!=3)
     {Alert("Error of copy iMA: MA red=",red,", MA blue=",blue);}   // Prüfen der Daten der MAs rot und blau

   line_blue=ma_blue[2];
   line_red=ma_red[2];

   if(ma_blue[2]>ma_red[2])                                         // anscheinend eine Aufwärtstrend
      if(ask<ma_blue[2])                                            // anscheinend ist der Preis zurückgekommen
         if(ask>ma_red[2])
           {answer=1;}                                              // bald ist eine Bewegung in Trendrichtung (aufwärts) möglich

   if(ma_blue[2]<ma_red[2])                                         // anscheinend gibt es einen Abwärtstrend
      if(bid>ma_blue[2])                                            // anscheinend ist der Preis zurückgekommen
         if(bid<ma_red[2])
           {answer=2;}                                              // bald ist eine Bewegung in Trendrichtung (abwärts) möglich
  }


Auch hier werden drei letzte Werte in die Puffer kopiert; dann wird überprüft, ob der Preis zwischen den beiden zwei Indikatorlinien liegt. Früher haben wir darüber diskutiert, dass oft das Intervall, innerhalb dessen der Handel erlaubt ist, eingeengt werden sollte. Aus diesem Grund übergibt die Funktion nicht nur den einen, letzten Wert, sondern die letzten drei Werte der beiden gleitenden Durchschnitte. Wie das Handelsintervall verkleinert werden kann, wird zu einem späteren Zeitpunkt besprochen.

Abfrage der Daten der Fraktale

Das Ermitteln der Trendstärke ist komplexer. Das basiert auf den Daten der Fraktale. Zu Beginn der Funktion werden die letzten 100 Daten kopiert, dann erfolgt die Überprüfung der oberen und unteren Signale in zwei Zyklen. Hier wird die Verfügbarkeit der Fraktale überprüft: Alle Werte über 10'000 werden herausgefiltert, dann werden benachbarte Werte verglichen und nach dem größten und kleinsten ersten Fraktal vom Ende her gesucht.

//+------------------------------------------------------------------+
//| Abfrage der Daten der Fraktale                                   |
//+------------------------------------------------------------------+
void Fractals(double &price_up,
              double &price_down)
  {
   price_up=0;
   price_down=0;
   double fractals_up[100];
   double fractals_down[100];
   int up=CopyBuffer(fractals_handle,0,0,100,fractals_up);
   int down=CopyBuffer(fractals_handle,1,0,100,fractals_down);
   if(up!=100 || down!=100)
     {Alert("Error of copy iFractals: Fractals up=",up,", Fractals down=",down);} // Prüfen der Daten der Fraktale hoch und tief

   double price_high=0;
   double price_low=0;

   for(int x=99; x>0; x--)                                                        // Schleife des oberen Fraktals
     {
      if(fractals_up[x]<10000)                                                    // Prüfen der Verfügbarkeit des Fraktals
        {
         if(price_high==0){price_high=fractals_up[x];}                            // Anfangsprüfung
         if(price_high>fractals_up[x]){break;}                                    // Falls es ein Fraktaltief ist, abbrechen
         else{price_high=fractals_up[x];}                                         // Falls es eine Fraktalhoch ist, Daten kopieren
        }
     }

   for(int x=99; x>0; x--)                                                        // Schleife für ein Fraktaltief
     {
      if(fractals_down[x]<10000)                                                  // Prüfen der Verfügbarkeit der Fraktale
        {
         if(price_low==0){price_low=fractals_down[x];}                            // Anfangsprüfung
         if(price_low<fractals_down[x]){break;}                                   // Falls es ein Fraktalhoch ist, abbrechen
         else{price_low=fractals_down[x];}                                        // Falls es eine Fraktaltief ist, Daten kopieren
        }
     }

   double price_ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);                         // Kaufpreis
   double price_bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);                         // Verkaufspreis

   if(price_high>price_ask && price_high>price_bid)                               // Prüfen, ob Kauf und Verkaufspreis zwischen dem Hoch und Tief der Preise liegt
      if(price_low<price_ask && price_low<price_bid)
        {
         price_up=price_high;                                                     // Zuweisung des Preises
         price_down=price_low;
        }
  }
//+------------------------------------------------------------------+


Um sicherzustellen, dass das Signal zuverlässig ist, wird vor der Antwort geprüft, ob der Preis innerhalb der gefundenen Spanne liegt. Dies geschieht, weil das letzte und wahrscheinlich auch das Schlüsselfraktal nach der Erzeugung von zwei letzten Kerzen (nach den Regeln für die Ermittelung der Fraktale) gebildet wird.

Berechnung der Eröffnungspreis einer Position

Die wichtigste Funktion ist die Berechnung der DiNapoli-Ebenen. Sie benötigt die zuvor erhaltenen Höchst- und Tiefstpreise sowie Daten über die Richtung des voraussichtlichen Trends und die letzten Werte aus den gleitenden Durchschnitten. Zuerst werden alle erhaltenen Entfernungen in 'points' umgewandelt, und, von diesen ausgehend, werden die Bereiche basierend auf den zuvor in den Parametern angegebenen Prozentsätzen berechnet. Die Bereichswerte müssen aber noch normalisiert werden.

//+------------------------------------------------------------------+
//| Berechnen des Eröffnungspreises                                  |
//+------------------------------------------------------------------+
void Price_for_order(double high_price,
                     double low_price,
                     double &p_enter_min,
                     double &p_enter_max,
                     double &p_tp,
                     double &p_sl,
                     char trend,                                      // 1 - Aufwärtstrend; 2 - Aufwärtstrend
                     double blue_line,
                     double red_line
                     )
  {
   double point_price=(high_price-low_price);
   double point_enter_min=point_price*percent_min_enter/100;
   double point_enter_max=point_price*percent_max_enter/100;
   double point_tp=point_price*percent_for_tp/100;
   double point_sl=point_price*percent_for_sl/100;
   double point_ma_line=MathAbs(blue_line-red_line)/2;

   point_enter_min=NormalizeDouble(point_enter_min,_Digits);
   point_enter_max=NormalizeDouble(point_enter_max,_Digits);
   point_ma_line=NormalizeDouble(point_ma_line,_Digits);

   point_tp=NormalizeDouble(point_tp,_Digits);
   point_sl=NormalizeDouble(point_sl,_Digits);

   if(trend==1)                                                       // Aufwärtstrend
     {
      p_enter_min=high_price-point_enter_min;
      double p_ma_min=red_line+point_ma_line;
      if(p_enter_min>p_ma_min)
        {p_enter_min=p_ma_min;}
      p_enter_max=high_price-point_enter_max;
      if(p_enter_max>p_enter_min)
        {p_enter_max=red_line;}

      p_tp=p_enter_min+point_tp;
      p_sl=high_price-point_sl;
     }

   if(trend==2)                                                       // Abwärtstrend
     {
      p_enter_min=low_price+point_enter_min;
      double p_ma_min=red_line-point_ma_line;
      if(p_enter_min<p_ma_min)
        {p_enter_min=p_ma_min;}
      p_enter_max=low_price+point_enter_max;
      if(p_enter_max<p_enter_min)
        {p_enter_max=red_line;}

      p_tp=p_enter_min-point_tp;
      p_sl=low_price+point_sl;
     }
  }


Weiterhin werden, je nach Trendrichtung, die Preise berechnet und von der Funktion zurückgegeben.

Anpassen und Schließen einer Position

Zuerst werden die alle Daten der letzten Position ermittelt. Je nachdem wird die Position angepasst (Stop-Loss auf Breakeven) oder geschlossen, wenn die Stochastik ein entgegengesetztes Signal liefert.

//+------------------------------------------------------------------+
//| Anpassen und Schließen einer Position                            |
//+------------------------------------------------------------------+
void Position_mod(double ask,
                  double bid,
                  int point,
                  int profit,
                  char stochastic)
  {
   double price=trade.RequestPrice();
   double tp=trade.RequestTP();
   double sl=trade.RequestSL();
   double sl_point=point*_Point;
   double sl_profit=profit*_Point;
   double tp_point=(MathAbs(tp-price))/2;

   if(trade.RequestType()==ORDER_TYPE_BUY)              // Kaufauftrag
     {
      if(sl<price && bid>(price+sl_point))
        {
         sl_profit=sl_profit+price;
         trade.PositionModify(_Symbol,sl_profit,tp);
        }
      if(stochastic==2)                                 // Abwärtsbewegung erwartet
        {
         trade.PositionClose(_Symbol,order_deviation);
        }
     }
   if(trade.RequestType()==ORDER_TYPE_SELL)             // Verkaufsauftrag
     {
      if(sl>price && ask<(price-sl_point))
        {
         sl_profit=sl_profit-price;
         trade.PositionModify(_Symbol,sl_profit,tp);
        }
      if(stochastic==1)                                 // Aufwärtsbewegung erwartet
        {
         trade.PositionClose(_Symbol,order_deviation);
        }

     }
  }


Die Konsolidierungsfunktion

Die letztere Funktion fasst alles zuvor Besprochene zusammen. Zu Beginn werden alle übereinstimmenden Variablen deklariert. Dann werden durch die Funktionen von Indikatoren die aktuellen Werte der "oberen Regeln der Strategie" empfangen. Danach erfolgt die Aufteilung, abhängig von den erhaltenen Antworten gemäß den "oberen Regeln". Die Größe des Trends und die Preise für eine günstige Positionseröffnung werden berechnet. Wenn es keine offenen Positionen gibt und der Preis im berechneten Bereich liegt, wird die Position geöffnet.

//+------------------------------------------------------------------+
//| Experten Funktion OnTick                                         |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double price_high=0;                                           // Höchstpreis zum Ermitteln der Fraktale
   double price_low=0;                                            // Tiefstpreis für die Ermittlung der Fraktale

   double price_enter_min=0;                                      // kleinster Eröffnungspreis
   double price_enter_max=0;                                      // höchster Eröffnungspreis
   double price_tp=0;                                             // Take-Profit
   double price_sl=0;                                             // Stop-Loss

   double price_ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);         // Kaufpreisabfrage
   double price_bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);         // Verkaufspreisabfrage

   double ma_blue_line=0;                                         // Wert des schnellen MA BLAU
   double ma_red_line=0;                                          // Wert des langsamen MA ROT

   Stochastic(answer_stochastic);
   MA(answer_ma,ma_blue_line,ma_red_line,price_ask,price_bid);

   if(answer_stochastic==1)                                       // Aufwärtsbewegung erwartet
     {
      if(answer_ma==1)                                            // Wir sind im Kaufbereich
        {
         Fractals(price_high,price_low);
         Price_for_order(price_high,price_low,price_enter_min,price_enter_max,price_tp,price_sl,1,ma_blue_line,ma_red_line);

         if(price_ask<price_enter_min && price_ask>price_enter_max)
           {
            if(PositionsTotal()==0)
              {
               trade.Buy(order_volume,_Symbol,price_ask,price_sl,price_tp,"Buy");
              }
           }
        }
     }

   if(answer_stochastic==2)                                        // Wirt sind im Verkaufsbereich
     {
      if(answer_ma==2)                                             // Abwärtsbewegung erwartet
        {
         Fractals(price_high,price_low);
         Price_for_order(price_high,price_low,price_enter_min,price_enter_max,price_tp,price_sl,2,ma_blue_line,ma_red_line);

         if(price_bid>price_enter_min && price_bid<price_enter_max)
            if(PositionsTotal()==0)
              {
               trade.Sell(order_volume,_Symbol,price_bid,price_sl,price_tp,"Sell");
              }
        }
     }

   if(PositionsTotal()!=0)
     {
      Position_mod(price_ask,price_bid,trailing_sl,trailing_profit,answer_stochastic);
     }

  }


Falls es bereits offenen Positionen gibt, wird die Funktion zum Anpassen/Löschen aufgerufen. Das ist das Ende des Codes. Jetzt ist es an der Zeit, den Expert Advisor zu testen.


Testergebnisse

Der Expert Advisor Dinapoli_v1.01 wurde mit verschiedenen Währungspaaren im Zeitrahmen H4 getestet. Es wird die folgende Zeitspanne verwendet: Von 2017.01.01 bis 2017.11.12.

Symbol: EURUSD

Parameter:

percent_min_enter=33.6 magic_number=65758473787389 stochastic_up_level=70
percent_max_enter=56 order_volume=0.01 stochastic_down_level=30
percent_for_tp=145 order_deviation=100 ma_red_period=25
percent_for_sl=100 stochastic_k=8 ma_red_shift=5
trailing_sl=675 stochastic_d=3 ma_blue_period=7
trailing_profit=40 stochastic_slowing=3 ma_blue_shift=5



Abb. 4. Testergebnisse EURUSD H4 (2017.01.01 - 2017.11.12)

Symbol: GBPUSD

Parameter:

percent_min_enter=23.6 magic_number=65758473787389 stochastic_up_level=90
percent_max_enter=50 order_volume=0.01 stochastic_down_level=30
percent_for_tp=335 order_deviation=100 ma_red_period=15
percent_for_sl=63 stochastic_k=3 ma_red_shift=5
trailing_sl=425 stochastic_d=1 ma_blue_period=4
trailing_profit=20 stochastic_slowing=4 ma_blue_shift=5



Abb. 5. Testergebnisse GBPUSD H4 (2017.01.01 - 2017.11.12)

Symbol: NZDUSD

Parameter:

percent_min_enter=31.6 magic_number=65758473787389 stochastic_up_level=60
percent_max_enter=88 order_volume=0.01 stochastic_down_level=30
percent_for_tp=45 order_deviation=100 ma_red_period=24
percent_for_sl=95 stochastic_k=10 ma_red_shift=5
trailing_sl=550 stochastic_d=2 ma_blue_period=4
trailing_profit=100 stochastic_slowing=1 ma_blue_shift=5



Abb. 6. Testergebnisse NZDUSD H4 (2017.01.01 - 2017.11.12)

Symbol: USDCAD

Parameter:

percent_min_enter=23.6 magic_number=65758473787389 stochastic_up_level=60
percent_max_enter=73 order_volume=0.01 stochastic_down_level=20
percent_for_tp=315 order_deviation=100 ma_red_period=25
percent_for_sl=69 stochastic_k=10 ma_red_shift=5
trailing_sl=325 stochastic_d=1 ma_blue_period=3
trailing_profit=10 stochastic_slowing=1 ma_blue_shift=5



Abb. 7. Testergebnisse USDCAD H4 (2017.01.01 - 2017.11.12)

Symbol: USDCHF

Parameter:

percent_min_enter=49.6 magic_number=65758473787389 stochastic_up_level=70
percent_max_enter=69 order_volume=0.01 stochastic_down_level=40
percent_for_tp=55 order_deviation=100 ma_red_period=20
percent_for_sl=98 stochastic_k=13 ma_red_shift=5
trailing_sl=900 stochastic_d=6 ma_blue_period=12
trailing_profit=40 stochastic_slowing=3 ma_blue_shift=5



Abb. 8. Testergebnisse USDCHF H4 (2017.01.01 - 2017.11.12)

Symbol: USDJPY

Parameter:

percent_min_enter=23.6 magic_number=65758473787389 stochastic_up_level=60
percent_max_enter=50 order_volume=0.01 stochastic_down_level=20
percent_for_tp=295 order_deviation=100 ma_red_period=22
percent_for_sl=53 stochastic_k=3 ma_red_shift=5
trailing_sl=750 stochastic_d=1 ma_blue_period=5
trailing_profit=10 stochastic_slowing=1 ma_blue_shift=5



Abb. 9. Testergebnisse USDJPY H4 (2017.01.01 - 2017.11.12)

Symbol: AUDUSD

Parameter:

percent_min_enter=23.6 magic_number=65758473787389 stochastic_up_level=80
percent_max_enter=81 order_volume=0.01 stochastic_down_level=40
percent_for_tp=305 order_deviation=100 ma_red_period=13
percent_for_sl=69 stochastic_k=3 ma_red_shift=5
trailing_sl=250 stochastic_d=4 ma_blue_period=1
trailing_profit=20 stochastic_slowing=4 ma_blue_shift=5



Abb. 10. Testergebnisse AUDUSD H4 (2017.01.01 - 2017.11.12)

Die Analyse der erhaltenen Ergebnisse zeigt einige Instabilität bei den Positionseröffnungen. Alle Symbole außer USHCHF zeigen eine fast gerade Horizontale.

Der Grund dafür ist folgender: Um Verluste zu minimieren, setzt die Strategie voraus, dass der Stop-Loss so nah wie möglich platziert wird. Aber dadurch werden die Anforderungen an die Signalqualität erhöht. Je höher aber die Signalqualität ist, desto weniger Positionen werden eröffnet, wenngleich dadurch die Saldenkurve stabiler (z.B. beim USDCHF) wird. In der Praxis wollen wir jedoch den Gewinn maximieren. Wir sollten sicherstellen, dass der Expert Advisor Verluste in schwierigen Marktsituationen klein halten kann.

Daher sollten die Optimierung und die Tests auf Ergebnisse mit einer großen Anzahl von Positionen beruhen, die über einen langen Zeitraum erzielt werden.

Symbol: XAUUSD

Nach dem Expert Advisor mit allen gängigen Währungspaare getestet wurde, wäre es schön, herauszufinden, wie er sich im Rohstoff-Markt verhält. Deshalb ist hier der Test mit XAUUSD (einem Future für Gold in USD):

Parameter:

percent_min_enter=23.6 magic_number=65758473787389 stochastic_up_level=90
percent_max_enter=50 order_volume=0.2 stochastic_down_level=10
percent_for_tp=255 order_deviation=100 ma_red_period=23
percent_for_sl=80 stochastic_k=3 ma_red_shift=5
trailing_sl=750 stochastic_d=1 ma_blue_period=6
trailing_profit=10 stochastic_slowing=1 ma_blue_shift=5




Abb. 11. Testergebnisse XAUUSD H4 (2017.01.01 - 2017.11.12)

Das Ergebnis mit Gold ist interessant: 83,3% der Positionen sind profitabel, und der Gewinn steigt um 461%, bei einem Drawdown von weit weniger als 40%. Das heißt, der Gewinn ist mehr als 10 Mal größer als der Drawdown. Ein ziemlich interessanter Erfolgswert, aber aufgrund der geringen Anzahl von Transaktionen (es gibt nur 18 Positionen), können wir keine ernsthaften Schlussfolgerungen auf der Grundlage dieses Tests ziehen.


Nachteile dieser Handelsstrategie

So wie jeder andere hat auch dieser Expert Advisor seine Nachteile.

Abb. 12. Der Expert Advisor bei einem Trend (NZDUSD H4)

Abb. 12. Der Expert Advisor bei einem Trend (NZDUSD H4)

Abb. 12 zeigt, wie sich der Expert Advisor in einem Preiskanal verhält. Es schaut sehr stabil aus, aber mit einem großen, offensichtlichen Nachteil: Die Positionen werden zu früh geschlossen.

Abb. 13. Expert Advisor in einer Seitwärtsbewegung (EURUSD H4)

Abb. 13. Expert Advisor in einer Seitwärtsbewegung (EURUSD H4)

Eine andere "Problemzone": In Seitwärtsbewegungen arbeitet der Expert Advisor nicht gerade ideal. Abb. 13 zeigt, dass bei solchen Preisbewegungen der Gewinn nicht groß ist; und die Eröffnungspreise sind auch nicht immer ideal.

Ergebnistabelle

SymbolPositionenprofitable Positionen (%)Nettogewinn, $ Max. Salden-Drawdown in %Expected Payoff, $PFRFSharpe
AUDUSD4116 (39.0%)49.9411.81.222.262.800.19
EURUSD5228 (53.8%)124.7917.72.402.234.010.28
GBPUSD4017 (42.5%)126.3919.03.164.845.020.24
NZDUSD13151 (38.9%)111.6311.90.852.255.290.26
USDCAD23145 (19.4%)85.7128.70.371.921.930.12
USDCHF1714 (82.3%)77.114.34.547.167.240.94
USDJPY21045 (21.4%)50.8852.30.241.350.960.07
XAUUSD1815 (83.3%)461.995.1
25.679.009.880.47

Die Tabelle zeigt unterschiedliche Ergebnisse, obgleich gemeinsame Tendenzen unterschiedlicher Paare erkennbar sind. Mit dem gleichen Einstellungen sind manche Paare profitabel (wenn auch nur moderat). Fazit: Um den Gewinn zu steigern, müssen die Einstellungen des Beraters für jedes Währungspaar sorgfältig optimiert werden. 

Schlussfolgerung

Wir sind wieder einmal davon überzeugt, dass die "alte Schule" der Händler für lange Zeit ein starkes Fundament geschaffen hat. Die Handelsstrategie mit den DiNapoli-Ebene hat sich als sehr aussichtsreich erwiesen, und es ist geplant diese weiterzuentwickeln. Aktuell gibt noch Probleme, in Seitwärtsbewegungen ist sie z.B. ziemlich schlecht. Außerdem erreicht der Preis nicht immer die COP-Linie; und meistens werden Positionen im Endeffekt durch ein Signal der Stochastik geschlossen.

Die Vorteile des entwickelten Expert Advisors schließen ziemlich aggressive Positionseröffnungen ein, insbesondere in Abb. 13. Der Expert Advisor folgt genau dem Algorithmus auch in jenen Situationen, in denen der Händler höchstwahrscheinlich die Position manuell nicht geöffnet hätte. Aber im Ganzen wird ein Gewinn erzielt, und das bei einem unbedeutendem Drawdown.

Angehängte Dateien

# Name Typ Beschreibung
1 Dinapoli_v1.01.mq5 Expert Advisor Expert Advisor mit der Strategie der DiNapoli-Ebenen und Hilfsindikatoren
2 AUDUSDH4.set Datei mit den Einstellungen des Expert Advisor Einstellungen für Tests und Optimierung für das Symbol AUDUSD Н4
3 EURUSDH4.set Datei mit den Einstellungen des Expert Advisor Einstellungen für Tests und Optimierung für das Symbol EURUSD H4
4 GBPUSDH4.set Datei mit den Einstellungen des Expert Advisor Einstellungen für Tests und Optimierung für das Symbol GBPUSD H4
5 NZDUSDH4.set Datei mit den Einstellungen des Expert Advisor Einstellungen für Tests und Optimierung für das Symbol NZDUSD H4
6 USDCADH4.set Datei mit den Einstellungen des Expert Advisor Einstellungen für Tests und Optimierung für das Symbol USDCAD H4
7 USDCHFH4.set Datei mit den Einstellungen des Expert Advisor Einstellungen für Tests und Optimierung für das Symbol USDCHF H4
8 USDJPYH4.set Datei mit den Einstellungen des Expert Advisor Einstellungen für Tests und Optimierung für das Symbol USDJPY H4
9 XAUUSDH4.set Datei mit den Einstellungen des Expert Advisor Einstellungen für Tests und Optimierung für das Symbol XAUUSD H4