English 日本語
preview
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 17): Handel mit mehreren Währungen

MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 17): Handel mit mehreren Währungen

MetaTrader 5Beispiele | 7 Juni 2024, 09:39
124 0
Stephen Njuki
Stephen Njuki

Vorwort

Dieser Artikel setzt die Serie darüber fort, wie der MQL5-Assistent ideal für das schnelle Testen und Prototyping von Ideen für Händler ist. Für viele, die Expertenberater und Handelssysteme entwickeln, ist es wichtig, sich ständig weiterzubilden und mit den Trends nicht nur im Bereich des maschinellen Lernens, sondern auch im Bereich des Handels und des Risikomanagements im Allgemeinen Schritt zu halten. Deshalb betrachten wir in dieser Serie, wie die MQL5-IDE in dieser Hinsicht nützlich ist, indem sie nicht nur Zeit spart, sondern auch Codierungsfehler minimiert.

Eigentlich wollte ich mich in diesem Beitrag mit der Neural Architecture Search (NAS) befassen, aber mir wurde klar, dass es einige grundlegende Prinzipien gibt, die ich noch nicht behandelt habe und die es wert sind, in Betracht gezogen zu werden, vor allem der Handel mit mehreren Wertpapieren in einem von einem Assistenten zusammengestellten Expert Advisor. Daher werden wir uns in diesem Artikel nicht mit neuen Handels-Setups befassen, sondern einige der Grundlagen betrachten. NAS werden im nächsten Artikel behandelt.


Einführung

Der Handel mit mehreren Währungen verringert im Gegensatz zum Handel mit einer einzigen Währung die Risikokonzentration. Da jedes Konto eine bestimmte Hebelwirkung und damit einen bestimmten Betrag an freier Marge hat, muss der Betrag der freien Marge auf alle verfügbaren Währungen aufgeteilt werden, wenn Sie mit mehr als einem Symbol handeln müssen. Wenn diese Währungen keine Korrelation aufweisen oder umgekehrt korreliert sind, kann das Risiko einer übermäßigen Abhängigkeit von nur einer dieser Währungen stark gemildert werden.

Wenn ein Handelssystem, bei dem die Eröffnung von Positionen in mehreren Währungen nicht wie erwähnt parallel erfolgt, um das Risiko zu minimieren, sondern sequentiell, d. h. jedes Währungspaar wird zu einem bestimmten Zeitpunkt betrachtet, können zudem marktübergreifende Chancen genutzt werden. Dies würde bedeuten, dass man Folge- oder Anschlusspositionen eröffnet, deren Währungspaare umgekehrt zu den bereits eröffneten Positionen korrelieren, wenn die eröffneten Positionen nach unten ziehen, oder das Gegenteil tun, wenn die bereits eröffneten Positionen einen Float haben. Die Paarung von Währungen als Marge oder Gewinn in einem beliebigen Paar macht diesen Prozess besonders interessant, wenn man neben der reinen Betrachtung von Korrelationen eine marktübergreifende Gelegenheit auswählt.

Die Gewinnspanne für jedes Währungspaar stellt auch einen Vorteil des Handels mit mehreren Währungen dar, nämlich das Hedging. Das Hedging mit mehreren Währungspaaren auf der Grundlage ihrer Margen- oder Gewinnwährungen kann mit schwebenden Aufträgen durchgeführt werden, insbesondere in Situationen, in denen ein Händler seine Positionen über wichtige Nachrichtenereignisse oder sogar über das Wochenende halten möchte, und grenzt damit an Arbitrage - eine Praxis, die nicht nur bei den meisten Brokern verpönt, sondern auch in der Praxis sehr schwierig umzusetzen ist.

Mehr noch als diese Strategien ermöglicht es der Handel mit mehreren Währungen dem Händler oder dem Expertenberater, währungsspezifische Trends in vielen der handelbaren Paare in der Marktübersicht zu beobachten und zu nutzen. Wenn zum Beispiel eine bestimmte Währung günstige Zinsen abwirft, können Sie im Rahmen von unentdeckter Zinsarbitrage eine Reihe von Paaren mit einem höheren Kurs kaufen und halten und so nicht nur an Kursänderungen, sondern auch an den Zinsen verdienen. Die Fähigkeit, eine Analyse für mehrere Währungspaare durchzuführen und die zu handeln, die diese währungsübergreifenden Setups ausnutzen, ist nur möglich, wenn der Expert Advisor für den Handel mit mehreren Währungen ausgelegt ist, wozu die von uns untersuchten Expert Advisors nicht in der Lage sind.

In diesem Artikel werden wir uns also mit der Erstellung von Vorlagen befassen, die die im MQL5-Assistenten verwendeten Klassen ändern, um einen Expert Advisor in weitgehend 2 Szenarien zusammenzustellen. Erstens werden wir einen Assistenten einsetzen, der Experten zusammenstellt, die einfach parallele Positionen für mehrere Währungspaare analysieren und eröffnen, um das Risiko zu minimieren. Dieser Ansatz erfordert wahrscheinlich die meisten Anpassungen, da wir eine wichtige Datei in der Assistentenbaugruppe ändern werden. Der zweite Ansatz schließlich sieht vor, dass die von Assistenten zusammengestellten Experten die relativen Korrelationen der Währungspaare berücksichtigen und auf der Grundlage unabhängiger Analysen nacheinander Positionen eröffnen können.


Vorlage für den MQL5-Assistenten (Option-1):

Die mit dem Assistenten zusammengestellten Expert Advisors haben 3 Hauptankerklassen, die jeweils in einer separaten Datei enthalten sind. Diese sind „ExpertBase“, „ExpertTrade“ und „Expert“. Neben diesen drei Ankerklassen gibt es noch drei weitere Hilfsklassen, nämlich „ExpertSignal“, „ExpertMoney“ und „ExpertTrailling“, die jeweils geerbt werden, wenn die Signal-, Money-Management- oder Trailing-Klassen eines Experten erstellt werden. In all diesen Klassen ist es die Klasse „ExpertBase“, die das Objekt der Symbolklasse definiert, das standardmäßig für den Zugriff auf Marktinformationen des gehandelten Symbols verwendet wird („m_symbol“). Wie bereits erwähnt, handeln die Expert Advisors aller Assistenten standardmäßig nur mit einem Symbol, sodass die in „ExpertBase“ initialisierte Symbolklasse nur für ein Symbol vorgesehen ist.

Um dies mit mehreren Symbolen zu versehen, könnte eine mögliche Lösung darin bestehen, diese Klasseninstanz in ein Array umzuwandeln. Dies ist zwar möglich, aber die Klassen, die auf diese Symbolklasseninstanz zugreifen, verwenden dazu viele Funktionen, und diese Verbindung erwartet immer ein „none“-Array, was bedeutet, dass eine Menge nicht praktikabler Änderungen am Code vorgenommen werden müssten. Dies ist also keine gute Lösung, um den Assistenten, der von Experten zusammengestellt wurde, mehrwährungsfähig zu machen.

Ein praktikablerer und ähnlicher Ansatz, den wir in Betracht ziehen werden, besteht darin, die Instanz der Oberklasse „Expert“ zu einem Array zu machen, dessen Größe der Anzahl der Handelssymbole entspricht, die wir testen wollen. Eine Instanz dieser Klasse wird immer in der „*.mq5“-Datei des vom Assistenten zusammengestellten Expertenberaters deklariert, und die einfache Umwandlung in ein Array markiert im Wesentlichen alle wichtigen nachgelagerten Anpassungen, die wir vornehmen müssen.

//+------------------------------------------------------------------+
//| Global expert object                                             |
//+------------------------------------------------------------------+
CExpert ExtExpert[__FOLIO];
CExpertSignal *signals[__FOLIO];

Um die Instanz der Expertenklasse in ein Array umzuwandeln, müssen wir ein Array der zu handelnden Währungspaare vordefiniert haben. Dies geschieht in dem unten stehenden Code:

//+------------------------------------------------------------------+
//| 'Commodity' Currency folio                                       |
//+------------------------------------------------------------------+
#define                          __FOLIO 9
string                           __F[__FOLIO] 

                                 = 
         
                                 {
                                 "AUDNZD","AUDUSD","AUDCAD","AUDJPY",
                                 "NZDUSD","NZDCAD","NZDJPY",
                                 "USDCAD",
                                 "CADJPY"
                                 };
input string                     __prefix="";
input string                     __suffix="";


Der obige Code wird in eine angepasste Version der Klasse Expert geändert. Da wir diese Klasse ändern, müssen wir anschließend eine Instanz davon unter einem neuen Namen speichern, um die Standardeinstellungen für typische Baugruppen beizubehalten. Der Name, den wir verwenden, ist „ExpertFolio.mqh“, ausgehend von dem ursprünglichen Namen „Expert.mqh“. Neben der Namensänderung und dem geänderten Code in der Kopfzeile müssen wir auch das Listing der Funktion „Init“ ändern, um besser auf Symbole reagieren zu können, die nicht mit dem Symbol des Diagramms übereinstimmen, an das der Experte angehängt ist. Dies geschieht in dem unten stehenden Code:

//+------------------------------------------------------------------+
//| Initialization and checking for input parameters                 |
//+------------------------------------------------------------------+
bool CExpert::Init(string symbol,ENUM_TIMEFRAMES period,bool every_tick,ulong magic)
  {
//--- returns false if the EA is initialized on a timeframe different from the current one
   if(period!=::Period())
     {
      PrintFormat(__FUNCTION__+": wrong timeframe (must be: %s)",EnumToString(period));
      return(false);
     }
     
   if(m_on_timer_process && !EventSetTimer(PeriodSeconds(period)))
      {
      PrintFormat(__FUNCTION__+": cannot set timer at: ",EnumToString(period));
      return(false);
      }
//--- initialize common information
   if(m_symbol==NULL)
     {
      if((m_symbol=new CSymbolInfo)==NULL)
         return(false);
     }
   if(!m_symbol.Name(symbol))
      return(false);
   
....
....


//--- ok
   return(true);
  }

Die oben genannten Änderungen können an einer Kopie der Expert-Klassendatei vorgenommen werden, die wir dann wie oben angegeben umbenennen, oder wir können eine neue Klasse erstellen, die von der Expert-Klasse in „Expert.mqh“ abgeleitet wird, und dann eine „überschreibende“ „Init“-Funktion in dieser neuen Klasse hinzufügen. Auf diese neue Klasse und Datei wird in der Haupt-Experten-Datei verwiesen. Nachfolgend finden Sie eine Auflistung davon:

#include "Expert.mqh"
//+------------------------------------------------------------------+
//| Class CExfolio.                                                  |
//| Purpose: Base class expert advisor.                              |
//| Derives from class CExpertBase.                                  |
//+------------------------------------------------------------------+
class CExfolio : public CExpert
  {
protected:

   
public:

                     CExfolio(void);
                    ~CExfolio(void);
                    
   //--- initialization
   virtual bool      Init(string symbol,ENUM_TIMEFRAMES period,bool every_tick,ulong magic=0) override;
   
   //...

  };

Wie aus dem obigen Code ersichtlich ist, wurde der Befehl „override“ am Ende der Schnittstellendeklaration hinzugefügt. Da die Funktion „Init“ jedoch nicht standardmäßig „virtuell“ ist, muss die Funktion „Init“ in der ursprünglichen Expertenklasse geändert werden, indem dieser Befehl hinzugefügt wird. Diese Zeilen würde also nur so aussehen:

//+------------------------------------------------------------------+
//| Initialization and checking for input parameters                 |
//+------------------------------------------------------------------+
bool CExfolio::Init(string symbol,ENUM_TIMEFRAMES period,bool every_tick,ulong magic)
  {
//--- returns false if the EA is initialized on a symbol/timeframe different from the current one
      
      bool _init=true;
      
      if(!CExpert::Init(symbol,period,every_tick,magic))
      {
         _init=false;
         //
         if(symbol!=_Symbol)
         {
            if(Reinit(symbol,period,every_tick,magic)){ _init=true; }
         }
      }
      
      CExpert::OnTimerProcess(true);
      
      if(CExpert::m_on_timer_process && !EventSetTimer(PeriodSeconds(_Period)))
      {
         printf(__FUNCTION__+": cannot set timer at: ",EnumToString(period));
         _init=false;
      }
      
//--- ok
      return(_init);
  }

Die wichtigsten Änderungen hier stellen sicher, dass die Initialisierung nicht fehlschlägt, wenn das Symbol des Charts nicht mit dem des Portfolios übereinstimmt. Dies wäre sicherlich eine „sauberere“ Option, da unsere erstellte Klassendatei wesentlich kleiner ist, was bedeutet, dass wir weniger Duplikate haben als im ersten Fall. Allerdings müssten wir die eingebaute Expertendatei ändern, was bedeutet, dass wir bei jeder Aktualisierung des Terminals den Spezifizierer für die virtuelle Funktion zur init-Funktion hinzufügen müssten.

Neben diesen Änderungen an der Expertenklasse müssten in der vom Assistenten generierten Expert Advisor-Datei auch die Funktionen OnInit, OnTick, OnTimer, OnDeInit und Trade geändert werden. Es wird eine for-Schleife hinzugefügt, die alle in der nutzerdefinierten Expertenklasse vordeklarierten Währungen durchläuft. Ihre Deklaration wird von Präfix- und Suffix-String-Eingabeparametern begleitet, die sicherstellen, dass ihre Namen wohlgeformt und in der Marktübersicht enthalten sind. Anstatt die Symbole explizit zu benennen und für vorangestellte/nachgestellte Namen zu sorgen, wird die richtige Vorgehensweise beim Zugriff auf verfügbare Symbole hervorgehoben hier. Aber selbst dann müssten Sie eine vordefinierte Liste der Symbole haben, an denen Sie interessiert sind, um die oft sehr lange Liste der Symbole, die in Market Watch verfügbar sind, richtig zu filtern.

Bei den in der nutzerdefinierten Expertenklasse ausgewählten Symbolen handelt es sich um das, was vor allem in der vergangenen Ära des Kalten Krieges als „Rohstoffe“ bezeichnet wurde, da ihre Dynamik zu stark vom Preis der Rohstoffe beeinflusst wurde. In unserer Liste werden also die Währungen AUD, NZD und CAD als wichtigste Rohstoffe verwendet. Die Hinzufügung von USD und JPY dient dem Volatilitätsrisiko, aber sie gehörten nicht zur Gruppe der „Rohstoffe“.

Die Signalklasse, die für den Expertenberater im Assistenten verwendet wird, kann eine der eingebauten Klassen sein. Der Grund dafür ist, dass bei der ersten Implementierung die Symbole parallel ausgeführt werden, um das Risiko zu minimieren. Die Handelsentscheidungen für ein beliebiges Symbol werden nicht von den Ereignissen bei einem anderen Symbol beeinflusst, sodass die Einstellungen für das ausgewählte Signal auf alle Symbole angewendet werden. Aus dem Testen folgt, dass unsere Testläufe bessere Chancen haben, bei Forward Walks oder Kreuzvalidierung gut abzuschneiden, da verschiedene Symbole dieselben Einstellungen haben und es daher weniger Kurvenanpassungen gibt. Wir verwenden die Signalklasse RSI, die relativ wenige Eingabeparameter erfordert, nämlich: Indikatorperiode und angewandter Preis.


Vorlage für den MQL5-Assistenten (Option-2):

Für die zweite Implementierung des Handels mit mehreren Währungen werden wir die vom Assistenten zusammengestellte Expert Advisor-Datei ändern, indem wir ihr eine „Select“-Funktion hinzufügen. Diese Funktion stützt sich auf die Korrelationen der Symbole im Handelsportfolio und versucht, marktübergreifende Chancen zu nutzen, indem sie nur dann mehr als ein Symbol handelt, wenn diese Chancen bestehen. Es handelt sich im Wesentlichen um einen Filter aus dem Ansatz, den wir in der ersten Option oben betrachtet haben.

Um dies zu erreichen, sollten wir erstens den zeitgesteuerten Handel aktivieren, der überraschenderweise nicht standardmäßig aktiviert ist. Wir tun dies mit einer Zeile in der Funktion „OnInit“, wie unten angegeben:

//
ExtExpert[f].OnTimerProcess(true);

Damit können wir uns nun auf die Funktion „Auswählen“ konzentrieren, die aus zwei Hauptbereichen besteht. Die erste behandelt Situationen, in denen keine Positionen offen sind und ein Korrelation bestätigendes Signal unter allen Handelssymbolen im Portfolio ausgewählt werden muss. Dieses Signal ist bestätigend, weil wir uns immer noch auf die Signalklasse RSI-Signal als primäres Signal für alle Symbole verlassen. Die Bestätigung erfolgt in unserem Fall also über Autokorrelation des Schlusskurs-Puffers für jedes der Symbole. Es wird das Symbol mit dem größten positiven Wert aus dem Portfolio ausgewählt.

Wir verwenden den größten positiven Wert und nicht einfach nur den Betrag, da wir auf Trendsymbole oder das Symbol mit dem stärksten Trend im Portfolio abzielen. Sobald wir diesen Wert haben, können wir die Trendrichtung bestimmen, indem wir die Preisänderung zwischen dem letzten Wert und dem letzten Wert betrachten. Eine positive Veränderung deutet auf eine Aufwärtstrend, eine negative Veränderung auf eine Abwärtstrend. Dies wird in der nachstehenden Auflistung verarbeitet:

//+------------------------------------------------------------------+
//| Symbol Selector via Correlation                                  |
//+------------------------------------------------------------------+
bool  Select(double Direction, int &Index, ENUM_POSITION_TYPE &Type)
{  if(PositionsTotal() == 0)
   {  double _max = 0.0;
      int _index = -1;
      Type = INVALID_HANDLE;
      for(int f = 0; f < __FOLIO; f++)
      {  vector _v_0, _v_1;
         _v_0.CopyRates(__F[f], Period(), 8, 0, 30);
         _v_1.CopyRates(__F[f], Period(), 8, 30, 30);
         double _corr = _v_0.CorrCoef(_v_1);
         if(_max < _corr && ((Direction > 0.0 && _v_0[0] > _v_0[29]) || (Direction < 0.0 && _v_0[0] < _v_0[29])))
         {  _max = _corr;
            _index = f;
            if(_v_0[0] > _v_0[29])
            {  Type = POSITION_TYPE_BUY;
            }
            else if(_v_0[0] < _v_0[29])
            {  Type = POSITION_TYPE_SELL;
            }
         }
      }
      Index = _index;
      return(true);
   }
   else if(PositionsTotal() == 1)
   {  

//...
//...

   }
   return(false);
}


Die obige Auflistung ist also der „Standardteil“ der Auswahlfunktion, der Situationen behandelt, in denen noch keine Position geöffnet wurde. Sobald eine Position eröffnet wurde, suchen wir je nach der Performance der eröffneten Position nach marktübergreifenden Möglichkeiten. Wenn sich die ursprünglich eröffnete Position in einem Drawdown befindet, werden die verbleibenden Portfoliosymbole gesichtet und es wird versucht, eines mit einer effektiven „umgekehrten“ Korrelation zu finden. Umgekehrt“ in dem Sinne, dass wir nur an der Größe interessiert sind und dem Trend dieses Symbols folgen, solange seine Korrelationsgröße zu dem aktuell geöffneten Symbol im Vergleich zu der bereits geöffneten Position am höchsten ist. Der entsprechende Code ist weiter unten zu finden:

//+------------------------------------------------------------------+
//| Symbol Selector via Correlation                                  |
//+------------------------------------------------------------------+
bool  Select(double Direction, int &Index, ENUM_POSITION_TYPE &Type)
{  if(PositionsTotal() == 0)
   {  
//...
//...

   }
   else if(PositionsTotal() == 1)
   {  ulong _ticket = PositionGetTicket(0);
      if(PositionSelectByTicket(_ticket))
      {  double _float = PositionGetDouble(POSITION_PROFIT);
         ENUM_POSITION_TYPE _type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
         int _index = ArrayBsearch(__F, PositionGetString(POSITION_SYMBOL));
         double _max = 0.0;
         Type = INVALID_HANDLE;
         for(int f = 0; f < __FOLIO; f++)
         {  if(f == _index)
            {  continue;
            }
            else
            {  vector _v_0, _v_1;
               _v_0.CopyRates(__F[_index], Period(), 8, 0, 30);
               _v_1.CopyRates(__F[f], Period(), 8, 0, 30);
               double _corr = fabs(_v_0.CorrCoef(_v_1));
               if(_float < 0.0 && _max < _corr)
               {  _max = _corr;
                  Index = f;
                  if(_v_1[0] > _v_1[29])
                  {  Type = POSITION_TYPE_BUY;
                  }
                  else  if(_v_1[0] < _v_1[29])
                  {  Type = POSITION_TYPE_SELL;
                  }
               }
            }
         }
      }
      return(true);
   }
   return(false);
}

Um diese „Select“-Funktion in der Umgebung eines mit einem Assistenten zusammengestellten Expertenberaters verwenden zu können, müssen wir einige weitere Änderungen an der Expertenklasse vornehmen. Deshalb wäre es pragmatischer, eine doppelte Instanz der Expertenklasse zu erstellen und sie umzubenennen, so sperrig dies auch erscheinen mag. Die erste Änderung, die wir vornehmen müssen, besteht darin, die Funktion „Aktualisieren“ öffentlich zugänglich zu machen. Dies bedeutet, dass sie vom Abschnitt „Protected“ der Klassenschnittstelle in den Abschnitt „Public“ verschoben wird. In ähnlicher Weise sollte auch die Funktion „Prozess“ öffentlich zugänglich gemacht werden. Diese Änderung würde wie unten angegeben aussehen:

//+------------------------------------------------------------------+
//| Class CExpert.                                                   |
//| Purpose: Base class expert advisor.                              |
//| Derives from class CExpertBase.                                  |
//+------------------------------------------------------------------+
class CExpert : public CExpertBase
  {
protected:
   
   //...
   //...

public:
                     CExpert(void);
                    ~CExpert(void);
   
   //...

   //--- refreshing 
   virtual bool      Refresh(void);
   //--- processing (main method)
   virtual bool      Processing(void);
   
protected:
   
   //...
   //...

  };


Diese beiden Schlüsselfunktionen müssen in den öffentlichen Bereich verschoben werden, da wir sie in unserem geänderten Expert Advisor manuell aufrufen müssen. Normalerweise werden sie intern von den Funktionen „OnTick“ oder „OnTimer“ aufgerufen, je nachdem, welche der beiden Funktionen aktiviert ist. Und wenn sie aufgerufen werden, führen sie eine vollständige Signal-, Trailing- und Money-Management-Verarbeitung des Symbols durch, für das sie aufgerufen werden. In unserem Fall wollen wir nur bestimmte Symbole verarbeiten, abhängig von a) ihren relativen Korrelationen und b) davon, ob wir bereits eine Position geöffnet haben. Dies würde natürlich voraussetzen, dass wir „das Kommando“ darüber übernehmen, wie und wann sie gerufen werden. Dies geschieht in der Funktion „OnTimer“ wie unten angegeben:

//+------------------------------------------------------------------+
//| "Timer" event handler function                                   |
//+------------------------------------------------------------------+
void OnTimer()
{  for(int f = 0; f < __FOLIO; f++)
   {  ExtExpert[f].Refresh();
   }
   for(int f = 0; f < __FOLIO; f++)
   {  int _index = -1;
      ENUM_POSITION_TYPE _type = INVALID_HANDLE;
      ExtExpert[f].Magic(f);
      if(Select(signals[f].Direction(), _index, _type))
      {  ExtExpert[f].OnTimer();
         ExtExpert[f].Processing();
      }
   }
}


Bei der Auswahl des zu handelnden Symbols verfolgen wir es, indem wir seinen Index innerhalb des Quellportfolio-Arrays als seine magische Zahl zuweisen. Das bedeutet, dass wir in jeder for-Schleife innerhalb der Standardverarbeitungsfunktionen „OnTick“, „OnTrade“ und „OnTimer“ die magische Zahl aktualisieren müssen, die von der Handelsklasse vor der Verarbeitung verwendet wird. Da für diesen Test nutzerdefinierte Symbole verwendet wurden, musste außerdem aus Gründen der Datenqualität der Name der Symbole im Portfolio-Array mit ihrem Suffix (oder Präfix, falls zutreffend) angegeben werden. Aus irgendeinem Grund kann der Strategietester nutzerdefinierte Symbole nicht synchronisieren, obwohl alle Daten auf dem Testcomputer vorhanden sind, wenn Sie beim Initialisieren das Präfix und Suffix hinzufügen.

Außerdem wollen wir „OnTimer“ und nicht „OnTick“ handeln. Theoretisch sollte dies durch einfaches Anpassen der Parameter „OnProcessTimer“ und „OnProcessTick“ möglich sein, aber das Ändern dieser Parameter führt entweder zu keinem Handel oder zum Handel auf Tick. Dies bedeutete, dass tiefgreifendere Änderungen in der OnTick-Funktion und der OnTimer-Funktion der Expertenklasse erforderlich waren, sodass die OnProcess-Funktion innerhalb von OnTick deaktiviert wurde und die OnProcess-Funktion, die oben öffentlich gemacht wurde, nun unabhängig innerhalb der OnTimer-Funktion des Expertenberaters aufgerufen wird, wie im obigen OnTimer-Code gezeigt. Dies ist wiederum notwendig, weil aus einem unbekannten Grund zum Zeitpunkt dieses Schreibens die Funktion „Process“ innerhalb von „OnTimer“ in der Klasse „ExpertFolio“ nicht ausgeführt wird. Wir sind in der Lage, Preise und Indikatorwerte für alle Symbole zu aktualisieren, aber die Funktion „Process“ muss unabhängig davon aufgerufen werden. Und auch der Timer muss wie bei gewöhnlichen Expert Advisors manuell deklariert und beendet werden.


Testen und Optimieren

Wir führen Testläufe für das „Rohstoff“-Kreuz AUDJPY auf dem 4-Stunden-Zeitfenster von 2023 bis 2024 durch. Unsere Test-Expertenberater verwenden keinen Stop-Loss, da bei der zweiten Option, wie oben beschrieben, Verlustpositionen durch marktübergreifende Chancen verwaltet werden. Wir optimieren nur die RSI-Periode, da sie der Indikator für die Signalklasse ist, sowie die Schwellenwerte für das Öffnen und Schließen, den Verfall von Limit-Orders und die Einstiegslücke für Limit-Orders. Die Geldverwaltung wurde für feste Lose in der Mindestgröße eingesetzt. Die Berichte und Aktienkurven beider Optionen werden im Folgenden dargestellt:

r1

c1


r2

c2

Wie aus den obigen Berichten hervorgeht, werden viel mehr Geschäfte getätigt, als dies bei einer einzigen Währung der Fall wäre, wie man erwarten würde. Interessanterweise wurden die Einstellungen verwendet, um diese multiplen Trades durchzuführen und gleichzeitig die Drawdowns in vernünftigen Grenzen zu halten, was auf eine erweiterte Anwendung und ein größeres Potenzial hindeutet. Außerdem wurden bei der zweiten Option erwartungsgemäß weniger Abschlüsse getätigt als bei der ersten, weil a) es keinen sekundären Filter für das Einstiegssignal gab und b) bei der zweiten Option marktübergreifende (Absicherungs-) Regeln verwendet werden, um Drawdowns zu minimieren und das Risiko zu steuern.

Neben den Cross-Market-Möglichkeiten können auch ungedeckte Zinsarbitrage-Möglichkeiten erkundet werden, wie in der Einleitung erwähnt. In diesem Fall müssten die Wirtschaftsnachrichten aus dem mql5-Wirtschaftskalender extrahiert werden. Das Testen von Strategien mit diesen Werten ist noch begrenzt, aber vor kurzem wurde ein interessanter Artikel über das Speichern von Wirtschaftsnachrichten in einer Datenbank unter Verwendung der MQL5 IDE hier veröffentlicht. Es lohnt sich, ihn zu lesen, wenn Sie diesen Weg erkunden möchten.


Schlussfolgerung

Abschließend haben wir untersucht, wie der Handel mit mehreren Währungen in die mit dem MQL5-Assistenten zusammengestellten Expert Advisors eingeführt werden kann. Der MQL5-Assistent ermöglicht jedoch nicht nur eine schnelle Entwicklung von Experten mit weniger Wiederholungen, sondern auch das gleichzeitige Testen von mehr als einer Idee durch ein Gewichtungssystem. Wie immer können neue Leser hier und hier nachlesen, wie man den Assistenten nutzt.

Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/14806

Beigefügte Dateien |
ExpertFolio_1.mqh (121.5 KB)
ExpertFolio_2.mqh (121.49 KB)
opt_17_1.mq5 (7.04 KB)
opt_17_2.mq5 (10.18 KB)
Die Gruppenmethode der Datenverarbeitung: Implementierung des Kombinatorischen Algorithmus in MQL5 Die Gruppenmethode der Datenverarbeitung: Implementierung des Kombinatorischen Algorithmus in MQL5
In diesem Artikel setzen wir unsere Untersuchung der Algorithmenfamilie Group Method of Data Handling mit der Implementierung des Kombinatorischen Algorithmus und seiner verfeinerten Variante, dem Kombinatorischen Selektiven Algorithmus in MQL5 fort.
Aufbau eines Modells von Kerzen, Trend und Nebenbedingungen (Teil 2): Zusammenführung integrierter Indikatoren Aufbau eines Modells von Kerzen, Trend und Nebenbedingungen (Teil 2): Zusammenführung integrierter Indikatoren
In diesem Artikel geht es darum, die Vorteile der im MetaTrader 5 integrierten Indikatoren zu nutzen, um Signale abseits eines Trends zu erkennen. In Fortführung des vorherigen Artikels werden wir untersuchen, wie wir unsere Idee mit Hilfe von MQL5-Code in das endgültige Programm übertragen können.
Neuronale Netze leicht gemacht (Teil 69): Dichte-basierte Unterstützungsbedingung für die Verhaltenspolitik (SPOT) Neuronale Netze leicht gemacht (Teil 69): Dichte-basierte Unterstützungsbedingung für die Verhaltenspolitik (SPOT)
Beim Offline-Lernen verwenden wir einen festen Datensatz, der die Umweltvielfalt nur begrenzt abdeckt. Während des Lernprozesses kann unser Agent Aktionen generieren, die über diesen Datensatz hinausgehen. Wenn es keine Rückmeldungen aus der Umwelt gibt, wie können wir dann sicher sein, dass die Bewertungen solcher Maßnahmen korrekt sind? Die Beibehaltung der Agentenpolitik innerhalb des Trainingsdatensatzes ist ein wichtiger Aspekt, um die Zuverlässigkeit des Trainings zu gewährleisten. Darüber werden wir in diesem Artikel sprechen.
Wie man ein volatilitätsbasiertes Handelssystem (Chaikin Volatility - CHV) aufbaut und optimiert Wie man ein volatilitätsbasiertes Handelssystem (Chaikin Volatility - CHV) aufbaut und optimiert
In diesem Artikel werden wir einen weiteren, volatilitätsbasierten Indikator namens Chaikin Volatility vorstellen. Wir werden verstehen, wie man einen nutzerdefinierten Indikator erstellt, nachdem wir herausgefunden haben, wie er verwendet und aufgebaut werden kann. Wir werden einige einfache Strategien vorstellen, die verwendet werden können, und sie dann testen, um zu verstehen, welche davon besser sein kann.