English Русский 中文 Español 日本語 Português
preview
Entwicklung eines Replay Systems (Teil 38): Den Weg ebnen (II)

Entwicklung eines Replay Systems (Teil 38): Den Weg ebnen (II)

MetaTrader 5Beispiele | 17 Juni 2024, 14:56
102 0
Daniel Jose
Daniel Jose

Einführung

Im vorherigen Artikel Entwicklung eines Replay Systems (Teil 37): Den Weg bereiten (I), haben wir eine einfache Möglichkeit gesehen, um zu verhindern, dass der Nutzer einen Indikator im Chart dupliziert. In diesem Artikel haben wir überprüft, dass die MetaTrader 5 Plattform mit einem sehr einfachen Code, der nur aus ein paar Zeilen besteht, das Erscheinen eines zweiten Indikators auf dem Chart vermeiden kann, wenn wir ihn in einer einzigen Kopie benötigen. Es ist wichtig, dass der Indikator nicht doppelt vorhanden ist.

Ich hoffe, Sie verstehen die Idee und wie das gewünschte Ergebnis erreicht wurde. Der Indikator darf auf keinen Fall dupliziert werden.

Auch wenn wir an dem Grundsatz festhalten, dass es in MetaTrader 5 keine Duplizierung geben soll, sollten Sie beachten, dass die Zwei-Wege-Kommunikation zwischen dem Indikator und dem Expert Advisor noch in weiter Ferne liegt. Davon sind wir noch sehr weit entfernt. Die Garantie, dass der Indikator im Chart nicht dupliziert wird, gibt jedoch zumindest Sicherheit. Denn wenn der Indikator und der EA zusammenspielen, wissen wir, dass wir es mit dem richtigen Indikator zu tun haben.

In diesem Artikel werden wir beginnen, die Dinge mit den Augen des EA zu betrachten. Aber wir müssen auch einige Änderungen am Indikator vornehmen, da der Indikator aus dem vorherigen Artikel leider überhaupt nicht auf den EA reagieren kann. Dies geschieht, wenn der EA etwas wissen will.


Schaffung der ersten Interaktion zwischen den Prozessen

Um eine gute Erklärung der Vorgänge zu geben, müssen wir einige Kontrollpunkte erstellen. Beginnen wir mit dem Code des Indikators. Keine Sorge, es ist alles leicht zu verstehen.

Der vollständige Indikatorcode ist nachstehend aufgeführt:

01. #property copyright "Daniel Jose"
02. #property link      ""
03. #property version   "1.00"
04. #property indicator_chart_window
05. #property indicator_plots 0
06. //+------------------------------------------------------------------+
07. #define def_ShortName       "SWAP MSG"
08. #define def_ShortNameTmp    def_ShortName + "_Tmp"
09. //+------------------------------------------------------------------+
10. input double user00 = 0.0;
11. //+------------------------------------------------------------------+
12. long m_id;
13. //+------------------------------------------------------------------+
14. int OnInit()
15. {
16.     m_id = ChartID();
17.     IndicatorSetString(INDICATOR_SHORTNAME, def_ShortNameTmp);
18.     if (ChartWindowFind(m_id, def_ShortName) != -1)
19.     {
20.             ChartIndicatorDelete(m_id, 0, def_ShortNameTmp);
21.             Print("Only one instance is allowed...");
22.             return INIT_FAILED;
23.     }
24.     IndicatorSetString(INDICATOR_SHORTNAME, def_ShortName);
25.     Print("Indicator configured with the following value:", user00);
26.     
27.     return INIT_SUCCEEDED;
28. }
29. //+------------------------------------------------------------------+
30. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
31. {
32.     return rates_total;
33. }
34. //+------------------------------------------------------------------+


Beachten Sie, dass die einzige Ergänzung des Codes die Zeile 25 ist. Dies wird unsere Überprüfungslinie sein, zumindest für das erste Mal. Im Moment sind wir daran interessiert, wie der EA mit dem Indikator interagiert und ob wir Informationen oder Daten an ihn senden können.

Beachten Sie, dass in Zeile 10 die Art der vom Indikator erwarteten Information vom Typ double ist. Dies geschieht absichtlich, da das Ziel darin besteht, einen Mechanismus zu schaffen, der das globale Terminalvariablensystem für die Kommunikation zwischen dem EA und dem Indikator ersetzen kann. Sollten sich die entwickelten oder verwendeten Mittel als ungeeignet erweisen, können wir dieses Modell leicht durch ein Modell der globalen Terminalvariablen ersetzen.

Sie können auch andere Datentypen für die Kommunikation verwenden, zumindest für die Übertragung von Daten vom EA zum Indikator.

Nachdem wir nun den Indikatorcode geändert haben, können wir mit dem EA-Code fortfahren. Er ist nachstehend in vollem Wortlaut wiedergegeben:

01. #property copyright "Daniel Jose"
02. #property link      ""
03. #property version   "1.00"
04. //+------------------------------------------------------------------+
05. input double user00 = 2.0;
06. //+------------------------------------------------------------------+
07. int m_handle;
08. long m_id;
09. //+------------------------------------------------------------------+
10. int OnInit()
11. {
12.     m_id = ChartID();
13.     if ((m_handle = ChartIndicatorGet(m_id, 0, "SWAP MSG")) == INVALID_HANDLE)
14.     {
15.             m_handle = iCustom(NULL, PERIOD_CURRENT, "Mode Swap\\Swap MSG.ex5", user00);
16.             ChartIndicatorAdd(m_id, 0, m_handle);
17.     }
18.     Print("Indicator loading result:", m_handle != INVALID_HANDLE ? "Success" : "Failed");
19.     
20.     return INIT_SUCCEEDED;
21. }
22. //+------------------------------------------------------------------+
23. void OnDeinit(const int reason)
24. {
25.     ChartIndicatorDelete(m_id, 0, "SWAP MSG");
26.     IndicatorRelease(m_handle);
27. }
28. //+------------------------------------------------------------------+
29. void OnTick()
30. {
31. }
32. //+------------------------------------------------------------------+


Für viele mag dieser EA-Code recht seltsam erscheinen. Mal sehen, wie es funktioniert. Dies ist der erste Schritt zu dem, was wir wirklich tun müssen.

In Zeile 05 geben wir dem Nutzer die Möglichkeit, den an den Indikator übergebenen Wert zu setzen. Denken Sie daran: Wir wollen testen und verstehen, wie die Kommunikation ablaufen wird. Die Zeilen 07 und 08 enthalten zwei interne globale Variablen im EA-Code. Normalerweise verwende ich nicht gerne globale Variablen, aber in diesem Fall kann man eine Ausnahme machen. Der Inhalt dieser Variablen wird in dem Code von OnInit festgelegt, der in Zeile 10 beginnt.

Dies mag ein wenig kompliziert erscheinen. Es gibt nämlich einige Dinge, die wir in dieser Phase verstehen müssen.

In Zeile 12 initialisieren wir eine Variable, die den Index des Zeitrahmens angibt, in dem der EA ausgeführt wird. Dann kommt Zeile 13, wo Anfänger oft auf Probleme stoßen. Viele Leute fügen diese Zeile einfach nicht in ihren Code ein. Das Fehlen dieser Zeile macht Ihren Code nicht sofort kaputt, aber ihr Einschluss verhindert das Auftreten bestimmter Arten von Fehlern. Viele dieser Fehler sind LAUFZEIT-Fehler, die jederzeit auftreten können und daher schwer zu beheben sind.

Nachdem wir den Code in Zeile 13 hinzugefügt haben, wird MetaTrader 5, wenn der von uns benötigte Indikator bereits im Chart vorhanden ist, den Handle dieses Indikators zurückgeben." Wir müssen uns also nicht die Mühe machen, den Indikator im Chart zu platzieren.

Wenn Zeile 13 jedoch zeigt, dass der gewünschte Indikator nicht im Chart vorhanden ist, wird der Code ausgeführt, der den Indikator zum Chart hinzufügt. Denken Sie an Folgendes: Der Indikator, den wir brauchen und verwenden werden, ist ein nutzerdefinierter Indikator. Daher rufen wir iCustom auf, was in Zeile 15 zu sehen ist.

Jetzt kommt der knifflige Teil: Warum wird iCustom, das in Zeile 15 steht, auf diese Weise deklariert? Haben Sie eine Ahnung, warum? Um dies zu verstehen, sollten wir uns ansehen, was in der Dokumentation steht:

int  iCustom(
                 string            symbol,   // symbol name
                 ENUM_TIMEFRAMES   period,   // period
                 string            name      // folder/custom indicator name
                 ...                         // list of indicator parameters
             );

Aus der obigen Tabelle können Sie ersehen, dass der erste Parameter der Funktion der Name des Symbols ist. Aber in Zeile 15 des Codes ist der erste Parameter NULL. Warum ist das so? Warum verwenden wir nicht die Konstante _Symbol ? Der Grund dafür ist, dass für den Compiler, NULL und _Symbol ein und dasselbe sind. Auf diese Weise wird der Indikator mit demselben Symbol erstellt, das auch der EA-Chart hat.

Der nächste Parameter in der Liste ist der Chartzeitrahmen. Wieder haben wir etwas anderes als das, was viele erwarten. In Zeile 15 verwenden wir den Wert PERIOD_CURRENT aber warum? Der Grund dafür ist, dass der Indikator mit der gleichen Periode wie der Expert Advisor synchronisiert bleiben soll. Ein Detail: Wenn Sie möchten, dass der Indikator einen anderen Chartzeitrahmen analysiert, geben Sie einfach die gewünschte Zeitrahmen in diesem Parameter an. So wird der Indikator auf eine bestimmte Zeitrahmen festgelegt, und der EA kann sich in anderen Zeitrahmen bewegen.

Bei den nutzerdefinierten Indikatoren ist es meines Erachtens der dritte Parameter, der zu schwerwiegenden Folgen führen kann. Viele Menschen wissen nicht, was sie hier eintragen sollen, und lassen es manchmal leer oder geben den falschen Ort an, weil sie die Bedeutung nicht verstehen. Wenn wir den falschen Ort angeben, kann MetaTrader 5 den benötigten Indikator nicht finden.

Schauen Sie sich an, was in Zeile 15 in diesem dritten Parameter deklariert ist. Wir geben nicht nur einen Namen an, sondern einen Namen und einen Pfad. Woher stammen diese Informationen? Um das herauszufinden, müssen wir auf den vorherigen Artikel zurückgreifen und herausfinden, woher diese Information stammt. Siehe Abbildung 01.

Abbildung 01

Abbildung 01 - Erstellen eines Indikators

In Abbildung 01 können Sie sehen, woher die Informationen für den dritten Parameter stammen. Das sind praktisch dieselben Dinge. Mit den folgenden Änderungen: Zuerst löschen wir das Stammverzeichnis, in diesem Fall wird es Indikatoren. Das liegt daran, dass MetaTrader 5 den Indikator zuerst in diesem Verzeichnis sucht. Der zweite Punkt ist, dass wir die .ex5 Datei hinzugefügt haben. Auf diese Weise erhalten wir den korrekten Speicherort der ausführbaren Datei. Wenn MetaTrader 5 den EA auf dem Chart platziert und Zeile 15 ausführt, weiß er, wo und welcher Indikator zu verwenden ist.

Im Folgenden gehen wir auf einige der Fragen und Probleme ein, die auftreten können. Aber lassen Sie uns zunächst die Grundlagen klären.

Dieser dritte Parameter und die folgenden sind optional. Wenn wir dem Indikator einen beliebigen Wert geben wollen, müssen wir dies über den vierten Parameter tun. Sie müssen jedoch sicherstellen, dass dies in der gleichen Reihenfolge geschieht, in der die Parameter auf dem Indikator erscheinen. Sie müssen auch darauf achten, dass sie vom richtigen Typ sind. Sie können nicht double eingeben, wenn der Indikator einen float- oder long-Wert erwartet. In diesem Fall wird MetaTrader 5 sofort nach dem Start des Indikators einen Fehler erzeugen.

Es gibt auch andere Möglichkeiten, Parameter an den Indikator zu übergeben, aber der Einfachheit halber werden wir jetzt iCustom verwenden. Wenn Sie sich den Code des Indikators ansehen, werden Sie feststellen, dass in Zeile 10 ein double-Wert erwartet wird. Dieser Wert wird dem Indikator durch den EA im vierten Parameter in Zeile 15 des EA-Codes zur Verfügung gestellt.

Jetzt kommt eine wichtige Frage, die viele Menschen vernachlässigen, was zu Problemen im gesamten System führt. Es ist die Zeile 16 im EA-Code. Warum ist diese Zeile so wichtig?

Es gibt Fälle, in denen diese Zeile ignoriert werden kann, wenn es um nutzerdefinierte Indikatoren geht. Dies gilt insbesondere für die Indikatoren, die wir benötigen, wenn wir wollen, dass MetaTrader 5 nur eine Instanz auf dem Chart unterstützt. Wir können Zeile 16 in keiner Weise ignorieren, und wenn Zeile 16 vorhanden ist, muss auch Zeile 25 hinzugefügt werden.

Diese beiden Zeilen vermeiden Probleme. In Zeile 16 wird der Indikator auf dem Chart ausgeführt. Wenn der Nutzer also versucht, eine weitere Instanz des Indikators auf demselben Chart auszuführen, verhindert MetaTrader 5 zusammen mit dem Indikatorcode, dass die neue Instanz ausgeführt wird. Wenn Sie Zeile 16 aus dem EA-Code entfernen, kann der Nutzer versehentlich eine neue Instanz des Indikators auf dem Chart platzieren, was dazu führt, dass der Nutzer, nicht der EA, über die Berechnungen, die der Indikator durchführt, verwirrt wird.

Mit berechneten Indikatoren haben wir ein gewisses Problem, aber im Falle eines Indikators wie Chart Trader ist das Problem noch komplexer. Da wir es in diesem Fall mit grafischen Objekten zu tun haben. Es ist wichtig, dass man weiß, wie man alles richtig macht. Dann wird es einfacher zu verstehen, wie man komplexere Dinge tut.

Ich denke, es ist jetzt klar, wie wichtig die Zeile 16 ist. Was bewirkt die Zeile 25? Sie entfernt den angegebenen Indikator aus dem Chart. Bitte beachten Sie eines: Wir müssen den Namen des zu löschenden Indikators angeben. Er wird im Indikator in Zeile 24 des Indikatorcodes platziert. Die Namen müssen übereinstimmen, sonst versteht MetaTrader 5 nicht, welcher Indikator gelöscht werden muss. Außerdem müssen wir in einigen Fällen auch angeben, welches Teilfenster verwendet wird. Da wir kein Teilfenster verwenden, belassen wir diesen Wert auf NULL.

Dann, in Zeile 26, entfernen wir den Indikator-Handler, weil wir ihn nicht mehr brauchen.

Schauen wir uns nun an, wie MetaTrader 5 mit diesem Schema der Interaktion zwischen dem EA und dem Indikator funktioniert. Um dies zu verstehen, müssen wir ein paar Dinge tun. Achten Sie daher genau auf die Details des Verfahrens. Außerdem sollten Sie jede Änderung testen und den generierten Code ausprobieren, denn jede der Änderungen bringt MetaTrader 5 seine eigene Art und Weise, die Situation zu handhaben. Es ist wichtig, die obigen Erklärungen nicht nur zu lesen, sondern auch zu verstehen, was geschieht. Und um zu verstehen, was passiert, wenn ein EA auf eine bestimmte Art und Weise geschrieben wird oder wenn derselbe EA auf eine andere Art und Weise programmiert wird, müssen wir drei Situationen betrachten. Der im EA und im Indikator verwendete Code ist derselbe wie der, den wir bisher erklärt haben, der einzige Unterschied besteht im Vorhandensein oder Fehlen der EA-Codezeile.

Gehen Sie nun wie folgt vor:

  • Kompilieren Sie zunächst den Code mit allen Zeilen und sehen Sie sich an, wie das System im MetaTrader 5 funktioniert.
  • Löschen Sie dann die Zeilen 16 und 25 und testen Sie das System erneut in MetaTrader 5.
  • Schließlich wird nur Zeile 16 gestrichen und Zeile 25 belassen. Danach testen Sie das System erneut.

Sie denken vielleicht, dass das alles Unsinn ist und dass Sie als erfahrener Programmierer niemals solche Fehler machen würden. Aber zu wissen, was jede einzelne Code-Zeile bewirkt und was sie bei der Ausführung von MetaTrader 5 bewirkt, ist vielleicht wichtiger als es scheint.

Wenn Sie dieses Stadium erreicht haben, dann verstehen Sie die zweite Phase, in der wir Daten vom EA zum Indikator übertragen können, ohne globale Terminalvariablen zu verwenden. Sie haben einen großen Schritt auf dem Weg zu einem Qualitätsprogrammierer gemacht. Aber wenn Sie es immer noch nicht verstehen, lassen Sie sich nicht entmutigen. Gehen Sie zum Anfang dieses oder des vorherigen Artikels zurück und versuchen Sie, diesen Schritt zu verstehen. Jetzt wird es sehr kompliziert, und das ist kein Scherz. Wir müssen dafür sorgen, dass der Indikator Daten an den EA sendet.

Hier sendet der Indikator Daten an den Expert Advisor. In manchen Fällen kann dies ganz einfach sein. Aber jeder, der meine Artikel verfolgt, hat wahrscheinlich bemerkt, dass ich die Dinge gerne auf die Spitze treibe, den Computer zum Schwitzen bringe und ihn auffordere, Dinge anders zu machen. Das liegt daran, dass ich wirklich möchte, dass sowohl die Sprache als auch die Plattform an der Grenze des Möglichen arbeiten.


IndicatorCreate oder iCustom - was ist zu verwenden?

Viele Anfänger fragen sich vielleicht, wie man nutzerdefinierte Indikatoren aufruft. Dies kann auf zwei Arten geschehen. Den ersten Punkt haben wir im vorherigen Thema behandelt, in dem wir die Verwendung von iCustom erläutert haben. Aber es gibt noch einen anderen Weg, der für einige Arten der Modellierung attraktiver sein kann, während für andere die Verwendung von iCustom ausreicht.

Es geht nicht darum, die eine oder andere Methode zu verwenden. Ich möchte hier zeigen, wie Sie den Aufruf IndicatorCreate verwenden können, um Ihre eigenen Indikatoren zu laden.

Bevor wir beginnen, sollten wir uns über eines im Klaren sein. Die Funktion IndicatorCreate ist keine spezielle Funktion. Dies ist eigentlich eine Grundfunktion. Was bedeutet das? Eine Basisfunktion ist eine Funktion, die im Wesentlichen dazu dient, eine andere Funktion zu fördern, jedoch mit einem Detail: „abgeleitete“ Funktionen verwenden die Basisfunktion, machen sie aber einfacher zu verwenden.

Dies liegt daran, dass es nicht notwendig ist, einen Aufruf zu modellieren, wie wir es von einer Basisfunktion erwarten würden. Wir können eine einfachere Modellierung verwenden. Auf diese Weise entstehen weitere Funktionen. Sie können sie in der Dokumentation als technische Indikatoren sehen. Zu diesen Indikatoren gehört iCustom, bei dem es sich im Wesentlichen um eine abgeleitete Funktion zur Vereinfachung der Modellierung handelt.

Wie sähe also der Quellcode des zu Beginn des Artikels besprochenen Expert Advisors aus, wenn wir IndicatorCreate statt iCustom verwenden würden? Der Code ist unten zu sehen:

01. #property copyright "Daniel Jose"
02. #property link      ""
03. #property version   "1.00"
04. //+------------------------------------------------------------------+
05. input double user00 = 2.2;
06. //+------------------------------------------------------------------+
07. int m_handle;
08. long m_id;
09. //+------------------------------------------------------------------+
10. int OnInit()
11. {
12.     MqlParam params[];
13.     
14.     m_id = ChartID();       
15.     if ((m_handle = ChartIndicatorGet(m_id, 0, "SWAP MSG")) == INVALID_HANDLE)
16.     {
17.             ArrayResize(params, 2);
18.             params[0].type = TYPE_STRING;
19.             params[0].string_value = "Mode Swap\\SWAP MSG";
20.             params[1].type = TYPE_DOUBLE;
21.             params[1].double_value = user00;
22.             m_handle = IndicatorCreate(NULL, PERIOD_CURRENT, IND_CUSTOM, ArraySize(params), params);
23.             ChartIndicatorAdd(m_id, 0, m_handle);
24.     }
25.     Print("Indicator loading result:", m_handle != INVALID_HANDLE ? "Success" : "Failed");
26.     
27.     return INIT_SUCCEEDED;
28. }
29. //+------------------------------------------------------------------+
30. void OnDeinit(const int reason)
31. {
32.     ChartIndicatorDelete(m_id, 0, "SWAP MSG");
33.     IndicatorRelease(m_handle);
34. }
35. //+------------------------------------------------------------------+
36. void OnTick()
37. {
38. }
39. //+------------------------------------------------------------------+

Vergleichen Sie die Unterschiede zwischen dem obigen Code und dem, den wir zu Beginn des Artikels gezeigt haben. Beide tun das Gleiche. Die Hauptfrage ist: Warum muss dieser Code, der den IndicatorCreate-Aufruf verwendet, auf diese Weise ausgeführt werden?

Die Funktion iCustom verbirgt eigentlich genau das, was wir tun müssen, aber lassen Sie uns herausfinden, was los ist.

Zunächst müssen wir eine Variable deklarieren, die in Zeile 12 als Array deklariert wird. Dies sollte genau so gemacht werden. Wenn der Indikator im Chart nicht vorhanden ist, müssen wir ihn erstellen. Dazu müssen wir der Funktion IndicatorCreate mitteilen, was sie tun soll und wie sie es tun soll.

Neben der Anzahl der Parameter, die wir im Indikator verwenden, müssen wir der Funktion IndicatorCreate auch den Namen des Indikators mitteilen. Wenn wir also nur den Namen des Indikators eingeben wollen, sollte die Funktion ArrayResize in Zeile 17 nicht zwei, sondern ein Element auswählen. Wenn wir dem Indikator 5 Parameter übergeben würden, müssten wir 6 Elemente zuweisen usw. Schauen wir, wie viele Parameter wir senden müssen, und weisen wir eine zusätzliche Position zu.

Nun müssen wir dieses Array konfigurieren. Hier zeigt Zeile 22 mit der Funktion IndicatorCreate an, dass wir einen nutzerdefinierten Indikator verwenden werden. Dies geschieht mit Hilfe der Enumeration IND_CUSTOM. Es gibt mehrere Dinge, die wir tun müssen. In Zeile 18 sehen wir, wie wir bei der ersten Position des Arrays vorgehen. Denken Sie daran, dass MQL5 C++ sehr ähnlich ist, sodass wir mit dem Zählen bei Null beginnen. Der Informationstyp an der ersten Stelle muss STRING sein, daher wird die Deklaration wie in Zeile 18 gezeigt geschrieben.

In Zeile 19 geben wir den Namen des verwendeten nutzerdefinierten Indikators ein. Beachten Sie, dass der Name des Indikators derselbe ist, der verwendet werden würde, wenn wir den iCustom-Aufruf verwenden würden. Der einzige Unterschied besteht darin, dass wir die Dateierweiterung nicht angeben. Es muss sich um eine ausführbare Datei mit der Erweiterung .ex5 handeln, die Angabe der Erweiterung ist also optional.

WICHTIG! Was in den Zeilen 18 und 19 geschieht, muss jedes Mal getan werden, wenn der nutzerdefinierte Indikator verwendet wird. Wenn Sie einen anderen Indikator verwenden, egal welchen, dann müssen Sie, sobald Sie mit dem Einrichten der Array-Daten beginnen, die Parameter so angeben, wie Sie sie im weiteren Verlauf sehen werden, d. h. ab Zeile 20.

Nachdem wir der Funktion IndicatorCreate mitgeteilt haben, welcher nutzerdefinierte Indikator verwendet werden soll, können wir nun damit beginnen, die Parameter auszufüllen, die an die Funktion übergeben werden. Diese Parameter müssen in der richtigen Reihenfolge angegeben werden. Unabhängig davon, welchen Indikator Sie verwenden, führt die Deklaration von falschen Typen zu Laufzeitfehlern. Seien Sie daher sehr vorsichtig, wenn Sie diese Informationen ausfüllen.

In Zeile 20 geben wir an, dass der erste Parameter vom Typ double sein soll. Es kann jedoch jeder der in der Enumeration ENUM_DATATYPE definierten Typen sein. Sie können jede davon verwenden, aber es gibt einige Dinge zu beachten.

Die Typen TYPE_DOUBLE und TYPE_FLOAT werden verwendet für double_value verwendet, in diesem Fall in Zeile 21.

Wenn in Zeile 20 der Typ TYPE_STRING verwendet worden wäre, dann würde in Zeile 21 der Wert in den Typ string_value Variable übertragen. Für alle anderen möglichen Typen, die in Zeile 20 deklariert werden, geben wir den Wert in Zeile 21 mit einer integer_value Variable ein.

Dies ist sehr wichtig, daher sollten wir diese Information klarstellen. Zum besseren Verständnis werfen Sie bitte einen Blick auf die nachstehende Tabelle:

Verwendete Identifikator Datentyp Wo soll der Wert eingetragen werden? 

TYPE_BOOL  Logisch integer_value

TYPE_CHAR  Char integer_value    
TYPE_UCHAR    Char ohne Vorzeichen integer_value    
TYPE_SHORT    Short integer_value    
TYPE_USHORT    Short ohne Vorzeichen integer_value
   
TYPE_COLOUR    Farbe integer_value
   
TYPE_INT    Integer integer_value
   
TYPE_UINT    Integer ohne Vorzeichen integer_value
   
TYPE_DATETIME    DateTime integer_value
   
TYPE_LONG    Long integer_value      
TYPE_ULONG    Long ohne Vorzeichen integer_value
   
TYPE_FLOAT    Float double_value     
TYPE_DOUBLE    Double double_value
   
TYPE_STRING    Zeichenfolge string_value    

Tabelle der Entsprechungen.

Aus dieser Tabelle geht klar hervor, was wir in Zeile 20 verwenden werden (der verwendete Identifikator) und welche Variable den Wert in Zeile 21 erhalten wird. Wir müssen dies für jeden der Parameter tun, die an unseren nutzerdefinierten Indikator übergeben werden sollen. Da wir nur einen Parameter verwenden, werden wir auch nur mit diesem einen arbeiten.

Beachten Sie, dass die Verwendung des Aufrufs IndicatorCreate in unserem speziellen Fall sehr viel arbeitsintensiver ist als sein Derivat iCustom.

Nachdem wir alle Parameter festgelegt haben, die wir definieren wollen, gehen wir zu Zeile 22, wo wir die Funktion tatsächlich aufrufen. Dies geschieht, damit wir Dinge leicht erhöhen oder reduzieren können. Alle Felder sind ausgefüllt, sodass Sie die Zeile 22 nicht erneut bearbeiten müssen, wenn Sie das Kennzeichen oder die Anzahl der Parameter ändern müssen.

Die Idee ist, die Dinge immer zu vereinfachen, anstatt sie zu verkomplizieren.

Wegen dieses zusätzlichen Aufwands, um die gleiche Art der Ausführung in MetaTrader 5 einzurichten, werden wir die Funktion IndicatorCreate im aktuellen Code nicht oft sehen. Aber nichts hindert Sie daran, es zu nutzen.

Bevor ich diesen Artikel abschließe, möchte ich kurz auf eine weitere Funktion eingehen: IndikatorParameter. Diese Funktion ermöglicht es, etwas über einen unbekannten Indikator zu überprüfen. Angenommen, Sie haben mehrere verschiedene Indikatoren in Ihrem Chart, von denen jeder auf eine bestimmte Weise initialisiert wurde. Vielleicht möchten Sie eine indikatorbasierte Strategie automatisieren, aber da sich der Markt so plötzlich ändert, kann es einige Minuten dauern, bis alle Indikatoren richtig eingestellt sind.

Um den Prozess ein wenig zu beschleunigen, können Sie die Funktion IndicatorParameters verwenden. Sobald diese Funktion aufgerufen wird, füllt MetaTrader 5 sie aus, um uns genau zu sagen, wie ein bestimmter Indikator konfiguriert ist. Dann wird eine andere Funktion, normalerweise IndicatorCreate, verwendet, um die Konfiguration dieses Indikators zu ändern. Wenn der EA diesen Indikator verwendet, um zu kaufen oder zu verkaufen, wird er sofort verstehen, was zu tun ist, weil wir einen Trigger haben.

Dieses Thema wurde in einer Serie über Handelsautomatisierung ausführlich erörtert und demonstriert. In dem Artikel „Erstellen eines EA, der automatisch arbeitet (Teil 15): Automation (VII)“ haben wir uns angesehen, wie man den Indikator als Auslöser für einen Kauf oder Verkauf verwenden kann.

Aber wie ich gerade erwähnt habe, können wir die Funktion IndicatorParameters verwenden, um denselben EA noch interessanter zu machen. Wir werden uns jedoch nicht mit der Verwendung der Funktion IndicatorParameters befassen, zumindest nicht in dieser Serie über Replay/Simulation. Ich wollte nur erwähnen, wie nützlich diese Funktion ist.


Schlussfolgerung

In diesem Artikel haben wir gesehen, wie man Daten an den Indikator sendet. Obwohl wir dies mit einem Expert Advisor gemacht haben, können Sie auch andere Arten von Prozessen verwenden, z. B. Skripte. Leider ist es, zumindest zum Zeitpunkt der Abfassung dieses Artikels, aufgrund des Charakters von Diensten nicht möglich, genau diese Aufgabe zu übernehmen.

Aber es ist alles in Ordnung. Wir müssen mit dem arbeiten, was wir haben. Diese Frage ist jedoch noch nicht vollständig geklärt. Wir müssen noch verstehen, wie man Daten vom Indikator zum Expert Advisor überträgt. Wir brauchen eine Möglichkeit, Chat Trader im Wiedergabe-/Simulationssystem zu verwenden, aber wir wollen dafür keine globalen Terminalvariablen verwenden, und wir wollen nicht mehrere Programme kompilieren und riskieren, dass wir vergessen, eines davon zu kompilieren.

Um herauszufinden, wie nah wir an dem sind, was wir für Chart Trader brauchen, brauchen wir einen weiteren Artikel. Im nächsten Artikel dieser Reihe werden wir uns damit befassen, wie wir einen Chart Trader erstellen können.

Verpassen Sie nicht den nächsten Artikel: das Thema wird sehr interessant und spannend sein.

Übersetzt aus dem Portugiesischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/pt/articles/11591

Beigefügte Dateien |
EA.mq5 (1.36 KB)
swap.mq5 (1.31 KB)
Algorithmen zur Optimierung mit Populationen: Evolution sozialer Gruppen (ESG) Algorithmen zur Optimierung mit Populationen: Evolution sozialer Gruppen (ESG)
Wir werden das Prinzip des Aufbaus von Algorithmen mit mehreren Populationen besprechen. Als Beispiel für diese Art von Algorithmus werden wir uns den neuen nutzerdefinierten Algorithmus - Evolution of Social Groups (ESG) - ansehen. Wir werden die grundlegenden Konzepte, die Mechanismen der Populationsinteraktion und die Vorteile dieses Algorithmus analysieren und seine Leistung bei Optimierungsproblemen untersuchen.
Entwicklung eines MQL5 RL-Agenten mit Integration von RestAPI (Teil 3): Erstellen von automatischen Bewegungen und Testskripten in MQL5 Entwicklung eines MQL5 RL-Agenten mit Integration von RestAPI (Teil 3): Erstellen von automatischen Bewegungen und Testskripten in MQL5
Dieser Artikel beschreibt die Implementierung von automatischen Zügen im Tic-Tac-Toe-Spiel in Python, integriert mit MQL5-Funktionen und Unit-Tests. Das Ziel ist es, die Interaktivität des Spiels zu verbessern und die Zuverlässigkeit des Systems durch Tests in MQL5 zu gewährleisten. Die Präsentation umfasst die Entwicklung der Spiellogik, die Integration und praktische Tests und schließt mit der Erstellung einer dynamischen Spielumgebung und eines robusten integrierten Systems.
Entwicklung eines Expertenberaters für mehrere Währungen (Teil 2): Übergang zu virtuellen Positionen von Handelsstrategien Entwicklung eines Expertenberaters für mehrere Währungen (Teil 2): Übergang zu virtuellen Positionen von Handelsstrategien
Lassen Sie uns mit der Entwicklung eines Multiwährungs-EAs mit mehreren parallel arbeitenden Strategien fortfahren. Versuchen wir, die gesamte mit der Eröffnung von Marktpositionen verbundene Arbeit von der Strategieebene auf die Ebene des EA zu verlagern, der die Strategien verwaltet. Die Strategien selbst werden nur virtuell gehandelt, ohne Marktpositionen zu eröffnen.
Trailing-Stopp im Handel Trailing-Stopp im Handel
In diesem Artikel befassen wir uns mit der Verwendung eines Trailing-Stops beim Handel. Wir werden bewerten, wie nützlich und wirksam das ist und wie es genutzt werden kann. Die Effizienz eines Trailing-Stopps hängt weitgehend von der Preisvolatilität und der Wahl des Stop-Loss-Niveaus ab. Für die Festlegung eines Stop-Loss können verschiedene Ansätze verwendet werden.