Schau, wie man Roboter kostenlos herunterladen kann
Finden Sie uns auf Facebook!
und werden Sie Mitglied unserer Fangruppe
Interessantes Skript?
Veröffentliche einen Link auf das Skript, damit die anderen ihn auch nutzen können
Hat Ihnen das Skript gefallen?
Bewerten Sie es im Terminal MetaTrader 5
Ansichten:
2860
Rating:
(53)
Veröffentlicht:
2016.05.18 16:03
Aktualisiert:
2018.06.04 17:56
Benötigen Sie einen Roboter oder Indikator, der auf diesem Code basiert? Bestellen Sie ihn im Freelance-Bereich Zum Freelance

Der Gleitende Durchschnitt EA ist im Standardpaket vom MetaTrader 5 Clientterminal enthalten und ist ein Beispiel für einen EA der unter Verwendung des gleitenden Durchschnitts handelt.

Datei Datei Moving Average.mq5 befindet sich im Ordner "terminal_data_folder\MQL5\Experts\Examples\Moving Average\". Dieser EA ist ein Beispiel für die Verwendung von technischen Indikatoren, Tradehistorie Funnktionen und Trading Klassen der Standard Bibliothek. Außerdem enthält der EA ein Money-Management-System, das auf Handelsergebnissen basiert.

Sehen wir uns die Struktur es Expert Advisors und wie er funktioniert an.

1. EA Eigenschaften

//+------------------------------------------------------------------+
//|                                              Moving Averages.mq5 |
//|                   Copyright 2009-2013, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2009-2013, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00

Die ersten 5 Zeilen enthalten einen Kommentar, die folgenden drei Zeilen stellen die Eigenschaften des MQL5-Programms (Copyright, Link, Version) mit Hilfe der Präprozessor Direktiven #property ein.

Wenn Sie den Expert Advisor ausführen, werden diese im "Allgemein" Tab angezeigt:


Abbildung 1. Allgemeine Parameter des Gleitender Durchschnitt EA


1.2. Include Files

Als nächstes kommen die #include Direktiven, die dem Compiler mitteilen, dass er die "Trade.mqh" Datei einbinden soll.

Diese Datei ist Teil der Standard Bibliothek, sie enthält die CTrade Klasse für den einfachen Zugriff auf Trading-Funktionen.

#include <Trade\Trade.mqh>

Der Name der Include-Datei wird in spitzen Klammern "<>;" angezeigt, daher ist der Pfad relativ zum Verzeichnis: "terminal_data_folder\Include\".

1.3 Eingaben

Dann kommt der Typ, Name, Standardwert und ein Kommentar. Ihre Rolle wird in Abb. 2 gezeigt.

input double MaximumRisk        = 0.02;    // Maximales Risiko in Prozent
input double DecreaseFactor     = 3;       //Verminderungsfaktor
input int    MovingPeriod       = 12;      // Periode des gleitenden Durchschnitts
input int    MovingShift        = 6;       //Verschiebung des gleitenden Durchschnitts

Die Parameter MaximumRisk und DecreaseFactor werden für das Moneymanagement verwendet, MovingPeriod und MovingShift stellen die Periode und die Verschiebung des technischen Indikators gleitender Durchschnitt ein, der für die Prüfung auf Handelsbedingungen verwendet wird.

Der Text im Kommentar der Eingabeparameterzeile wird gemeinsam mit Standardwerten im "Optionen"-Tab anstatt des Namens des Eingabeparameters angezeigt:


Abb. 2. Eingabeparameters des Gleitender Durchschnitt EA

1.4. Globale Variablen

Dann wird die globale Variable ExtHandle deklariert. Sie wird für die Speicherung des Handles des gleitender Durchschnitt Indikator verwendet.

//---
int   ExtHandle=0;

Es folgen 6 Funktionen. Der Zweck jeder dieser Funktionen wird im Kommentar vor dem Funktionskörper beschrieben:

  1. TradeSizeOptimized() - Berechne optimale Lotgröße;
  2. CheckForOpen() - Prüfe auf Bedingung zum Öffnen von Positionen;
  3. CheckForClose() - Prüfe auf Bedingung zum Schließen von Positionen;
  4. OnInit() - Experten-Initialisierungsfunktion;
  5. OnTick() - Experten Tickfunktion;
  6. OnDeinit() - Expert Deinitialisierungsfunktion;

Die letzten drei Funktionen sind Ereignishandling Funktionen; die erstern drei Servicefunktionen werden in deren Code aufgerufen.


2. Ereignishandling Funktionen

2.1. Die OnInit() Initialisierungsfunktion

Die OnInit() Funktion wird einmal während des ersten Starts des Expert Advisors aufgerufen. Für gewöhnlich wird der EA im OnInit() Ereignishandler für die Benützung vorbereitet: Eingabeparameter werden geprüft, Indikatoren und Parameter werden initialisiert, etc. Im Falle von kritischen Fehlern bei denen eine weitere Verarbeitung keinen Sinn hat, wird die Funktion mmit dem Rückgabecode INIT_FAILED verlassen.

//+------------------------------------------------------------------+
//| Experteninitialisierungfunktion                                  |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//---
   ExtHandle=iMA(_Symbol,_Period,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE);
   if(ExtHandle==INVALID_HANDLE)
     {
      printf("Fehler beim Erstellen des MA Indikators");
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }

Da das Trading des EA auf dem Indikator Gleitender Durchschnitt beruht, wird durch Aufruf von iMA() der Gleitende Durchschnitt Indikator erstellt und sein Handle wird in der globalen Variablen ExtHandle gespeichert.

Im Falle eines Fehlers wird OnInit() mit dem Rückgabecode INIT_FAILED verlassen - das ist eine korrekte Art die Verarbeitung des EA/Indikators im Falle einer nicht erfolgreichen Initialisierung zu beenden.


2.2. Die OnTick() Funktion

Die OnTick() Funktion wird jedes Mal aufgerufen, wenn eine neue Quotierung für das Symbol am Chart für das der EA ausgeführt wird, erhalten wird.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(void)
  {
//---
   if(PositionSelect(_Symbol))
      CheckForClose();
   else
      CheckForOpen();
//---
  }

Die PositionSelect() Funktion wird verwendet, um zu definieren, ob es eine offene Position für das aktuelle Symbol gibt.

Wenn es offene Positionen gibt, wird die CheckForClose() Funktion aufgerufen, die den aktuellen Marktstatus analysiert und offene Positionen schließt, ansonsten wird CheckForOpen() aufgerufen, das die Marktbedingungen eines Markteinstieges prüft und eine neue Position öffnet, wenn eine solche Bedingung zutrifft.


2.3. Die OnDeInit() Deinitialisierungsfunktion

OnDeInit() wird aufgerufen, wenn der EA vom Chart entfernt wird. Wenn ein Programm im Zuge seiner Arbeit graphische Objekte platziert, können diese vom Chart entfernt werden.

//+------------------------------------------------------------------+
//| Expertendeinitialisierungsfunktion                               |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }
//+------------------------------------------------------------------+

In diesem Fall werden keine Schritte während der Expert Advisor Deinitialisierung ausgeführt.


3. Servicefunktionen

3.1. Funktion TradeSizeOptimized()

Diese Funktion berechnet und gibt den Wert der optimalen Lotgröße für die Eröffnung einer Position mit dem spezifizierten Risikolevel und Handelsergebnissen zurück.

//+------------------------------------------------------------------+
//| Berechne optimale Lotgröße                                      |
//+------------------------------------------------------------------+
double TradeSizeOptimized(void)
  {
   double price=0.0;
   double margin=0.0;
//--- Berechne die Lotgröße
   if(!SymbolInfoDouble(_Symbol,SYMBOL_ASK,price))
      return(0.0);
   if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin))
      return(0.0);
   if(margin<=0.0)
      return(0.0);

   double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_FREEMARGIN)*MaximumRisk/margin,2);
//--- Berechne die Länge der Serie von aufeinander folgenden Verlusttrades
   if(DecreaseFactor>0)
     {
      //--- fordere die gesamte Handelshistorie an
      HistorySelect(0,TimeCurrent());
      //--
      int    orders=HistoryDealsTotal();  // Gesamtanzahl der Trades
      int    losses=0;                    // Anzahl der Verluste in Folge

      for(int i=orders-1;i>=0;i--)
        {
         ulong ticket=HistoryDealGetTicket(i);
         if(ticket==0)
           {
            Print("HistoryDealGetTicket fehlgeschlagen, keine Handelshistorie");
            break;
           }
         //--- Prüfung des Handelssymbols
         if(HistoryDealGetString(ticket,DEAL_SYMBOL)!=_Symbol)
            continue;
         //--- Prüfung des Profits
         double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
         if(profit>0.0)
            break;
         if(profit<0.0)
            losses++;
        }
      //---
      if(losses>1)
         lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
     }
//--- Normalisierung und Prüung der erlaubten Werte des Handelsvolumens
   double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lot=stepvol*NormalizeDouble(lot/stepvol,0);

   double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
   if(lot<minvol)
      lot=minvol;

   double maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
   if(lot>maxvol)
      lot=maxvol;
//--- gibt den Wert des Handelsvolumens zurück
   return(lot);
  }


Die SymbolInfoDouble() Funktion wird für die Überprüfung der Verfügbarkeit des Preises für das aktuelle Symbol verwendet, anschließend wird die OrderCalcMargin() Funktion verwendet, um den notwendigen Margin zu ermitteln, der für die Platzierung dieser Order erforderlich ist (in diesem Fall eine Kauforder). Die initiale Lotgröße wird durch dem Wert des für die Platzierung einer Order notwendigen Margins bestimmt, vom freien Margin des Kontos (AccountInfoDouble(ACCOUNT_FREEMARGIN)) und vom maximal zulässigen Wert des Risikos, der im Eingabeparameter MaximumRisk spezifiziert wurde.

Wenn der Wert des Eingabeparameters DecreaseFactor positiv ist, werden dei Trades in der Historie analysiert und die Lotgröße wird unter Berücksichtigung der Information über die maximale Serie von Verlusttrades angepasst: die initiale Lotgröße wird mit der Größe multipliziert (1-Verluste/DecreaseFactor).

Dann wird das Handelsvolumen auf den Wert "gerundet", der ein Vielfaches der minimal erlaubten Volumenschrittgröße (stepvol) für das aktuelle Symbol beträgt. Es werden auch das Minimum (minvol) und das Maximum (maxvol) der möglichen Werte für das Tradevolumen benötigt und wenn der Wert der Lotgröße die erlaubten Limits übersteigt, wird er angepasst. Die Funktion gibt als Ergebnis den berechneten Wert des Tradingvolumens zurück.


3.2. Funktion CheckForOpen()

CheckForOpen() wird verwendet, um zu prüfen, ob Voraussetzungen für das Öffnen einer Position erfüllt sind und öffnet einen Trade, wenn dies zutrifft (in diesem Fall wenn der Preis den gleitenden Durchschnitt kreuzt).

//+------------------------------------------------------------------+
//| Prüfe Voraussetzungen für Öffnen einer Positon                   |
//+------------------------------------------------------------------+
void CheckForOpen(void)
  {
   MqlRates rt[2];
//--- kopiere die Preiswerte
   if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
     {
      Print("CopyRates von ",_Symbol," fehlgeschlagen, keine Historie");
      return;
     }
//--- Handle nur beim ersten Tick eines neuen Balkens
   if(rt[1].tick_volume>1)
      return;
//--- Bestimme den aktuellen Wert des Gleitender Durchschnitt Indikator 
   double   ma[1];
   if(CopyBuffer(ExtHandle,0,0,1,ma)!=1)
     {
      Print("CopyBuffer von iMA fehlgeschlagen, keine Daten");
      return;
     }
//--- Signale prüfen
   ENUM_ORDER_TYPE signal=WRONG_VALUE;

   if(rt[0].open>ma[0] && rt[0].close<ma[0])
      signal=ORDER_TYPE_SELL;    // Verkaufsbedingung
   else
     {
      if(rt[0].open<ma[0] && rt[0].close>ma[0])
         signal=ORDER_TYPE_BUY;  // Kaufbedingung
     }
//--- Zusätzliche Prüfungen
   if(signal!=WRONG_VALUE)
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
         if(Bars(_Symbol,_Period)>100)
           {
            CTrade trade;
            trade.PositionOpen(_Symbol,signal,TradeSizeOptimized(),
                               SymbolInfoDouble(_Symbol,signal==ORDER_TYPE_SELL ? SYMBOL_BID:SYMBOL_ASK),
                               0,0);
           }
//---
  }

Beim Handel mit dem MA müssen Sie prüfen, ob der Preis den gleitenden Durchschnitt kreuzt. Mit Hilfe der CopyRates() Funktion werden zwei Werte des aktuellen Preises in das Array der Struktur rt[] kopiert, rt[1] korrespondiert mit dem aktuellen Balken, rt[0] - dem abgeschlossenen Balken.

Ein neuer Balken wird angefangen, indem das Tickvolumen des aktuellen Balkens geprüft wird - wenn es 1 ist, dann wird ein neuer Balken angefangen. Es sollte beachtet werden, dass diese Methode der Erkennung eines neuen Balkens in einigen Fällen fehlschlagen kann (wenn Quotierungen in Blöcken kommen), daher sollte ein neuer Balken durch Speicherung und Vergleich der Uhrzeit der aktuellen Quotierung erkannt werden (siehe IsNewBar).

Der aktuelle Wert des Gleitender Durchschnitt Indikator wird durch die CopyBuffer() Funktion angefordert und wird im ma[] Array gespeichert, der nur einen Wert enthält. Das Programm prüft dann, ob der Preis den gleitenden Durchschnitt gekreuzt hat und führt weitere Prüfungen druch (wenn das Trading durch den EA möglich ist und Balken in der Historie vorliegen). Bei Erfolg wird eine entsprechende Position für das Symbol eröffnet, indem die PositionOpen() Methode des Trade Objektes (eine Instanz von CTrade) aufgerufen wird.

Der Eröffnungspreis der Position wird durch Anwendung der SymbolInfoDouble() Funktion gesetzt, die den Bid oder Ask Preis abhängig vom Wert der Signalvariablen zurück gibt. Das Positionsvolumen wird durch Aufruf von TradeSizeOptimized() wie oben beschrieben festgelegt.


3.3. Funktion CheckForClose()

CheckForClose() prüft die Bedingungen für das Schließen einer Position und schließt sie, wenn die Bedingungen für das Schließen eintreten.

//+------------------------------------------------------------------+
//| Prüfung auf Bedingung für das Schließen einer Position         |
//+------------------------------------------------------------------+
void CheckForClose(void)
  {
   MqlRates rt[2];
//--- Kopiere Preise
   if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
     {
      Print("CopyRates von ",_Symbol," fehlgeschlagen, keine Historie");
      return;
     }
//--- Trade nur beim ersten Tick eines neuen Balken
   if(rt[1].tick_volume>1)
      return;
//--- hole den aktuellen Wert des gleitenden Durchschnitt Indikator
   double   ma[1];
   if(CopyBuffer(ExtHandle,0,0,1,ma)!=1)
     {
      Print("CopyBuffer von iMA fehlgeschlagen, keine Daten");
      return;
     }
//--- hole den Typ der Position der zuvor von PositionSelect() ausgewählt wurde
   bool signal=false;
   long type=PositionGetInteger(POSITION_TYPE);

   if(type==(long)POSITION_TYPE_BUY   && rt[0].open>ma[0] && rt[0].close<ma[0])
      signal=true;
   if(type==(long)POSITION_TYPE_SELL  && rt[0].open<ma[0] && rt[0].close>ma[0])
      signal=true;
//--- Zusätzliche Prüfungen
   if(signal)
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
         if(Bars(_Symbol,_Period)>100)
           {
            CTrade trade;
            trade.PositionClose(_Symbol,3);
           }
//---
  }

Der Algorithmus der CheckForClose() Funktion ist ähnlich dem Algorithmus von CheckForOpen(). Abhängig von der Richtung der aktuell offenen Positionen werden die Bedingungen für ihre Schließung geprüft (Preis kreuzt den gleitenden Durchschnitt abwärts um zu kaufen oder aufwärts um zu verkaufen). Eine offene Position wird geschlossen, indem die PositionClose() Methode des Tradeobjektes (Instanz von CTrade) aufgerufen wird.


4. Backtesting

Die besten Werte für die Parameter können durch Verwendung des Strategie Testers des MetaTrader 5 Terminals gefunden werden.

Wenn zum Beispiel der Parameter MovingPeriod im Intervall von 2012.01.01-2013.08.01 optimiert wird, wird das beste Ergebnis durch MovingPeriod=45 erzielt:

Backtesting Ergebnisse des Gleitender Durchschnitt Expert Advisor

Backtesting Ergebnisse des Gleitender Durchschnitt Expert Advisor

Schlussfolgerungen:

Der Gleitende Durchschnitt Expert Advisor der im Standard des MetaTrader 5 Terminal enthalten ist, ist ein Beispiel für die Verwendung von technischen Indikatoren, Tradinghistorie Funktionen und Trade Klassen der Standardbibliothek. Außerdem enthält der EA ein Money-Management-System, das auf Handelsergebnissen basiert.


Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalpublikation: https://www.mql5.com/ru/code/1921

Ergodic_Ticks_Volume_Indicator Ergodic_Ticks_Volume_Indicator

Einer der Indikatoren des Tickvolumens mit mehreren EMAs von William Blau.

Ticks_Volume_Indicator Ticks_Volume_Indicator

Ein Indikator, der das Tickvolumen für seine Berechnungen verwendet.

BlauCMI BlauCMI

Ergodischer CMI Oszillator als Farbhistogramm.

Math-System Math-System

Eine Menge von Zielunterstützungs-/widerstandslevels für die vorhergesagte Preisbewegung.