Von der Grundstufe bis zur Mittelstufe: Ereignisse (II)
Einführung
Im vorherigen Artikel „Von der Grundstufe zur Mittelstufe: Ereignisse (I)“ haben wir mit der Diskussion über ereignisgesteuerte Programmierung begonnen. Ja, dieser Ansatz ist vielen Programmierern unter genau diesem Namen bekannt: Ereignisgesteuerte Programmierung. Viele halten sie für komplex und schwierig. Das liegt daran, dass sie die Mechanismen und Konzepte nicht verstehen.
Die ereignisgesteuerte Programmierung befreit uns jedoch von verschiedenen Problemen und Aufgaben im Zusammenhang mit der grafischen Nutzeroberfläche (GUI). Da es sich bei MetaTrader 5 um eine GUI-Plattform handelt, vereinfacht die ereignisgesteuerte Programmierung die Entwicklung von ereignisgesteuerten Anwendungen erheblich.
Im letzten Artikel haben wir die ersten Schritte unternommen, um ein Gefühl dafür zu bekommen, wie es weitergehen soll. Wir haben gesehen, wie man durch bestimmte Aspekte navigieren kann, um die aufgetretenen Ereignisse mit Hilfe eines einfachen Indikators zu verfolgen. Wer jedoch testen möchte, wie gut er bestimmte Programmierkonzepte versteht und in der Praxis anwenden kann, hat eine kleine Aufgabe zu lösen.
Da die vorgeschlagene Aufgabe nicht sehr komplex war, glaube ich, dass diejenigen, die etwas mehr Zeit und Mühe darauf verwendet hätten, in der Lage gewesen wären, eine Methode zu entwickeln, um sie zu lösen, denn sie scheint tatsächlich relativ einfach lösbar zu sein.
Als Nächstes werde ich zwei Wege zur Lösung derselben Aufgabe aufzeigen und die Vor- und Nachteile der jeweiligen Herangehensweise an das Problem diskutieren. Es ist also an der Zeit, sich auf das heutige Material zu konzentrieren. Und, wie üblich, werden wir ein neues Thema eröffnen, um alles besser zu organisieren.
Eine mögliche erste Lösung
Um die Erklärung richtig zu beginnen, beginnen wir mit dem Code des Indikators, wie er im vorherigen Artikel gezeigt wurde:
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. uint gl_Counter; 05. //+------------------------------------------------------------------+ 06. int OnInit() 07. { 08. gl_Counter = 0; 09. 10. Print(__FUNCTION__); 11. 12. return INIT_SUCCEEDED; 13. }; 14. //+------------------------------------------------------------------+ 15. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) 16. { 17. if (!gl_Counter) 18. { 19. uint arr[]; 20. 21. if (FileLoad(_Symbol, arr) > 0) 22. gl_Counter = arr[0]; 23. } 24. 25. Print(__FUNCTION__, " :: ", ++gl_Counter); 26. 27. return rates_total; 28. }; 29. //+------------------------------------------------------------------+ 30. void OnDeinit(const int reason) 31. { 32. uint arr[1]; 33. 34. arr[0] = gl_Counter; 35. FileSave(_Symbol, arr); 36. 37. Print(__FUNCTION__); 38. }; 39. //+------------------------------------------------------------------+
Code 01
Die vorgeschlagene Aufgabe bestand darin, eine Möglichkeit zu schaffen, dass die in Zeile 04 dieses Codes deklarierte Variable ihren aktuellen Zählerwert nur dann beibehält, wenn sich der Zeitrahmen des Charts ändert. In allen anderen Fällen sollte der Wert dieser Variablen gleich Null sein. Dadurch würde der Zähler zurückgesetzt.
Obwohl diese Aufgabe relativ einfach ist, kann sie zeigen, wie bereit der Leser für komplexere Aufgaben ist. Wenn Sie jedoch bei der Lösung des Problems nicht weiterkommen, machen Sie sich keine Sorgen. Das Wichtigste ist, dass Sie nach einer Lösung für das Problem gesucht haben. Das ist es, was wirklich zählt. Das Lösen der Aufgabe wäre ein „Bonus“ für Sie gewesen, aber es würde nicht beweisen, dass Sie bereits programmieren können. Dann hätten Sie nur eine Lösung gefunden. Wenn das der Fall ist, dann nehmen Sie bitte meine herzlichsten Glückwünsche entgegen.
Gut, lassen Sie uns ein wenig nachdenken. Jedes Mal, wenn wir den Zeitrahmen des Charts ändern, löst MetaTrader 5 das Ereignis Deinit aus. Dies wiederum erzeugt einen Anruf, der an ein bestimmtes Chart gerichtet ist. Wir werden diesen Mechanismus in Zukunft weiter erforschen. Im Moment müssen Sie nur verstehen, inwieweit der MetaTrader 5 für Sie funktioniert und wie wir mit ihm arbeiten können und sollten. Wenn dieses Ereignis in einem Chartfenster eintrifft, wird es an ALLE ANWENDUNGEN AUF DEM CHART gesendet. AN ALLE. Jede Anwendung muss dieses Deinit-Ereignis abfangen und es bestmöglich behandeln.
Okay, wer erhält also dieses Ereignis? Nun, dieses Ereignis wird einzig und allein von der Prozedur OnDeinit abgefangen, und genau hier wird es interessant. In Zeile 30 von Code 01 sieht man, dass diese Prozedur einen Wert erhält. Dieser Wert wird von MetaTrader 5 gefüllt, um den Grund für die Entfernung der Anwendung aus dem Chart mitzuteilen. „Aber Moment mal, was bedeutet aus der Chart entfernen?“ Auf den ersten Blick macht dies nicht viel Sinn, da wir nur den Zeitraum des Charts ändern und nicht den Indikator entfernen wollen. In gewisser Weise haben Sie Recht, liebe Leser.
Aus verschiedenen Gründen, die hauptsächlich mit der Implementierung der MetaTrader 5-Plattform selbst zusammenhängen, ist es jedoch viel einfacher, alle Elemente aus dem Chart zu entfernen, seine Neuzeichnung anzufordern und erst dann die entfernten Elemente wieder in das Chart einzufügen. Aus diesem Grund werden die Skripte natürlich nicht neu positioniert, da sie keine Ereignisse verarbeiten können. Indikatoren und Expert Advisors, die mit Ereignissen arbeiten können, werden jedoch automatisch wieder an das Chart angehängt. Dies ist dasselbe wie beim Start der Plattform. Wenn ein Indikator oder ein Expert Advisor auf einem offenen Chart vorhanden ist, wird er automatisch von MetaTrader 5 auf dem Chart platziert. Unmittelbar nach der Platzierung all dieser Elemente auf dem Chart gibt MetaTrader 5 ein neues Ereignis für diesen Chart aus. Das betreffende Ereignis ist Init, das wiederum von der Funktion OnInit abgefangen wird. Diese Funktion ist in Zeile 06 von Code 01 zu sehen. Das ist alles, was MetaTrader 5 für uns tun wird. Von dort aus entscheiden wir, wie unsere Anwendung auf solche Ereignisse reagieren wird.
Dies ist sehr wichtig, also bitte verstehen und verinnerlichen Sie es gut. Dies ist die Grundlage der ereignisgesteuerten Programmierung in MQL5 zur Erstellung von Anwendungen, die auf MetaTrader 5 laufen. Da unsere Anwendung den Zählerwert in gl_Counter nur zur Laufzeit kennt, können wir nicht wissen, wie hoch er vor dem Eintreten des Init-Ereignisses war. Dies geschieht, weil MetaTrader 5 während des Prozesses des Entfernens des Charts von der Plattform und des anschließenden Neuaufbaus den gesamten von unserer Anwendung verwendeten Speicherbereich auf dem Chart löscht.
Das einzige, was (je nach Situation) beibehalten werden kann, sind statische Variablen. Aber statische Variablen in Anwendungen, die als Indikatoren funktionieren sollen, werfen einige Probleme auf. Sie können verwendet werden, aber mit bestimmten Vorsichtsmaßnahmen. Wir werden dies in Zukunft diskutieren. Vergessen wir zunächst ein wenig die statischen Variablen in Codes, die als Indikatoren dienen sollen. Bei den Expert Advisors ist die Situation anders, da hier andere Mechanismen im Spiel sind, die man verstehen muss, um sie richtig zu nutzen. Konzentrieren wir uns also zunächst auf die Frage der Indikatoren – gerade weil sie einfacher sind.
In diesem Stadium können wir nämlich nicht mit statischen Variablen arbeiten, und der Wert von gl_Counter ist nur so lange gültig, wie sich der Indikator im Chart befindet. Wenn wir MetaTrader 5 auffordern, die Chart-Periode zu ändern, wird ein Ereignis ausgelöst, das von der Prozedur in Zeile 30 erfasst wird, deren Parameterwert reason die Ursache des Deinit-Ereignisses angibt. Jetzt müssen wir die Dokumentation konsultieren und prüfen, welcher Wert die Art des Ereignisses meldet, für das wir gl_Counter erhalten müssen. Auf diese Weise erhalten wir unsere Lösung.
Nun gut, wenn wir die Dokumentation konsultieren, sehen wir, dass die Konstante REASON_CHARTCHANGE unser Kriterium erfüllt, nämlich eine Änderung des Zeitrahmens des Charts. Wird jedoch auch das Symbol geändert, so wird die gleiche Konstante gemeldet. Konzentrieren wir uns jedoch zunächst auf die Frage des Chart-Zeitraums. Durch Hinzufügen eines kleinen Tests in der OnDeinit-Prozedur erhalten wir also unseren neuen Code:
. . . 29. //+------------------------------------------------------------------+ 30. void OnDeinit(const int reason) 31. { 32. uint arr[1]; 33. 34. arr[0] = (reason == REASON_CHARTCHANGE ? gl_Counter : 0); 35. FileSave(_Symbol, arr); 36. 37. Print(__FUNCTION__); 38. }; 39. //+------------------------------------------------------------------+
Code 02
Da der Rest des Codes identisch ist mit dem, was in Code 01 zu sehen ist, werden wir uns nur darauf konzentrieren, was sich geändert hat. Die Änderung ist sehr einfach: Ich musste nur Zeile 34 ändern, um zu prüfen, ob die Konstante die gewünschte ist. Wenn ja, wird der Zählerstand beibehalten. Andernfalls wird der Wert auf Null zurückgesetzt, was dazu führt, dass der Zähler neu startet, wenn der Indikator erneut auf demselben Symbol verwendet wird, auf dem die Zählung stattgefunden hat.
Im Folgenden werden wir die Vor- und Nachteile dieser Art der Umsetzung betrachten. Und ja, das sind nicht alle Vor- und Nachteile, die mit der Umsetzung verbunden sind. Daher ist das Verstehen von Konzepten und das Üben Teil des Lernprozesses.
Der Kürze halber werden wir nur einen Vorteil und einen Nachteil nennen. Der Rest liegt bei Ihnen, und das Wissen wird sich mit zunehmender Übung und dem Studium jedes spezifischen Anwendungsfalls für eine bestimmte Form der Implementierung entwickeln.
Der Vorteil ist, dass der Prozess relativ „sauber“ und über mehrere Parameter leicht kontrollierbar ist. Sie möchten zum Beispiel wissen, wie oft ein bestimmtes Ereignis innerhalb eines bestimmten Zeitraums ausgelöst wurde.
Andererseits zwingt uns die Verwendung von Dateien zur Speicherung von Werten dazu, diese zu analysieren, was in vielen Fällen problematisch werden kann. Wenn beispielsweise dasselbe Symbol mit demselben Indikator in derselben MetaTrader 5-Sitzung geöffnet ist, kann ein ständiger Wechsel der Chart-Periode zu nicht übereinstimmenden Werten führen. In der Programmierung ist diese Art von Problem als Race Condition bekannt und recht komplex; tatsächlich wurden ganze Doktorarbeiten und Bücher zu diesem Thema geschrieben. Glauben Sie mir, als Anfänger wollen Sie wirklich nicht auf eine Race Condition in Ihrem Code stoßen.
Nun, mein lieber Leser, dies wäre die erste Lösung, gerade weil es keine wesentlichen Änderungen am Code erfordert: nur eine schnelle Suche in der Dokumentation und die Anleihe Elemente bereits in früheren Artikeln gezeigt.
Im Folgenden werden wir uns eine etwas andere Lösung ansehen, bei der ein Teil der Verfolgung des Zählerwerts an den MetaTrader 5 delegiert wird. Aber, wie Sie verstehen, werden wir dies in einem neuen Thema tun.
Eine mögliche zweite Lösung
Die zweite Lösung ist weitaus interessanter, sowohl aus praktischer Sicht als auch weil die Verantwortung für die Aufrechterhaltung des Zählerstands in den Händen von MetaTrader 5 bleibt. Doch bevor Sie sich fragen, warum wir diese Lösung nicht schon früher in Betracht gezogen haben, werden wir das Gegenteil tun. Zunächst werden wir die Vor- und Nachteile der zweiten vorgeschlagenen Lösung erörtern, und dann werden wir uns ansehen, wie sie umgesetzt wird. Wie bei der vorherigen Lösung werden wir einen Vorteil und einen Nachteil aufführen, damit die Erklärung nicht zu lang wird.
Der Vorteil der zweiten Lösung ist, dass sie uns von der Verantwortung entbindet, den Wert der Variablen irgendwo zu speichern, höchstwahrscheinlich in einer Datei. Andererseits ist anzumerken, dass die Delegierung der Verantwortung für die Aufrechterhaltung des Variablenwerts die Aufgabe je nach Zielsetzung etwas erschwert. Dies liegt daran, dass diese Verantwortung bei MetaTrader 5 liegt, nicht bei uns.
„Aber wie ist das möglich? Wie kann ein und dieselbe Sache sowohl als Vorteil als auch als Nachteil betrachtet werden?“ Um zu verstehen, warum ich sie als beides anführe, müssen wir untersuchen, worin diese Lösung besteht, bei der der Vorteil und der Nachteil praktisch gleich sind und die dennoch den Eindruck erweckt, etwas Unglaubliches zu sein. Diese Lösung ist eine fast unbekannte Funktion des MetaTrader 5. In der Vergangenheit habe ich es für andere Zwecke verwendet, und die Entwickler von MetaTrader 5 haben sicherlich nicht damit gerechnet, dass jemand es genau für diesen Zweck verwenden würde.
Sie können dies in dem Artikel „Einen handelnden Expert Advisor von Grund auf neu entwickeln (Teil 17): Zugang zu Daten im Internet (III)“ sehen. Damals stellte ich mir vor, dass die Ressourcen von MetaTrader 5 von einer großen Anzahl von Programmierern viel intensiver untersucht wurden. Mit der Zeit stellte ich jedoch fest, dass viele Leute mit sehr oberflächlichen Kenntnissen auftauchten und versuchten, MQL5 zu Dingen zu zwingen, für die es nicht konzipiert war. Deshalb habe ich eine Pause eingelegt, nachgedacht und bin gereift, um diese Artikel zu verfassen, die Sie jetzt nutzen, um MQL5 auf angenehme Art und Weise zu lernen. Ich wollte dieses wissensdurstige Publikum ermutigen, aber wir haben nur sehr wenige Referenzen, die sich an Anfänger richten.
Ich hoffe, dass diese Artikel einen guten Ausgangspunkt für Sie darstellen. Fragen und Vorschläge zur Verbesserung dieses Inhalts sind willkommen.
Gut, kommen wir zurück zum Thema. Die Idee ist, die globalen Variablen des Terminals zu verwenden. Dies ist eine sehr interessante Ressource, die über die in der MQL5-Bibliothek definierten Funktionen und Prozeduren zugänglich ist. Sie ist einfach, praktisch und in einer Vielzahl von Situationen sehr nützlich. Schauen wir uns nun an, wie der Indikatorcode für die Nutzung dieser Ressource aussieht. Und zwar so:
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. union u_01 05. { 06. double d_value; 07. uint u_Counter; 08. }gl_Union; 09. //+------------------------------------------------------------------+ 10. int OnInit() 11. { 12. ZeroMemory(gl_Union); 13. 14. if (!GlobalVariableGet(_Symbol, gl_Union.d_value)) 15. if (!GlobalVariableTemp(_Symbol)) 16. return INIT_FAILED; 17. 18. GlobalVariableSet(_Symbol, gl_Union.d_value); 19. 20. Print(__FUNCTION__); 21. 22. return INIT_SUCCEEDED; 23. }; 24. //+------------------------------------------------------------------+ 25. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) 26. { 27. Print(__FUNCTION__, " :: ", ++gl_Union.u_Counter); 28. 29. return rates_total; 30. }; 31. //+------------------------------------------------------------------+ 32. void OnDeinit(const int reason) 33. { 34. switch(reason) 35. { 36. case REASON_CHARTCHANGE: 37. GlobalVariableSet(_Symbol, gl_Union.d_value); 38. break; 39. default: 40. GlobalVariableDel(_Symbol); 41. } 42. 43. Print(__FUNCTION__); 44. }; 45. //+------------------------------------------------------------------+
Code 03
Wenn wir den Code 03 ausführen, sehen wir etwas Ähnliches wie die unten abgebildete Animation:

Animation 01
Bitte beachten Sie, dass wir zu einem bestimmten Zeitpunkt den Zeitrahmen des Charts geändert haben und dabei dieselbe Abfolge von Ereignissen erzeugt haben, die wir im vorherigen Thema besprochen haben. Dies lässt sich aus den auf dem Terminal ausgedruckten Informationen ableiten. Aber das ist nicht alles, was hier passiert. Beachten Sie, dass wir im Gegensatz zum vorherigen Code 03 keine Datei für die vorübergehende Speicherung von Informationen verwenden (in diesem Fall den Zählerstand), sondern den MetaTrader 5 auffordern, diese Informationen auf eine ganz bestimmte Weise zu speichern.
Um dies zu überprüfen, können wir prüfen, ob es existiert und, wenn ja, welche globalen Variablen des Terminals in MetaTrader 5 vorhanden sind, noch bevor wir den Code 03 erklären. Verwenden Sie dazu einfach die Tastenkombination F3 oder folgen Sie dem im Bild unten gezeigten Pfad:

Abbildung 01
Wenn der Indikator Code 03 läuft, wird im geöffneten Fenster eine solche Variable angezeigt:

Abbildung 02
Wenn der Indikator aus Code 03 nicht läuft, ist es gut möglich, dass das gleiche Fenster wie in Abbildung 02 keine Informationen enthält, da meines Wissens nur wenige Leute globale Terminalvariablen aus irgendeinem Grund verwenden. Aber wenn eine Ressource vorhanden und verfügbar ist, warum sollte man sie nicht kreativ nutzen?
Dank der Informationen, die wir in den Bildern und der Animation gesehen haben, haben wir genug Elemente, um zu verstehen, wie Code 03 funktioniert. In gewissem Sinne sehe ich keine Notwendigkeit zu erklären, wie es funktioniert, da es sich nur um eine einfache Änderung des Codes 02 handelt. Das werde ich jedoch nicht tun, denn globale Terminalvariablen sind eine Art von Ressource, deren Verwendung sehr spezifisch ist. Bei dieser Gelegenheit werde ich erklären, wie man sie in anderen Situationen einsetzen kann.
Wenn Sie wirklich eine globale Terminalvariable verwenden wollen, müssen Sie wissen, dass diese nur Werte vom Typ double enthalten kann. Das heißt, wir können keine Text- oder Ganzzahlwerte in eine solche Variable eingeben. Das heißt, im Allgemeinen. Da MQL5 jedoch die Erstellung von Unions erlaubt, die, wie wir bereits gesehen haben, bei der täglichen Arbeit sehr nützlich sein können, erstellen wir in Zeile 04 eine Union, um einen Nicht-Fließkommawert in eine globale Terminalvariable zu setzen.
Auf diese Weise eröffnen sich mehrere Möglichkeiten für die Verwendung dieser Variablen, da wir in diesem Fall kleine Textstücke in sie einfügen können, sofern der Text in einen Doppeltyp integriert werden kann. Wenn Sie nicht ganz verstehen, wovon ich spreche, empfehle ich Ihnen einen Blick in die vorherigen Artikel, um mehr über dieses Thema zu erfahren.
Um unnötigen Zugriff auf globale Terminalvariablen zu vermeiden, deklarieren wir die Union als globale Variable. Dies ist aus Zeile 08 ersichtlich. Bitte beachten Sie: Was wir tun, ist nicht verpflichtend. Wir könnten diesen Code so implementieren, dass wir keine globale Variable haben, aber das würde uns dazu zwingen, diese globale Variable, die in unserem Code deklariert ist, außerhalb unseres Codes zu verschieben und sie in eine globale Terminalvariable zu verwandeln. In gewissem Sinne könnte dies die Gesamtleistung verringern. In einigen sehr spezifischen Szenarien kann es jedoch interessant und notwendig sein, diese Art der Implementierung zu verwenden. Jeder Fall ist einzigartig. Deshalb sollte man nicht verallgemeinern oder denken, dass man immer auf die eine Art und Weise handeln muss und auf die andere nicht. Das wird nicht immer der Fall sein.
In der Praxis verwenden wir Zeile 12, um den Speicherbereich zu löschen, in dem sich unser Zähler befinden wird. Wir können dies auch auf andere Weise tun, also denken Sie an andere Methoden und verwenden Sie sie, um das Ergebnis zu sehen. Unmittelbar danach, in Zeile 14, versuchen wir, die Variable zu lesen, die in Abbildung 02 zu sehen ist. Wenn eine solche Variable nicht existiert, wird in Zeile 15 versucht, sie zu erstellen. Beachten Sie, dass der Variablenname der Name des Symbols ist, für das der Indikator verwendet wird. Wenn der Versuch fehlschlägt, gibt der Indikator einen MetaTrader 5-Fehlerwert zurück und löst ein neues Ereignis aus – in diesem Fall das Deinit-Ereignis, da die Initialisierung fehlgeschlagen ist. Dadurch wird die Prozedur in Zeile 32 ausgeführt, und der Indikator verschwindet vom Chart.
Es ist amüsant, wie alles funktioniert und sehr einfach umgesetzt werden kann, wenn man versteht, was zu tun ist und wie alles erzeugt wird. Ich möchte Sie jedoch darauf hinweisen, dass diese Funktion in Zeile 15 versucht, eine temporäre globale Terminalvariable zu erstellen, und es ist wichtig, dass dies VOR dem Aufruf in Zeile 18 geschieht. Andernfalls wird die Variable nicht temporär sein. Aber selbst dann wäre die Variable immer noch nach anderen Kriterien global, nur nicht nach dem, das wir verwenden wollen.
Wenn wir eine temporäre globale Terminalvariable erstellen, wird diese nur so lange existieren, wie die MetaTrader 5 Plattform geöffnet ist. Wenn sie aus irgendeinem Grund geschlossen wird, werden alle globalen Terminalvariablen, die von der Funktion in Zeile 15 erstellt wurden, gelöscht. Diese Situation ist sehr interessant, wenn wir Werte speichern wollen, während MetaTrader 5 geöffnet ist (unabhängig davon, was gerade läuft), und diese Informationen vergessen werden, wenn die Plattform geschlossen wird. Dies geschieht jedoch nur, wenn die globale Terminalvariable mit der Funktion GlobalVariableTemp erstellt wurde.
Wir können die gleiche Variable auch ohne die Bedingung des Löschens erstellen, indem wir die Funktion in Zeile 18 verwenden. In diesem Fall wird sie von MetaTrader 5 nach einer bestimmten Zeit gelöscht. Lesen Sie die Dokumentation, um mehr darüber zu erfahren, denn es gibt Fälle, in denen wir einerseits Informationen für eine lange Zeit benötigen, sie aber andererseits nicht in einer Datei speichern wollen. In einer solchen Situation können globale Terminalvariablen recht interessant sein.
Nun gut, der Funktion OnCalculate ist nichts mehr hinzuzufügen. Lassen Sie uns jedoch noch ein paar Worte über die OnDeinit-Prozedur verlieren. Achten Sie auf Folgendes: In Zeile 34 wird geprüft, welche Situation das Deinit-Ereignis ausgelöst hat. Wenn es sich, wie erwartet, um eine Änderung des Zeitrahmens des Charts handelt, wird in Zeile 37 der aktuelle Wert unseres Zählers gespeichert. In jeder anderen Situation löschen wir die erstellte globale Terminalvariable in Zeile 40. Aber warum sollte man das tun, wenn die erstellte Variable vorübergehend ist? Der Grund dafür ist rein pädagogischer Natur. Sie können mit Code 03 experimentieren und Ihre eigenen Situationen schaffen. Nichts ist fairer, als zu zeigen, wie wir eine globale Terminalvariable direkt durch Code erstellen und löschen können. Aus diesem Grund gibt es die Linie 40.
Es geht darum, zu zeigen, dass wir das gleiche Ergebnis auf unterschiedliche Weise erreichen können. Die Wahl der Mittel hängt von der Art des Szenarios oder der Situation ab, mit der wir konfrontiert sind.
Abschließende Gedanken
Nun, wir sind am Ende eines weiteren Artikels angelangt. Sie ergänzt die vorherige, sodass Sie sie zusammen betrachten sollten. Wenn Sie das im vorherigen Artikel Gezeigte studieren und das in anderen Artikeln dieser Reihe erworbene Wissen anwenden, können Sie das in diesem Artikel Erklärte und Gezeigte noch besser verstehen. Ich bin zwar nicht sehr detailliert darauf eingegangen, wie jede einzelne Zeile des Codes funktioniert, aber das war auch nicht mein Ziel. Ich möchte, dass du lernst, „wie man fischt“. Ich vermittle Ihnen das Wissen und die Materialien, damit Sie auf die beste Weise üben und lernen können, um Ihre Ziele zu erreichen. Sie müssen jedes gezeigte Detail üben und studieren.
Deshalb werden wir uns im nächsten Artikel ansehen, wie man einen echten Indikator entwickeln kann, um alles, was wir bisher gezeigt haben, anzuwenden. Um jedoch das Wesentliche des nächsten Artikels zu verstehen, muss man wissen, wie Ereignisse generiert werden und wie sehr uns der MetaTrader 5 dabei helfen kann; andernfalls werden Ihnen viele Türen verschlossen bleiben.
Im Anhang haben Sie Zugang zu den in diesem Artikel besprochenen Codes. Viel Glück, und wir sehen uns im nächsten Artikel!
Übersetzt aus dem Portugiesischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/pt/articles/15733
Warnung: Alle Rechte sind von MetaQuotes Ltd. vorbehalten. Kopieren oder Vervielfältigen untersagt.
Dieser Artikel wurde von einem Nutzer der Website verfasst und gibt dessen persönliche Meinung wieder. MetaQuotes Ltd übernimmt keine Verantwortung für die Richtigkeit der dargestellten Informationen oder für Folgen, die sich aus der Anwendung der beschriebenen Lösungen, Strategien oder Empfehlungen ergeben.
Marktsimulation (Teil 10): Sockets (IV)
Wie man Code in CodeBase veröffentlicht: Ein praktischer Leitfaden
Verwendung von Deep Reinforcement Learning zur Verbesserung des Ilan Expert Advisor
Einführung in MQL5 (Teil 26): Aufbau eines EAs mit Hilfe von Unterstützungs- und Widerstandszonen
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.