English Русский 中文 Español Português
preview
Entwicklung eines Replay-Systems (Teil 78): Neuer Chart Trade (V)

Entwicklung eines Replay-Systems (Teil 78): Neuer Chart Trade (V)

MetaTrader 5Beispiele |
35 0
Daniel Jose
Daniel Jose

Einführung

Im vorherigen Artikel „Entwicklung eines Replay Systems (Teil 77): Neuer Chart Trade (IV)“ habe ich das Thema so gründlich wie möglich erklärt, wobei ich versucht habe, die Dinge nicht zu sehr zu verkomplizieren, auch wenn es sich oft um ein recht komplexes Thema handelt. Die Frage, die sich stellt, ist: Wie entwickelt man ein Kommunikationsprotokoll? Dies ist unerlässlich, wenn Sie Informationen zwischen verschiedenen Anwendungen oder Programmen übertragen wollen, unabhängig davon, ob sie in derselben Umgebung laufen oder nicht. In unserem speziellen Fall möchten wir, dass der Indikator Chart Trade den Expert Advisor anweisen kann, welche Aktionen er durchführen soll. Mit anderen Worten: Wenn der Nutzer Chart Trade mitteilt, dass er verkaufen möchte, führt der Expert Advisor einen Verkaufsauftrag aus. Wenn der Nutzer angibt, dass er kaufen möchte, erteilt der Expert Advisor einen Marktkaufauftrag.

In den letzten Artikeln habe ich mich hauptsächlich darauf konzentriert, zu erklären, warum wir den Indikator Chart Trade erstellen sollten, und vor allem, wie man ein Nachrichtenprotokoll entwirft, bevor man versucht, etwas anderes zu programmieren. Bislang haben wir uns jedoch ausschließlich auf den Indikator konzentriert.

Diese Erklärung ist jedoch unvollständig, wenn man nicht zuerst die Empfängerseite betrachtet, die sich im Expert Advisor befindet. Dies liegt daran, dass MetaTrader 5 den Indikatoren ausdrücklich verbietet, Aufträge zu senden, Positionen zu verwalten oder direkt mit dem System zu interagieren, das für die Kommunikation mit dem Handelsserver zuständig ist. Mit anderen Worten: Indikatoren können keine Positionen oder Aufträge einleiten, schließen oder ändern.

Einige könnten argumentieren, dass hier ein Schlupfloch besteht. In Wirklichkeit ist es etwas ganz anderes. Darauf werden wir in künftigen Artikeln eingehen, wenn wir ein weiteres Instrument entwickeln, das sich als unverzichtbar erweisen wird. Im Moment befinden wir uns jedoch noch in der Anfangsphase des Aufbaus des Bestellsystems.

In diesem Moment ist unser Hauptanliegen ein anderes: zu verstehen, wie der Expert Advisor weiß, was passiert. Dies ist von entscheidender Bedeutung, da der Nutzer niemals direkt mit dem Expert Advisor interagieren wird. Stattdessen interagiert der Nutzer ausschließlich mit dem Indikator Chart Trade. Chart Trade muss seinerseits Anweisungen an den Expert Advisor übermitteln. Denn der Indikator allein ist nutzlos, wenn die Komponente, die für das Senden von Anfragen an den Markt zuständig ist – ob eine Position eröffnet oder geschlossen werden soll – nicht weiß, was passiert. Denken Sie daran: Nur der Expert Advisor hat die Berechtigung, diese Operationen in MetaTrader 5 auszuführen. Kein anderes Programm kann dies leisten.

Die zentrale Frage dieses Artikels lautet also: 


Wie versteht der Expert Advisor den Chart Trade?

Beginnen wir mit genau dieser Frage. Wenn Sie sich noch nicht sicher sind, wie das funktioniert, empfehle ich Ihnen, noch einmal den vorherigen Artikel zu lesen, in dem ich erklärt habe, wie man ein Nachrichtenprotokoll erstellt. Dieser Hintergrund ist wichtig, denn hier werden wir sehen, wie man die „Magie“ Wirklichkeit werden lässt. Weder der Indikator Chart Trade noch der Expert Advisor wissen von der Existenz des jeweils anderen. Und das müssen sie auch nicht. Es reicht, wenn beide darauf vertrauen, dass die Botschaft ankommt und verstanden wird. 

Auch wenn Sie nicht wissen, dass sich ein Expert Advisor auf dem Chart befindet, kann der Indikator Chart Trade ihm die Absichten des Nutzers mitteilen. Es ist faszinierend, diesen Prozess zu beobachten.

Noch wichtiger ist, dass Sie, sobald Sie diesen Mechanismus verstanden haben, in der Lage sein werden, vielseitigere Programme und Anwendungen für MetaTrader 5 zu entwickeln. Und dieses Wissen geht weit über MetaTrader 5 selbst hinaus.

Ja, lieber Leser. Diese Art des Nachrichtenaustauschs zwischen Programmen oder Prozessen ist auch in Betriebssystemen wie Windows, Linux und macOS weit verbreitet. Jedes moderne System beruht auf diesem Prinzip: Sie entwickeln mehrere kleinere Programme, die miteinander kommunizieren können. Auf diese Weise entsteht ein breites und nachhaltiges Ökosystem.

Jede Anwendung kann für die Ausführung einer bestimmten Aufgabe optimiert werden. Kombiniert man sie jedoch, kann man praktisch alles erreichen, und zwar zu weitaus geringeren Kosten in Bezug auf Implementierung, Wartung und Verbesserung.

Von diesem Punkt an möchte ich Sie ermutigen, sich von der Idee zu verabschieden, große, komplexe All-in-One-Anwendungen zu entwickeln, die nur schwer zu warten oder zu aktualisieren sind. Denken Sie stattdessen darüber nach, kleinere, einfachere Programme zu erstellen. Diese Einfachheit bringt Flexibilität mit sich und macht es einfacher, die Anwendung zu verbessern oder zu verfeinern. Für viele mag das neu sein. Aber glauben Sie mir, der größte Teil der Branche arbeitet auf diese Weise. Niemand baut mehr vollständig monolithische Systeme, denn das ist nicht nur teuer, sondern auch äußerst unpraktisch, vor allem wenn es darum geht, sie zu ändern oder zu verbessern.

Eine einfachere Anwendung ist viel leichter zu debuggen, anzupassen oder zu optimieren. Aus diesem Grund wird der Expert Advisor nur für das programmiert, was MetaTrader 5 von ihm verlangt: das Senden und Ändern von Aufträgen und Positionen. Alles andere wird an andere Programme und Anwendungen delegiert.

Um wirklich zu verstehen, wie der Expert Advisor den Chart Trade interpretiert, beginnen wir mit der Erstellung eines sehr einfachen Stücks Code. Und ich meine wirklich einfach. In diesem Stadium werden wir noch keine Aufträge senden, Positionen schließen oder Geschäfte rückgängig machen – noch nicht. Dies jetzt zu tun, würde die Sache nur unnötig verkomplizieren.

Wir brauchen ein möglichst einfaches Beispiel, damit Sie verstehen können, wie die Empfängerseite funktioniert. So können Sie besser verstehen, wie das Nachrichtenprotokoll es dem Indikator Chart Trade (der nichts von der Existenz des Expert Advisors weiß) ermöglicht, Aktionen in ihm auszulösen.

Gleichzeitig kann der Expert Advisor, der ebenfalls keine Kenntnis vom Chart Trade hat, dennoch auf Nutzeranfragen reagieren. Denken Sie daran: Der Nutzer interagiert nie direkt mit dem Expert Advisor.

Der einfachste Code, um dies zu erreichen, ist unten zu finden. Sie wird in vollem Umfang vorgelegt.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. #property description "Demo version between interaction"
04. #property description "of Chart Trade and Expert Advisor"
05. #property version   "1.78"
06. #property link "https://www.mql5.com/pt/articles/11760"
07. //+------------------------------------------------------------------+
08. #include <Market Replay\Defines.mqh>
09. //+------------------------------------------------------------------+
10. class C_Decode
11. {
12.    private   :
13.       struct stInfoEvent
14.       {
15.          EnumEvents ev;
16.          string     szSymbol;
17.          bool       IsDayTrade;
18.          ushort     Leverange;
19.          double     PointsTake,
20.                     PointsStop;
21.       }info[1];
22.    public   :
23. //+------------------------------------------------------------------+
24.       C_Decode()
25.          {
26.             info[0].szSymbol = _Symbol;
27.          }
28. //+------------------------------------------------------------------+   
29.       bool Decode(const int id, const string sparam)
30.       {
31.          string Res[];
32.       
33.          if (StringSplit(sparam, '?', Res) != 6) return false;
34.          stInfoEvent loc = {(EnumEvents) StringToInteger(Res[0]), Res[1], (bool)(Res[2] == "D"), (ushort) StringToInteger(Res[3]), StringToDouble(Res[4]), StringToDouble(Res[5])};
35.          if ((id == loc.ev) && (loc.szSymbol == info[0].szSymbol)) info[0] = loc;
36.          
37.          ArrayPrint(info, 2);
38.       
39.          return true;
40.       }
41. //+------------------------------------------------------------------+   
42. }*GL_Decode;
43. //+------------------------------------------------------------------+
44. int OnInit()
45. {
46.    GL_Decode = new C_Decode;
47.    
48.    return INIT_SUCCEEDED;
49. }
50. //+------------------------------------------------------------------+
51. void OnTick() {}
52. //+------------------------------------------------------------------+
53. void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
54. {
55.    switch (id)
56.    {
57.       case CHARTEVENT_CUSTOM + evChartTradeBuy     :
58.       case CHARTEVENT_CUSTOM + evChartTradeSell    :
59.       case CHARTEVENT_CUSTOM + evChartTradeCloseAll:
60.          (*GL_Decode).Decode(id - CHARTEVENT_CUSTOM, sparam);
61.          break;
62.    }
63. }
64. //+------------------------------------------------------------------+
65. void OnDeinit(const int reason)
66. {
67.    delete GL_Decode;
68. }
69. //+------------------------------------------------------------------+

Quellcode des Expert Advisors

Sie wollen mir weismachen, dass der obige Code einfach ist? Ehrlich gesagt, verstehe ich das nicht. Für mich sieht das sehr kompliziert aus. Ich kann kaum etwas verstehen. Ich fühle mich hier völlig verloren. Wenn Sie das als einfach bezeichnen, dann kann ich mir nur vorstellen, wie etwas Kompliziertes aussehen muss! Ja, dieser Code ist wirklich recht einfach. Aber sie verwendet bestimmte Elemente, die viele von Ihnen normalerweise nicht kennen. Oder, genauer gesagt, Dinge, von denen viele von Ihnen nicht einmal wissen, dass sie in MQL5 möglich sind. Wenn das bei Ihnen der Fall ist und wenn Sie wirklich vorhaben, in Zukunft ein professioneller Programmierer zu werden, dann bleiben Sie bei mir. Folgen Sie den Erklärungen, die ich gleich geben werde, denn die Dinge sind in der Tat viel einfacher, als es den Anschein hat: Der Code ist einfach und sehr direkt, um genau das zu erreichen, was er tun muss.

Und das Wissen, das ich Ihnen nun vermitteln werde, wird Ihnen helfen, langsamer zu werden, klarer zu denken und Probleme gelassener anzugehen. Es dient auch als Erinnerung daran, dass Programmieren Spaß machen kann – und sollte. Wenn Sie es nur als langweilige, schwierige oder übermäßig komplizierte Arbeit ansehen, sollten Sie vielleicht etwas ganz anderes machen. Vergessen Sie das Programmieren oder Entwickeln. Denn wenn Sie programmieren, sollten Sie sich wirklich wie ein Kind im Süßwarenladen fühlen – nie ganz sicher, welche Süßigkeit Sie zuerst nehmen werden.

Aber genug der Abschweifung. Schauen wir uns an, wie dieser Code tatsächlich funktioniert. Die ersten sieben Zeilen sollten für niemanden ein Problem darstellen. Selbst Anfänger sollten ihnen leicht folgen können. Die achte Zeile ist jedoch eine vertraute Zeile. Hier binden wir eine Datei in unseren Code ein. Diese Datei ist ein Header, der Definitionen enthält, die wir bald brauchen werden. Überspringen wir zunächst den Code zwischen den Zeilen 10 und 42. Wir werden sie nämlich später noch einmal genau durchgehen. Zunächst müssen wir auf einige kleine, aber wichtige Details eingehen.

Damit sind wir bei der ersten wirklich wichtigen Funktion in unserem Code angelangt. Es ist OnInit, das in Zeile 44 beginnt. Aufgrund dessen, was in Zeile 42 passiert, könnten die Dinge ein wenig anders laufen, als viele erwarten würden. In Zeile 46 verwenden wir den Operator new, um Speicher zuzuweisen und die Klasse C_Decode zu initialisieren. Warum wird der Speicher auf diese Weise zugewiesen? Wäre es nicht einfacher, dies einfach dem Compiler zu überlassen? Ja, es wäre einfacher. Aber als Programmierer müssen Sie lernen zu kontrollieren, wann und wo eine Klasse verwendet wird. Wenn Sie dies dem Compiler überlassen, kann es passieren, dass Sie die Klasse mit Werten verwenden, die Sie nicht erwartet haben.

Glauben Sie mir, das ist keine Seltenheit. Besonders in großen Codebasen, in denen Klassen an mehreren Stellen deklariert werden, ist Verwirrung vorprogrammiert. Irgendwann werden sich die Dinge verheddern. Durch die explizite Verwendung von new und delete haben Sie die volle Kontrolle darüber, wo Ihr Code beginnt und endet. Viele Programmieranfänger tun sich mit diesem Konzept schwer. So seltsam es klingen mag, aber manche können nicht klar erkennen, wo ihr Code endet oder wo er beginnt. Aber es passiert.

Wenn also Zeile 46 ausgeführt wird, wird Speicher für die Klasse C_Decode zugewiesen und gleichzeitig wird Zeile 24 aufgerufen. Diese Zeile ist der Konstruktor der Klasse C_Decode. In diesem Konstruktor wird nur eine Variable initialisiert. Es handelt sich dabei um den Symbolnamen, oder anders gesagt, den Namen des Vermögenswerts, auf dem der Expert Advisor läuft. Passen Sie gut auf: In diesem Modell sind auftragsübergreifende Berechtigungen nicht aktiviert. Zu diesem Zeitpunkt ist Ihnen das vielleicht noch nicht ganz klar. Aber lesen Sie weiter – Sie werden bald verstehen, warum auftragsübergreifende Operationen hier nicht erlaubt sind. Mit ein paar kleinen Änderungen (und die sind wirklich einfach) könnten Kreuzaufträge ermöglicht werden. Aber machen Sie sich darüber keine Sorgen. Denken Sie daran: Dieser Code dient nur zur Demonstration der Funktionsweise des Nachrichtenprotokolls. Es ist nicht dazu gedacht, tatsächlich Anfragen an den Handelsserver zu senden.

Zurück zur Funktion OnInit. Nach der Ausführung von Zeile 46 gibt Zeile 48 einen Wert zurück, der anzeigt, dass die Initialisierung erfolgreich war. Dies ist wichtig. Denn wenn der Rückgabewert nicht INIT_SUCCEEDED ist, wird MetaTrader 5 automatisch Schritte zur Deaktivierung des Expert Advisors unternehmen. Einer dieser Schritte ist das Auslösen des Deinit-Ereignisses, das die OnDeinit-Prozedur in Ihrem Expert Advisor-Code aufruft.

Wenn Ihr Code diese Prozedur nicht enthält, greift MetaTrader 5 auf Standardmaßnahmen zurück. In beiden Fällen wird Ihre Anwendung keine CPU-Zeit mehr erhalten. Mit anderen Worten: Sie wird nicht zur Ausführung vorgesehen.

Und alle Informationen, die auf dem Chart verbleiben und zur Anwendung gehören, werden ignoriert. Es ist üblich, dass Anwendungen Objekte auf dem Chart erstellen und platzieren. Aber wenn MetaTrader 5 Deinit auslöst und Ihr Code diese Objekte nicht entfernt. Sie bleiben auf dem Chart. Oft werden dabei irreführenderweise falsche oder ungültige Daten angezeigt.

Aus diesem Grund ist es eine gute Praxis, immer die OnDeinit-Prozedur zu implementieren. Oft wird sie nur sehr wenig bewirken. In unserem Fall enthält er jedoch eine wichtige Zeile: Zeile 67. Hier verwenden wir den Operator delete, um den zugewiesenen Speicher freizugeben. An diesem Punkt wird der Destruktor von C_Decode aufgerufen. Da wir nicht explizit einen Destruktor deklariert haben, stellt der Compiler automatisch einen bereit, wenn delete verwendet wird. Denn der Operator delete erfordert einen Destruktor. Darüber brauchen Sie sich keine Sorgen zu machen. Aber es lohnt sich zu wissen, wie es unter der Haube funktioniert.

Nun, da wir uns damit beschäftigt haben, wo der Code des Expert Advisors beginnt und wo er endet, können wir weitermachen. In Zeile 51 finden wir die Prozedur, die bei jedem Tick, den die Anlage erhält, aufgerufen wird. Dieses Verfahren ist in jedem Expert Advisor obligatorisch. Sie sollten jedoch vermeiden, zu viel Logik darin unterzubringen. Die Gründe dafür werden in der Artikelserie zum Aufbau eines vollautomatischen Expert Advisors erläutert. Wenn Sie daran interessiert sind, einen EA mit einem gewissen Grad an Automatisierung zu erstellen, empfehle ich Ihnen dringend, diese Serie zu lesen.

Es besteht aus 15 Artikeln, beginnend mit „Erstellen eines EA, der automatisch funktioniert (Teil 01): Konzepte und Strukturen“. Die Lektüre dieser Serie wird Ihnen sehr helfen. In dieser Replay-/Simulationsreihe werden wir sogar einige Konzepte aus der automatisierten EA-Reihe wiederverwenden. Wie auch immer, lassen Sie es nicht ausfallen.

Jetzt geht es weiter: Das andere wichtige Verfahren erscheint in Zeile 53. Es handelt sich um OnChartEvent. Und hier beginnen die Dinge wirklich interessant zu werden. Der Übersichtlichkeit halber werden wir dies jedoch im nächsten Abschnitt untersuchen.


Entschlüsseln einer Nachricht aus einem Ereignis

In früheren Artikeln dieser Replay/Simulator-Serie habe ich erklärt, wie EventChartCustom und OnChartEvent miteinander verbunden sind. Wir haben diese Verbindung intensiv genutzt, damit der Replay/Simulator-Dienst Daten an den Kontrollindikator senden kann. Dies ist erforderlich, damit der Indikator genau weiß, wo wir uns in der Simulation oder Wiedergabe befinden. Wenn Sie diese Artikel noch nicht gelesen haben (und gerade an diesem Punkt der Serie angekommen sind), empfehle ich Ihnen, sie noch einmal durchzulesen.

Ein Beispiel ist Entwicklung eines Replay Systems (Teil 60): Abspielen des Dienstes (I). Es gibt sieben Artikel zu diesem Thema. Wenn Sie sie alle lesen, werden Sie nicht nur die technischen Details verstehen, sondern auch, warum dieser Ansatz sinnvoll ist.

Damals kommunizierte der Dienst mit dem Kontrollgerät über numerische Parameter. Das war der einfache Teil, da die Informationen in Parametern wie lparam oder dparam leicht verfügbar waren. Aber hier sind die Dinge anders. Dieses Mal verwenden wir den Parameter sparam. Mit anderen Worten: Die Nachricht ist jetzt eine Zeichenkette. Und in dieser Zeichenfolge befinden sich die Informationen, die wir brauchen. Der Haken ist, dass die Informationen verschlüsselt sind. Die Art der Kodierung wird durch das Nachrichtenprotokoll festgelegt. Ich habe dieses Konzept im vorherigen Artikel erläutert. Hier konzentrieren wir uns auf die Dekodierung dieser Nachricht gemäß dem Protokoll.

Im letzten Artikel habe ich erwähnt, dass die Nachricht das Ereignis selbst enthalten würde. Dies ist wichtig, weil es dem Empfänger – in unserem Fall dem Expert Advisor – ermöglicht, zu überprüfen, ob die Nachricht verfälscht wurde oder nicht.

Da für alle drei anerkannten Ereignistypen das gleiche Protokoll verwendet wird, können sie alle einheitlich behandelt werden. In den Zeilen 57-59 sehen Sie diese drei Ereignisse, die der Expert Advisor abfangen muss. Und da sie alle denselben Dekodierungsprozess durchlaufen können, ist die einzige wirklich relevante Zeile die Zeile 60. Diese Zeile ruft den Code auf, der in Zeile 29 beginnt. Passen Sie jetzt sehr gut auf. Wenn Sie diese Erklärung nicht auf Anhieb verstehen, lesen Sie sie noch einmal, denn sie ist zwar ungewöhnlich, aber äußerst wichtig.

In Zeile 31 deklarieren wir eine lokale Variable: ein dynamisches Array. Da es sich um ein dynamisches Programm handelt, kümmert sich das Programm selbst um die Speicherzuweisung. Wir brauchen uns also keine Sorgen zu machen. Dann, in Zeile 33, rufen wir StringSplit auf. Es füllt das Array mit Teilzeichenfolgen, die durch ein bestimmtes Zeichen getrennt sind. In unserem Fall ist dieses Zeichen ein Fragezeichen (?). Warum gerade diese Wahl?

Ich habe dies im letzten Artikel erläutert. Das Fragezeichen wurde als Begrenzungszeichen für die Gruppierung der Werte gewählt. Bei der Aufteilung erwarten wir, dass wir eine feste Anzahl von Teilstrings erhalten. Wenn die Nachricht gültig ist (oder zumindest minimal gültig), sollten wir sechs Zeichenfolgen erhalten. Wenn StringSplit mehr oder weniger zurückgibt, schlägt der Test fehl und wir geben false zurück. Wenn genau sechs zurückgegeben werden, fahren wir fort.

In Zeile 34 wird es dann richtig interessant. Es ist kein gewöhnlicher Code, aber er ist auch nicht fremd. Um sie zu verstehen, müssen Sie sie neben der in Zeile 13 deklarierten Struktur sehen. Passen Sie hier gut auf. Jedes Element in Zeile 34 entspricht direkt einem Feld in der Struktur stInfoEvent. Was ich hier getan habe, geschah mit Absicht. Achten Sie auf die Reihenfolge der in stInfoEvent deklarierten Variablen. Das ist sehr wichtig. Achten Sie nun auf die Reihenfolge der Werte in Zeile 34. Wow! Sie passen zusammen! Das Ergebnis ist gleichbedeutend mit dem Schreiben dieses expliziteren Codes:

      stInfoEvent loc;
          
      loc.ev = (EnumEvents) StringToInteger(Res[0]);
      loc.szSymbol = Res[1];
      loc.IsDayTrade = (Res[2] == "D");
      loc.Leverange = (ushort) StringToInteger(Res[3]);
      loc.PointsTake = StringToDouble(Res[4]);
      loc.PointsStop = StringToDouble(Res[5]);

Codefragment – Modell 01

Die beiden Ansätze sind funktionell identisch. Es gibt jedoch einen wichtigen Vorbehalt: Die Linie 34 birgt ein Risiko. Dieses Risiko wird in der obigen Codeversion vermieden. Dieses Risiko besteht, wenn Sie die Struktur stInfoEvent ändern. Warum? Das Ändern der Struktur stInfoEvent ist ein Problem, wenn Sie Code wie in Zeile 34 schreiben, aber nicht, wenn Sie Code wie im Codefragment zeigen.

Der Grund dafür ist ganz einfach. Das mag albern klingen, aber es verursacht eine Menge Kopfschmerzen und stundenlange Versuche, herauszufinden, warum alles schief läuft. Nehmen wir an, Sie beschließen, die in den Zeilen 19 und 20 deklarierten Variablen zu vertauschen. Mit der obigen expliziten Version geht nichts kaputt – die Zuweisungen sind immer noch korrekt.

Doch mit der kompakten Zuordnung der Zeile 34 verschiebt sich alles. Was eigentlich PointsTake zugewiesen werden sollte, landet in PointsStop und umgekehrt. Das klingt nach Unsinn. Das ist kein Scherz. Das passiert wirklich.

Es hat damit zu tun, wie der Compiler die Variablen im Speicher organisiert. Es ist das gleiche Prinzip, das manchmal absichtlich in der alten C-Programmierung verwendet wird. Entwickler manipulieren Speicherlayouts direkt, um bestimmte Verhaltensweisen zu erzwingen. Aber das würde den Rahmen dieses Artikels bei weitem sprengen.

Die Schlussfolgerung ist einfach: Verwenden Sie den kompakten Zuweisungsstil erst dann, wenn Ihre Struktur vollständig definiert und fertiggestellt ist. Und wenn er einmal fertig ist, darf er nicht mehr geändert werden. Wenn Sie dies tun, müssen Sie jede Aufgabe, die im kompakten Stil geschrieben ist (z. B. Zeile 34), überarbeiten und anpassen. Um dies zu sehen, verwenden Sie diesen Code, um das System zu testen, indem Sie einfach Zeile 34 oder die Reihenfolge der Variablendeklarationen in der stInfoEvent-Struktur ändern.

Kommen wir auf den Code zurück. In Zeile 35 wird geprüft, ob die Daten mit den erwarteten Werten übereinstimmen – sowohl der Name der Anlage als auch der Ereignistyp. Wenn ja, ordnen wir die Werte einem statischen Array zu. HINWEIS: Diese Aufgabe ist nur zu Test- und Demonstrationszwecken gedacht. Im Moment brauchen wir nur stInfoEvent in einem Array zu platzieren. Der Grund ist Zeile 37. In dieser Zeile verwenden wir die MQL5-Funktion ArrayPrint. Diese Funktion zeigt den Inhalt des Arrays im Terminal an. Ein solches Ergebnis ist in der nachstehenden Abbildung dargestellt.

Bild


Schlussfolgerung

Wie in diesem Artikel erläutert, ist der Expert Advisor noch nicht in der Lage, Anfragen an den Handelsserver zu senden. Das ist gewollt. Bevor Sie dies tun, müssen Sie verstehen, wie der Code funktioniert – und, was noch wichtiger ist, wie das Kommunikationsprotokoll zwischen Chart Trade und dem Expert Advisor funktioniert. Ohne diese Grundlage laufen Sie Gefahr, ernsthafte Probleme zu bekommen.

Dennoch hat diese Art der Darstellung ihre Vorteile. Auf diesem Weg konnte ich ein Konzept erklären, das Ihnen vielleicht in Zukunft begegnen wird und von dem Sie nicht sofort verstehen, warum es funktioniert (oder auch nicht). Auf jeden Fall haben wir jetzt die Bausteine für das, was als Nächstes kommt, beisammen. Im folgenden Video können Sie sehen, wie sich das System in der Praxis verhält. Also, bis zum nächsten Artikel, in dem die Dinge noch interessanter werden.


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

Beigefügte Dateien |
Anexo.zip (420.65 KB)
Von der Grundstufe bis zur Mittelstufe: Template und Typenname (III) Von der Grundstufe bis zur Mittelstufe: Template und Typenname (III)
In diesem Artikel werden wir den ersten Teil des Themas behandeln, der für Anfänger nicht so leicht zu verstehen ist. Um nicht noch mehr Verwirrung zu stiften und dieses Thema richtig zu erklären, werden wir die Erklärung in Etappen unterteilen. Dieser Artikel ist der ersten Phase gewidmet. Auch wenn es am Ende des Artikels so aussehen mag, als hätten wir eine Sackgasse erreicht, werden wir in Wirklichkeit einen Schritt in Richtung einer anderen Situation machen, die im nächsten Artikel besser verstanden wird.
Von der Grundstufe bis zur Mittelstufe: Definitionen (II) Von der Grundstufe bis zur Mittelstufe: Definitionen (II)
In diesem Artikel werden wir unsere Kenntnisse über die Direktive #define fortsetzen, aber dieses Mal werden wir uns auf ihre zweite Form der Verwendung konzentrieren, nämlich die Erstellung von Makros. Da dieses Thema etwas kompliziert sein kann, haben wir uns für eine Anwendung entschieden, mit der wir uns schon seit einiger Zeit beschäftigen. Ich wünsche Ihnen viel Spaß mit dem heutigen Artikel.
Marktsimulation (Teil 01): Kreuzaufträge (I) Marktsimulation (Teil 01): Kreuzaufträge (I)
Heute beginnen wir mit der zweiten Phase, in der wir uns mit dem Replay-/Simulationssystem beschäftigen werden. Zunächst zeigen wir eine mögliche Lösung für Kreuzaufträge. Ich werde Ihnen die Lösung zeigen, aber sie ist noch nicht endgültig. Es wird eine mögliche Lösung für ein Problem sein, das wir in naher Zukunft lösen müssen.
Entwicklung eines Replay-Systems (Teil 77): Neuer Chart Trade (IV) Entwicklung eines Replay-Systems (Teil 77): Neuer Chart Trade (IV)
In diesem Artikel werden wir einige der Maßnahmen und Vorsichtsmaßnahmen behandeln, die bei der Erstellung eines Kommunikationsprotokolls zu beachten sind. Dies sind recht einfache und unkomplizierte Dinge, sodass wir in diesem Artikel nicht zu sehr ins Detail gehen werden. Aber um zu verstehen, was passieren wird, müssen Sie den Inhalt des Artikels verstehen.