English Русский 中文 Español 日本語 Português
preview
Entwicklung eines Replay System (Teil 57): Verstehen eines Testdienstes

Entwicklung eines Replay System (Teil 57): Verstehen eines Testdienstes

MetaTrader 5Beispiele | 12 Februar 2025, 09:26
114 0
Daniel Jose
Daniel Jose

Einführung

Im vorherigen Artikel Entwicklung eines Replay Systems (Teil 56): Anpassen der Module, haben wir einige Änderungen am Kontrollanzeigemodul und vor allem am Mausanzeigemodul vorgenommen.

Da der Artikel bereits viele Informationen enthielt, habe ich beschlossen, keine weiteren neuen Daten hinzuzufügen, da sie Sie, liebe Leserin, lieber Leser, wahrscheinlich nur verwirren würden, anstatt zur Klärung und Erklärung der tatsächlichen Funktionsweise beizutragen.

Der Anhang zum vorigen Artikel enthält die Mausanzeige und den Dienst. Wenn Sie den Dienst ausführen, erstellt er ein nutzerdefiniertes Symbol und fügt ein Feld mit einer Mausanzeige und einer Kontrollanzeige hinzu. Beide Module sind auf dem nutzerdefinierten Symboldiagramm platziert, und obwohl sie keine dienstbezogenen Aktionen durchführen, ist eine gewisse Interaktionsaktivität zwischen dem Nutzer und diesen beiden Modulen zu erkennen.

Sie haben vielleicht keine Ahnung, wie das geht, vor allem, wenn Sie neu in MQL5 sind. Wenn Sie sich den Code dieser beiden Indikatoren ansehen, können Sie keine Aktivität erkennen, die den Verlust von Daten im Indikator oder genauer gesagt im Kontrollmodul verhindern würde.

In diesem Artikel soll daher vor allem erklärt werden, wie der Dienst tatsächlich funktioniert. Diese Erläuterung ist von größter Bedeutung, da ein richtiges Verständnis der Funktionsweise des Dienstes für das Verständnis der Funktionsweise des Wiedergabe-/Simulatorsystems unerlässlich ist. Das liegt daran, dass es immer einfacher ist, einen Code mit weniger Komponenten zu erstellen und zu erklären, als zu versuchen, einen Code mit einer viel komplexeren Struktur auf Anhieb zu verstehen.

Auch wenn wir den Code, der im Folgenden erläutert wird, nicht wirklich verwenden werden, ist es sehr wichtig, ihn im Detail zu verstehen. Das Zusammenspiel von Steuermodul, Mausmodul und Dienst lässt sich viel besser verstehen, wenn man diesen einfacheren Code gut kennt.

Werfen wir also kurzerhand einen Blick auf den Quellcode des Dienstes, der im vorherigen Artikel implementiert und gezeigt wurde. Versuchen wir, das Video zu verstehen, das am Ende des Artikels zu sehen ist.


Analysieren wir den Code des Dienstes

Der gesamte Quellcode des Dienstes lautet wie folgt:

01. //+------------------------------------------------------------------+
02. #property service
03. #property copyright "Daniel Jose"
04. #property description "Data synchronization demo service."
05. #property link "https://www.mql5.com/en/articles/12000"
06. #property version   "1.00"
07. //+------------------------------------------------------------------+
08. #include <Market Replay\Defines.mqh>
09. //+------------------------------------------------------------------+
10. #define def_IndicatorControl   "Indicators\\Market Replay.ex5"
11. #resource "\\" + def_IndicatorControl
12. //+------------------------------------------------------------------+
13. #define def_Loop ((!_StopFlag) && (ChartSymbol(id) != ""))
14. //+------------------------------------------------------------------+
15. void OnStart()
16. {
17.    uCast_Double info;
18.    long id;
19.    int handle;
20.    short iPos, iMode;
21.    double Buff[];
22.    MqlRates Rate[1];
23.    
24.    SymbolSelect(def_SymbolReplay, false);
25.    CustomSymbolDelete(def_SymbolReplay);
26.    CustomSymbolCreate(def_SymbolReplay, StringFormat("Custom\\%s", def_SymbolReplay));
27.    CustomSymbolSetDouble(def_SymbolReplay, SYMBOL_TRADE_TICK_SIZE, 0.5);
28.    CustomSymbolSetDouble(def_SymbolReplay, SYMBOL_TRADE_TICK_VALUE, 5);
29.    Rate[0].close = 110;
30.    Rate[0].open = 100;
31.    Rate[0].high = 120;
32.    Rate[0].low = 90;
33.    Rate[0].tick_volume = 5;
34.    Rate[0].time = D'06.01.2023 09:00';
35.    CustomRatesUpdate(def_SymbolReplay, Rate, 1);
36.    SymbolSelect(def_SymbolReplay, true);
37.    id = ChartOpen(def_SymbolReplay, PERIOD_M30);   
38.    if ((handle = iCustom(ChartSymbol(id), ChartPeriod(id), "\\Indicators\\Mouse Study.ex5", id)) != INVALID_HANDLE)
39.       ChartIndicatorAdd(id, 0, handle);
40.    IndicatorRelease(handle);      
41.    if ((handle = iCustom(ChartSymbol(id), ChartPeriod(id), "::" + def_IndicatorControl, id)) != INVALID_HANDLE)
42.       ChartIndicatorAdd(id, 0, handle);
43.    IndicatorRelease(handle);   
44.    Print("Service maintaining sync state. Version Demo...");
45.    iPos = 0;
46.    iMode = SHORT_MIN;
47.    while (def_Loop)
48.    {
49.       while (def_Loop && ((handle = ChartIndicatorGet(id, 0, "Market Replay Control")) == INVALID_HANDLE)) Sleep(50);
50.       info.dValue = 0;
51.       if (CopyBuffer(handle, 0, 0, 1, Buff) == 1) info.dValue = Buff[0];
52.       IndicatorRelease(handle);
53.       if ((short)(info._16b[0]) == SHORT_MIN)
54.       {
55.          info._16b[0] = (ushort)iPos;
56.          info._16b[1] = (ushort)iMode;
57.          EventChartCustom(id, evCtrlReplayInit, 0, info.dValue, "");
58.       }else if (info._16b[1] != 0)
59.       {
60.          iPos = (short)info._16b[0];
61.          iMode = (short)info._16b[1];
62.       }
63.       Sleep(250);
64.    }
65.    ChartClose(id);
66.    SymbolSelect(def_SymbolReplay, false);
67.    CustomSymbolDelete(def_SymbolReplay);
68.    Print("Finished service...");   
69. }
70. //+------------------------------------------------------------------+

Quellcode des Dienstes für Tests

Um sicherzustellen, dass jeder wirklich versteht, was vor sich geht, auch diejenigen, die nicht viel Erfahrung mit MQL haben, und vor allem diejenigen, die noch nicht sehr vertraut damit sind, wie man Dienste für MetaTrader 5 programmiert, lassen Sie uns einen genaueren Blick auf den Code werfen, beginnend mit Zeile 2.

Wenn Sie auf eine Eigenschaft stoßen, die in der zweiten Zeile im MQL5-Code deklariert ist, sollten Sie verstehen, dass es sich um einen Dienst handelt. Würde diese Eigenschaft fehlen, müsste der Code wie ein Skript behandelt werden. Die Hauptunterschiede zwischen einem Dienst und einem Skript sind vor allem das Vorhandensein oder Fehlen dieser Eigenschaft im Code. Bei der Ausführung besteht der Hauptunterschied darin, dass das Skript immer mit einem Chart verknüpft ist, während der Dienst von keinem Chart abhängig ist.

Die übrigen Zeilen zwischen 3 und 6 sind all jenen bekannt, die zumindest minimale Kenntnisse der MQL5-Programmierung haben. Wir können also ihre Beschreibung überspringen.

In Zeile 8 haben wir die include-Direktive hinzugefügt, um die Header-Datei in diesen Code einzubinden. Beachten Sie, dass sich die Header-Datei in diesem Fall im Ordner „Include“ innerhalb des Ordners „Market Replay“ befindet und den Namen „Defines.mqh“ trägt. Der „Include“-Ordner befindet sich im Stammverzeichnis des MQL5-Hauptverzeichnisses, auf das MetaEditor während der Kompilierung verweist.

Nun müssen wir den Zeilen 10 und 11 besondere Aufmerksamkeit widmen. Diese Zeilen sorgen dafür, dass der Indikator bzw. das Steuermodul eine interne Ressource des kompilierten Dienstcodes wird. Was bedeutet das? Das bedeutet, dass Sie bei der Migration von bereits kompiliertem Code nicht auch den Code des Kontrollmoduls migrieren müssen, da dieser bereits als Dienstressource eingebettet ist. Aus diesem Grund enthielt der Anhang des vorigen Artikels nur zwei ausführbare Dateien, obwohl zum Zeitpunkt des Starts des Dienstes tatsächlich drei Dateien ausgeführt wurden.

Aber warum haben wir nicht auch den Indikator bzw. das Mausmodul als Service-Ressource eingebunden, so wie wir es mit dem Kontrollmodul getan haben? Der Grund dafür ist einfach: Der Nutzer soll das Mausmodul verwenden können und es soll leichter zugänglich sein. Wäre dieses Modul in die ausführbare Datei des Dienstes eingebettet, wäre es für den Nutzer schwierig, auf das Mausmodul zuzugreifen, um es auf einem anderen als dem vom Dienst erstellten Chart zu platzieren.

Aus diesem Grund müssen wir oft Entscheidungen darüber treffen, welche Elemente, und vor allem warum, zu internen Ressourcen einer bestimmten ausführbaren Datei gemacht werden sollen.

Sehen Sie sich als nächstes Zeile 13 an. In dieser Zeile deklarieren wir eine Definition, um einige der Tests, die wir durchführen werden, zu vereinfachen oder besser noch zu standardisieren. In komplexen Programmen kommt es häufig vor, dass die gleiche Art von Test an verschiedenen Stellen durchgeführt wird. Die Erstellung einer Definition zur Standardisierung solcher Tests macht den Code nicht nur einfacher und leichter wartbar, sondern stellt auch sicher, dass wir immer die gleiche Art von Tests durchführen. In vielen Fällen ist dies für die meisten Programmierer höchst wünschenswert, da es möglich ist, dass man vergisst, einige Testpunkte zu ändern, und der Code dann aus irgendeinem Grund einen bestimmten Test gut durchführt, aber an anderen Stellen versagt. Dies verursacht in der Regel eine Menge Kopfschmerzen.

Also gut. In Zeile 15 kommen wir in den ausführbaren Teil des Codes. Beachten Sie, dass OnStart der gleiche Einstiegspunkt für Skripte und Dienste im MQL5-Code ist. Aus der Erklärung in Zeile 2 wissen wir jedoch, dass es sich um einen Dienst handelt. MetaTrader 5 erzeugt bei jeder Ausführung des Codes nur einen OnStart-Ereignisaufruf, sodass einige Manöver erforderlich sind, um sicherzustellen, dass der Code für die erforderliche Zeitspanne ausgeführt wird. Dies geschieht nur in einem bestimmten Fall, der in Zeile 47 zu finden sein wird. Aber zuerst müssen wir noch ein paar Dinge erledigen.

Das heißt, wir müssen den Dienst initialisieren und anpassen, damit er etwas Nützliches für uns tun kann. Zu den notwendigen Schritten gehört die Deklaration und Initialisierung von Variablen und Bedingungen, die von unserem Dienst im MetaTrader 5 auferlegt werden. All dies wird nach der Einführung des Dienstes geschehen. In diesem Sinne deklarieren wir in den Zeilen 17 bis 22 die Variablen, die wir verwenden werden, und fahren mit der richtigen Initialisierung der erforderlichen Regeln fort. Vieles von dem, was ab jetzt besprochen wird, mag seltsam erscheinen.

Dies sind scheinbar einfache Dinge, die ursprünglich Teil einer anderen Art von Anwendung sein könnten, aber da wir alles in einem einzigen Code zentralisieren wollen, müssen wir so arbeiten.

In Zeile 24 teilen wir MetaTrader 5 also mit, dass das Symbol, auf das wir uns beziehen, aus dem Fenster Market Watch entfernt werden soll. Unmittelbar danach, in Zeile 25, wird es aus der Liste der Symbole entfernt. Diese Liste enthält alle Symbole, auf die wir zugreifen können. Aber was uns wirklich interessiert, ist Zeile 26. In dieser Zeile teilen wir MetaTrader 5 mit, dass wir ein nutzerdefiniertes Symbol erstellen möchten und geben an, wo es erstellt werden soll. Sie sollten darauf achten, denn wenn Sie nicht aufpassen, können Sie bei dieser Aktion das Marktsymbol überschreiben und später, während Sie versuchen, auf das echte Instrument zuzugreifen, auf ein nutzerdefiniertes zugreifen. Aber normalerweise treffen wir immer einige Vorsichtsmaßnahmen, um dies zu verhindern.

Die Zeilen 26 und 27 sind obligatorisch; ohne sie wäre das Mausmodul nicht in der Lage, die Preislinie an die richtige Position zu setzen, wenn Sie die Maus über das Chart bewegen.

Zwischen den Zeilen 29 und 34 definieren wir den Balken, der als erster Balken im Chart zu sehen sein wird. Aus Gründen, die ich nicht ganz verstehe, ist dieser Balken immer so positioniert, dass Sie die Höchst- und Tiefstwerte nicht sehen können. Da unser Ziel jedoch darin besteht, den Balken im Chart anzuzeigen und zu verhindern, dass die Module Bereichsfehler erzeugen, ist es uns egal, ob der gesamte Balken sichtbar ist oder nicht.

Bis zu diesem Punkt haben wir absolut nichts auf dem Chart, nicht einmal die Chart selbst. In Zeile 35 teilen wir MetaTrader 5 mit, dass die in den vorangegangenen Zeilen definierten Werte, in denen wir den Balken beschreiben, als erster Balken des von uns erstellten Assets platziert werden sollen. In Zeile 36 teilen wir der Plattform mit, dass der Vermögenswert im Marktbeobachtungsfenster platziert werden soll. Würde der Code an dieser Stelle enden, könnten wir das nutzerdefinierte Symbol manuell öffnen und den darin befindlichen Balken anzeigen. Da wir aber noch mehr Automatisierung wollen, haben wir die Linie 37.

Im Moment der Ausführung von Zeile 37 öffnet MetaTrader 5 einen Chart mit dem angegebenen Symbol und Zeitrahmen. An einer Stelle in dieser Serie habe ich bereits den Grund für die Information der Module über die Chart-ID erläutert. Es ist sehr wichtig, daran zu denken, dass wir jetzt ein Chart geöffnet haben, und da wir nicht angeben, welche Vorlage verwendet werden soll, wird das Chart mit der Standardvorlage geöffnet. Dieser Gedanke ist notwendig, um die folgenden Zeilen zu verstehen.

Beginnen wir damit: Beachten Sie, dass wir in Zeile 38 versuchen, ein Handle zu erzeugen, um das Mausmodul auf dem Chart zu platzieren. Beachten Sie insbesondere den Speicherort und den Namen der angegebenen ausführbaren Datei. Wenn der Versuch, ein Handle zu erstellen, aus irgendeinem Grund fehlschlägt, wird Zeile 39 nicht ausgeführt. In der Regel liegt es daran, dass sich die ausführbare Datei nicht an dem angegebenen Ort befindet; dies werde ich später genauer erklären. Wenn das Handle jedoch erfolgreich erstellt wurde, fügen wir in Zeile 39 das Modul zum Chart hinzu. Auf diese Weise steht der Indikator zur Verfügung, ist aber nicht unbedingt sichtbar, sondern wird in der Liste der auf dem Chart laufenden Indikatoren angezeigt.

In Zeile 40 teilen wir MetaTrader 5 mit, dass das Handle nicht mehr benötigt wird, sodass der dafür reservierte Speicher an das System zurückgegeben werden kann. Da sich das Modul jedoch bereits im Chart befindet, wird es von MetaTrader 5 nicht aus dem Chart entfernt, es sei denn, Sie weisen das Terminal ausdrücklich an, dies zu tun.

Das gleiche Skript könnte entfernt werden und der Effekt wäre derselbe, d.h. das Mausmodul würde auf dem Chart platziert werden. Dies wäre der Fall, wenn die Chartvorlage das Modul enthalten würde. Dazu öffnen Sie ein beliebiges Chart, fügen einen Mausindikator hinzu und speichern diese Vorlage als Default.tpl. Zur Verdeutlichung können Sie nun eine Standardvorlage erstellen, die bereits einen Mauszeiger enthält. Damit entfällt die Notwendigkeit, Befehle in den Zeilen 38 bis 40 anzuzeigen, und wir können den Mauszeiger trotzdem an einer für uns bequemen Stelle platzieren.

Im Falle des Steuermoduls ist die Situation etwas anders. Das liegt daran, dass das Kontrollmodul in die ausführbare Datei des Dienstes integriert ist. Allein die Tatsache, dass dies geschieht, erleichtert dem Dienst die Platzierung des Moduls auf dem Chart. Dies geschieht in den Zeilen 41 und 42. In Zeile 41 erzeugen wir ein Handle für den Zugriff auf das Modul, und in Zeile 42 fügen wir es dem Chart hinzu. Beachten Sie, dass das Modul, wenn Sie die Zeile 42 nicht verwenden, nicht auf dem Chart platziert wird, sondern nur in den Speicher geladen wird, aber MetaTrader 5 wird es nicht auf dem von uns benötigten Chart ausführen.

In Zeile 43 entfernen wir den Griff, da wir ihn nicht mehr brauchen, genau wie in Zeile 40.

Bis zu diesem Zeitpunkt verhält sich der Dienst wie ein Programm, das in Kürze beendet wird. Zuvor wird jedoch in Zeile 44 eine Meldung in das Nachrichtenfeld ausgegeben, damit wir wissen, wie weit wir bei der Ausführung fortgeschritten sind. Dann, zwischen den Zeilen 45 und 46, initialisieren wir die letzten Variablen, die wir tatsächlich verwenden werden. Beachten Sie, dass wir diese Variablen mit Werten initialisieren, die zum Starten des Steuermoduls verwendet werden. Er wurde soeben auf dem Chart gestartet, aber noch nicht initialisiert, weshalb er nicht auf dem Chart angezeigt wird.

In Zeile 47 wird schließlich eine Schleife eingefügt. Diese Schleife wird beendet, wenn eine der in Zeile 13 definierten Bedingungen erfüllt ist, wodurch die Bedingung falsch wird und die Schleife beendet wird. Von nun an werden wir die Dinge nicht mehr nach dem Zufallsprinzip erledigen. Von diesem Zeitpunkt an führt der Dienst keine Aktionen mehr aus und ist für die Verwaltung der bereits laufenden Vorgänge zuständig. Es ist wichtig, dieses Konzept im Auge zu behalten und zu wissen, wie man diese Unterscheidung trifft. Andernfalls könnten Sie versuchen, etwas zu tun, was nicht in der Schleife sein sollte, was wiederum alles sehr instabil und problematisch machen würde.

Dann folgt eine neue Schleife in Zeile 49. Diese Schleife ab Zeile 49 ist eine gefährliche Art von Schleife, wenn sie nicht richtig geplant wird. Der Grund dafür ist, dass wir ohne die Definition in Zeile 13 in dieser Schleife auf unbestimmte Zeit stecken bleiben könnten. Dies liegt daran, dass das Steuermodul möglicherweise nicht im Chart vorhanden ist und der Dienst darauf wartet, dass MetaTrader 5 ihm den Wert des Handles mitteilt, bevor er auf den Indikator oder das Steuermodul zugreifen kann.

Das Löschen des Chart Control Moduls führt jedoch dazu, dass MetaTrader 5 den Chart schließt. Dadurch wird die Definition in Zeile 13 falsch, sodass die Schleifen in Zeile 49 und Zeile 47 beendet werden.

Deshalb erkläre ich am Beispiel eines einfacheren Systems, wie das Ganze funktioniert. In einem komplexeren System wäre es viel schwieriger, solche Feinheiten zu erkennen und zu verstehen. Wenn Sie also etwas testen wollen, sollten Sie dies mit einem einfachen Programm tun, das der gleichen Logik folgt wie das System, das später entwickelt werden soll.

Unter der Annahme, dass MetaTrader 5 uns ein gültiges Handle zurückgibt, setzen wir in Zeile 50 den Wert auf Null, den wir definieren, wenn das Lesen des Kontrollindikatorpuffers in Zeile 51 erfolgreich war.

Wenn das Lesen des Puffers aus irgendeinem Grund fehlschlägt, wird die Variable auf Null gesetzt. Aber wenn das Lesen erfolgreich ist, haben wir Daten, die sich im Puffer des Kontrollanzeigers befinden.

Sobald wir die Daten erhalten haben, können wir das Handle entfernen. Dies geschieht in Zeile 52. Der Grund dafür ist, dass in den nächsten Schritten alles Mögliche passieren kann und wir bei der Wiederholung der Schleife nicht den Wert false erhalten wollen. Es mag den Anschein haben, dass dies die Gesamtleistung des Systems verlangsamt, aber es ist besser, ein wenig Leistung zu verlieren, als Daten zu analysieren, die möglicherweise ungültig oder unnötig sind.

Achten Sie nun auf Folgendes: Der Indikator bzw. das Steuermodul ist noch nicht initialisiert. Sein Puffer enthält jedoch die Werte, die in der ersten Phase des Indikatorvorgangs dort abgelegt wurden. Um dies zu verstehen, lesen Sie bitte die vorherigen Artikel dieser Reihe. Sie sollten also nicht erwarten, dass beim Lesen des Puffers Nullwerte zurückgegeben werden, das wird nicht passieren.

Hierfür gibt es zwei bedingte Tests. Mit dem einen können wir das Steuermodul initialisieren, damit es weiß, welche Steuerelemente angezeigt werden sollen. Der zweite Test ermöglicht es uns, im Dienst alle Informationen darüber zu speichern, was im Steuermodul vor sich geht. Dies geschieht, damit wir, wenn wir wieder den letzten Arbeitszustand des Moduls melden müssen, wissen, welche Werte wir ihm übergeben müssen.

In Zeile 53 wird also geprüft, ob das Modul dem Chart hinzugefügt wurde. Dies kann an zwei Stellen geschehen. Die erste ist, wenn wir uns noch in der ersten Ausführung der in Zeile 47 begonnenen Schleife befinden. In diesem Fall stammen die an das Steuermodul zu meldenden Werte aus den Zeilen 45 und 46. Der zweite Punkt ist, wenn MetaTrader 5 das Kontrollmodul auf dem Chart zurücksetzen und neu platzieren muss, weil sich der Zeitrahmen des Charts aus irgendeinem Grund geändert hat. In diesem Fall werden die letzten Werte verwendet, die im Kontrollindikator vorhanden waren, bevor MetaTrader 5 ihn wieder in den Chart eingefügt hat.

Aber wie auch immer, am Ende führen wir Zeile 57 aus, die MetaTrader 5 veranlasst, ein nutzerdefiniertes Ereignis auf dem vom Dienst überwachten Chart zu erzeugen. Auf diese Weise erhält der Kontrollindikator neue oder alte Werte, sodass der Eindruck entsteht, dass auf magische Weise nichts verloren gegangen ist. Dies geschieht nur, weil wir im Indikator, im Steuermodul, einen bestimmten Wert im Puffer platziert haben, der anzeigt, dass der Indikator aktualisierte Werte von einer externen Quelle erhalten will und soll. In diesem Fall handelt es sich um den Dienst, der auf der Plattform MetaTrader 5 läuft.

Wenn es sich nun nicht um den Inhalt des Indikatorpuffers handelt, wird in Zeile 58 eine neue Prüfung durchgeführt, bei der geprüft wird, ob der Wert ungleich Null ist. So können wir erkennen, ob sich die Kontrollanzeige im Abspiel- oder im Pausenmodus befindet. Im Demodienst zeigen beide Situationen an, dass der Dienst den Inhalt des Indikatorpuffers erfassen und den Wert speichern sollte, der verwendet wird, wenn MetaTrader 5 beschließt, den Indikator aufgrund einer Änderung des Chart-Zeitrahmens zu entfernen und wieder auf dem Chart zu platzieren.

Da die Ausführung sehr schnell erfolgen kann und wir keine superschnelle Aktualisierung benötigen, verwenden wir Zeile 63, um dem Dienst eine Pause zu gönnen, in der er nichts Wichtiges tut. Diese Zeile sagt uns auch, dass die in Zeile 47 begonnene Schleife beendet ist.

Wenn der Nutzer den Dienst schließt oder das Chart aus irgendeinem Grund geschlossen wird, verlassen wir die in Zeile 47 begonnene Schleife und führen zuerst Zeile 65 aus. In dieser Zeile wird das Chart geschlossen, denn wenn der Nutzer den Dienst beendet, bleibt das Chart weiterhin geöffnet. Um dies zu vermeiden, teilen wir dem MetaTrader 5 mit, dass er den von uns verwendeten Chart jetzt schließen kann.

Nach dem Schließen des Charts versuchen wir, das erstellte, nutzerdefinierte Symbol aus dem Marktbeobachtungsfenster zu entfernen. Dies geschieht in Zeile 66. Wenn es keine anderen offenen Charts mit diesem Symbol gibt, können wir MetaTrader 5 zwingen, es aus dem Market Watch zu entfernen. Aber auch nach dem Löschen erscheint sie noch an der Stelle, an der sie erstellt wurde, nämlich in Zeile 26.

Wenn das Symbol tatsächlich aus der Marktbeobachtung entfernt wurde, wird es in Zeile 67 aus der Liste der im System verfügbaren Symbole entfernt. Und schließlich, in Zeile 68, wenn alles gut gelaufen ist und alle Prozeduren wie erwartet durchgeführt wurden, geben wir eine Meldung im Terminalfenster aus, die besagt, dass der Dienst beendet wurde und nicht mehr läuft.


Schlussfolgerung

Diese Art von Situationen, auch wenn sie auf lange Sicht unwichtig oder nutzlos erscheinen mögen, liefern in Wirklichkeit nützliche und notwendige Kenntnisse für das, was wir später wirklich brauchen werden. Bei der Entwicklung einer Lösung oder Anwendung müssen wir uns oft mit unbekannten oder ungünstigen Szenarien auseinandersetzen. Wenn Sie also etwas entwerfen, programmieren oder entwickeln müssen, das vielleicht viel komplizierter ist als ursprünglich gedacht, erstellen Sie ein kleines Programm, das leicht zu verstehen und zu erlernen ist, aber dennoch einen Teil der Arbeit erledigt, die Sie auf lange Sicht erledigen müssen.

Wenn Sie alles richtig machen, können Sie einen Teil des kleinen Programms, das Sie erstellt haben, in Ihrem wirklich großen und komplexen Projekt verwenden. Aus diesem Grund habe ich mich entschlossen, diesen Artikel zu schreiben. Damit Sie verstehen, dass ein Programm, das manchmal sehr komplex ist und verschiedene Wissensstufen erfordert, nicht einfach aus dem Nichts entsteht.

Sie wird immer in Etappen, in funktionalen Teilen, erstellt, und ein Teil der Idee wird dann in einer größeren Lösung verwendet. Und das ist genau das, was wir mit unserem Replay/Simulator-System tun werden. Die Art und Weise, wie der hier beschriebene Dienst funktioniert, gibt uns genau das, was wir für die Umsetzung unseres großen Systems brauchen.

Bitte beachten Sie, dass es ohne die gründliche Analyse und Forschung, die uns dieser Artikel ermöglicht hat, unwahrscheinlich ist, dass wir in der Lage gewesen wären, die Module mit minimalem Aufwand in das Replay/Simulator-System zu integrieren. Wir müssten viele Anpassungen und Änderungen am Code vornehmen, die sich aber alle auf einen Punkt konzentrieren würden: die Klasse C_Replay. Aber ohne zu wissen, wo, wie und auf welche Weise die Klasse C_Replay angepasst werden sollte, würden wir in einer Sackgasse landen, was die Implementierung dessen, was wir hier sehen, extrem schwierig machen würde.

Da wir nun wissen, wie sich das System tatsächlich verhalten wird, müssen wir nur noch ein paar kleine Änderungen (hoffentlich) an der Klasse C_Replay vornehmen, damit die Schleife in den Zeilen 47 bis 64 Teil unseres Systemcodes werden kann. Aber es gibt einen kleinen Punkt: Im Gegensatz zu dem, was wir hier sehen, werden wir im Replay/Simulator-System Berechnungen durchführen, die dem folgen, was bereits im Chart angezeigt wurde. Dies wird jedoch in den folgenden Artikeln erörtert. Nehmen Sie sich die Zeit, die in diesem Artikel gezeigten Informationen zu studieren und zu verstehen, wie das System funktioniert, um alles besser zu verstehen, was im Folgenden vorgestellt wird. Wir werden den Replay/Simulator-Dienst die Module verwenden lassen, die im Video im vorherigen Artikel gezeigt wurden.

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

Beigefügte Dateien |
Anexo.zip (420.65 KB)
Nutzerdefinierter Indikator: Darstellen von partiellen Eintritts-, Austritts- und Stornogeschäften für Netting-Konten Nutzerdefinierter Indikator: Darstellen von partiellen Eintritts-, Austritts- und Stornogeschäften für Netting-Konten
In diesem Artikel werden wir uns eine nicht standardisierte Methode zur Erstellung eines Indikators in MQL5 ansehen. Anstatt sich auf einen Trend oder ein Chartmuster zu konzentrieren, wird unser Ziel sein, unsere eigenen Positionen zu verwalten, einschließlich partieller Ein- und Ausstiege. Wir werden ausgiebig Gebrauch von dynamischen Matrizen und einigen Handelsfunktionen machen, die sich auf die Handelshistorie und offene Positionen beziehen, um auf dem Chart anzuzeigen, wo diese Geschäfte getätigt wurden.
Adaptive Social Behavior Optimization (ASBO): Zweiphasige Entwicklung Adaptive Social Behavior Optimization (ASBO): Zweiphasige Entwicklung
Wir beschäftigen uns weiterhin mit dem Thema des Sozialverhaltens von Lebewesen und dessen Auswirkungen auf die Entwicklung eines neuen mathematischen Modells - ASBO (Adaptive Social Behavior Optimization). Wir werden uns mit der zweiphasigen Entwicklung befassen, den Algorithmus testen und Schlussfolgerungen ziehen. So wie sich in der Natur eine Gruppe von Lebewesen zusammenschließt, um zu überleben, nutzt ASBO die Prinzipien des kollektiven Verhaltens, um komplexe Optimierungsprobleme zu lösen.
Entwicklung eines Replay Systems (Teil 58): Wiederaufnahme der Arbeit am Dienst Entwicklung eines Replay Systems (Teil 58): Wiederaufnahme der Arbeit am Dienst
Nach einer Pause in der Entwicklung und Verbesserung des Dienstes für Replay/Simulator nehmen wir die Arbeit daran wieder auf. Da wir nun die Verwendung von Ressourcen wie Terminalglobals aufgegeben haben, müssen wir einige Teile des Systems komplett umstrukturieren. Keine Sorge, dieser Prozess wird im Detail erklärt, sodass jeder die Entwicklung unseres Dienstes verfolgen kann.
Entwicklung eines Expertenberaters für mehrere Währungen (Teil 15): Den EA für den realen Handel vorbereiten Entwicklung eines Expertenberaters für mehrere Währungen (Teil 15): Den EA für den realen Handel vorbereiten
Wenn wir uns allmählich einem fertigen EA nähern, müssen wir auf Aspekte achten, die in der Phase des Testens einer Handelsstrategie zweitrangig erscheinen, aber wichtig werden, wenn wir zum echten Handel übergehen.