English Русский Español Português
preview
Entwicklung eines Wiedergabesystems (Teil 42): Chart Trader Projekt (I)

Entwicklung eines Wiedergabesystems (Teil 42): Chart Trader Projekt (I)

MetaTrader 5Beispiele | 7 August 2024, 09:53
26 0
Daniel Jose
Daniel Jose

Einführung

Im vorherigen Artikel Entwicklung eines Wiedergabesystems (Teil 41): Zu Beginn der zweiten Phase (II), habe ich gezeigt, wie man einen Indikator für die Maus erstellt. Sie werden vielleicht denken, dass das Unsinn ist und auf Dauer nichts bringt. Wenn dies der Fall ist, dann nur, weil Sie nie verstanden haben, was passiert ist.

Jedes Mal, wenn wir etwas Neues schaffen, müssen wir eine Reihe von Tests durchführen und Bedingungen schaffen, damit ein bestimmtes Programm oder Verfahren mit anderen koexistieren kann. Die Erfüllung dieser Bedingung zeigt, ob Sie bereit sind, sich als Fachmann zu bezeichnen.

Anfänger haben oft Probleme, wenn ein Programm oder ein Prozess mit anderen in Konflikt gerät. In einem solchen Fall können seltsame Dinge passieren. Für einen Anfänger mag es schwierig oder unmöglich sein, diese Probleme zu lösen, aber ein Profi sollte in der Lage sein, mit solchen Situationen umzugehen.

Was ich damit sagen will: Es hat keinen Sinn, einen Expert Advisor zu programmieren, der tausend und eine Operation durchführen kann, oder eine Reihe von Indikatoren und grafischen Elementen oder viele Programme oder Prozesse für die Arbeit am Markt zu haben, wenn sie, wenn man versucht, sie auf einem Chart zu kombinieren, anfangen, miteinander in Konflikt zu geraten.

Oder noch schlimmer: Nachdem Sie ein äußerst zuverlässiges und stabiles Programm erstellt haben, müssen Sie manchmal ein weiteres entwickeln, das einen Teil der Funktionalität des ersten nutzt, und dabei fängt das neue Programm an, eine Reihe von Fehlern und Ausfällen zu zeigen, insbesondere wenn es mit anderen Prozessen zusammenarbeitet. Die Behebung dieser Störungen wird auf jeden Fall einige Zeit in Anspruch nehmen, da einige von ihnen einfach, andere aber sehr komplex sind.

Warum sage ich das? Denn wir haben bereits einen Indikator für die Maus erstellt. Die MetaTrader 5-Plattform verfügt über verschiedene Tools, die uns helfen können. Einige von ihnen sind einfacher und müssen verbessert werden, um den individuellen Bedürfnissen aller gerecht zu werden. Sie können dies tun, indem Sie verschiedene Programme erstellen, um die perfekte Waffe, die perfekte Waffe für den Einsatz auf dem Markt zu erhalten. Aber ich möchte, dass Sie über Folgendes nachdenken: Wie wäre es, wenn wir nicht mehr versuchen würden, die perfekte Waffe zu entwickeln, sondern verschiedene kompatible Teile und Komponenten herstellen würden, die in Kombination jedes Mal zu einer Waffe zusammengesetzt werden können, die speziell für die jeweilige Situation entwickelt wurde?

Das scheint eine gute Lösung zu sein, nicht wahr? Und genau das haben wir getan, als wir den Mauszeiger erstellt haben. Auf der Grundlage dieses Indikators werden wir eine Reihe von Teilen und Komponenten erstellen, die uns sehr helfen werden.

Gleich zu Beginn dieser Serie über die Entwicklung des Replay/Simulator-Systems habe ich gesagt, dass die MetaTrader 5-Plattform sowohl in dem von uns entwickelten System als auch auf dem realen Markt auf die gleiche Weise verwendet werden soll. Es ist wichtig, dass dies richtig gemacht wird. Niemand möchte trainieren und lernen, mit einem Werkzeug zu kämpfen, während er während des Kampfes ein anderes nutzen muss. Glauben Sie mir, mit dem Replay/Simulator lernt man, aber der Handel auf einem ECHTEN Konto ist ein echter Kampf. In einem echten Kampf müssen Sie das anwenden, was Sie im Training gelernt und sich angewöhnt haben.

Nach dem Mauszeiger gibt es zwei weitere Werkzeuge, die so schnell wie möglich erstellt werden müssen. Die eine ist einfach, die andere ist recht komplex, da wir uns mit der Datensimulation befassen müssen. Beginnen wir also mit etwas Einfachem, um uns daran zu gewöhnen. Wenn wir dann zu etwas viel Komplexerem übergehen, haben wir bereits eine gute Vorstellung davon, wie alles funktionieren wird.

Ein einfaches Instrument ist Chart Trade. In seiner neuesten Fassung wurde es in dem Artikel vorgestellt: Entwicklung eines Expert Advisors für den Handel von Grund auf (Teil 30): CHART TRADE als Indikator?!. Im Vergleich zu dem, was wir jetzt tun werden, wird dieser Indikator wie ein Kinderspielzeug erscheinen, da er so einfach und nicht universell ist. Lassen Sie uns einen neuen Chart Trade erstellen, der harmonisch mit dem bereits erstellten Indikator, nämlich dem Maus-Indikator, koexistieren kann.


Neuer Chart-Handel

Chart Trade, das wir in dem oben genannten Artikel besprochen haben, wird als Grundlage dienen, aber wir werden seinen Code oder seine Vorlage nicht verwenden. Wir werden ein anderes, viel ausgereifteres und unseren Bedürfnissen entsprechendes System schaffen.

Sie werden sehen, dass der neue Code, den ich vorstellen werde, viel einfacher und kompakter ist, was bedeutet, dass es einfacher sein wird, Dinge zu ändern und zu korrigieren. Die Idee ist, den Mausindikator zum Bewegen, Klicken und Interagieren mit jedem Element im Chart zu verwenden. Zu diesem Zweck müssen wir einen recht ungewöhnlichen Code erstellen. Ich werde alles schrittweise demonstrieren, sodass man leicht nachvollziehen kann, was und wie etwas gemacht wird, da es sich stark von dem unterscheidet, was viele im MetaTrader 5 zu sehen und zu nutzen gewohnt sind. Wenn es um das Programmieren geht, verstehen viele das vielleicht zunächst nicht.

Beginnen wir mit der Tatsache, dass unser Chart Trade ein Konzept verwendet, das ich kürzlich vorgestellt habe: RAD-Programmierung. Das Wort RAD steht für Rapid Aapplication Development (schnelle Anwendungsentwicklung). Ich habe dieses Konzept vor vielen Jahren kennen gelernt, als ich mit der Programmierung für Windows-Systeme begann. Es ist eine große Hilfe bei der effizienten Erstellung von Anwendungen, sodass Sie mehr Zeit mit der direkten Arbeit am Code verbringen können, anstatt sich um das Aussehen des Programms zu kümmern. In dem Artikel Mehrere Indikatoren in einem Chart (Teil 06): MetaTrader 5 in ein RAD-System verwandeln (II), habe ich gezeigt, wie man etwas Ähnliches in MetaTrader 5 verwenden kann.

Das gleiche Konzept wird auch hier verwendet, allerdings in einer verbesserten Version. Wenn Sie auf dem richtigen Fuß beginnen wollen, lesen Sie den genannten Artikel sowie den vorhergehenden, der ebenfalls wichtig ist, um zu verstehen, was wir tun werden. Hier ist der Artikel: Mehrere Indikatoren in einem Chart (Teil 05): Umwandlung von MetaTrader 5 in ein RAD-System (I). Es ist sehr wichtig zu verstehen, was dort erklärt wird. Das aktuelle Thema wird reichhaltiger und komplexer sein, obwohl dieser Indikator im Vergleich zu dem, was uns in Zukunft erwartet, der einfachste Teil ist.

Die neue Vorlage wird wie in Abbildung 01 unten aussehen:

Abbildung 01

Abbildung 01 - RAD-Vorlage

Abbildung 01 zeigt die aktuelle Ansicht, die Chart Trade haben wird. Dies ist eine Chart Trade-Vorlage, nicht Chart Trade selbst. Letzteres ist in Video 01 unten zu sehen, in dem ich die Interaktion zwischen dem Mauszeiger und dem Mauszeiger demonstriere. Sehen Sie sich das Video an und beachten Sie, wie es funktioniert. Das Video stellt alles, was in diesem Artikel besprochen wird, anschaulich dar und wird daher zum Anschauen empfohlen.


Video 01 - Demo-Video

Nachdem Sie sich das Video 01 angesehen haben, wollen wir uns nun den Indikator-Code von Chart Trade ansehen. Zunächst müssen wir jedoch eine kleine Ergänzung zum Code der Klasse C_Terminal vornehmen, wie der folgende Ausschnitt zeigt.

Chart Trade Indikator Quellcode

156. //+------------------------------------------------------------------+
157.            bool IndicatorCheckPass(const string szShortName)
158.                    {
159.                            string szTmp = szShortName + "_TMP";
160.                            
161.                            if (_LastError != ERR_SUCCESS) return false;
162.                            IndicatorSetString(INDICATOR_SHORTNAME, szTmp);
163.                            if (ChartWindowFind(m_Infos.ID, szShortName) != -1)
164.                            {
165.                                    ChartIndicatorDelete(m_Infos.ID, 0, szTmp);
166.                                    Print("Only one instance is allowed...");
167.            
168.                                    return false;
169.                            }
170.                            IndicatorSetString(INDICATOR_SHORTNAME, szShortName);
171.                            ResetLastError();
172.    
173.                            return true;
174.                    }
175. //+------------------------------------------------------------------+

Fragment der Klasse C_Terminal

Dieser Code mag nicht ungewöhnlich erscheinen. Wir haben ihn schon einmal gesehen, aber jetzt ist er Teil der Klasse C_Terminal, sodass alle Klassen oder Indikatoren, die diese Klasse verwenden, von diesem Code profitieren. Dieser Code verhindert, dass der Indikator mehr als einmal auf dem Chart platziert wird. Es gibt eine Möglichkeit, dies zu umgehen, und wir werden sie in Zukunft nutzen, aber machen Sie sich über dieses Detail vorerst keine Gedanken. Beachten Sie, dass dieser Code verhindert, dass zwei identische Indikatoren gleichzeitig im Chart angezeigt werden.

Doch bevor wir uns der Quellcodeklasse zuwenden, die unseren Chart Trade unterstützen wird, wollen wir uns zunächst den Indikatorcode ansehen. Ich ändere die Reihenfolge der Präsentation, um die Erklärung für die Klasse angemessener zu gestalten. Der vollständige Code des Indikators ist unten zu sehen.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. #property description "Base version for Chart Trade (DEMO version)"
04. #property version   "1.42"
05. #property link "https://www.mql5.com/pt/articles/11652"
06. #property indicator_chart_window
07. #property indicator_plots 0
08. //+------------------------------------------------------------------+
09. #include <Market Replay\Chart Trader\C_ChartFloatingRAD.mqh>
10. //+------------------------------------------------------------------+
11. C_ChartFloatingRAD *chart = NULL;
12. //+------------------------------------------------------------------+
13. int OnInit()
14. {
15.     chart = new C_ChartFloatingRAD("Indicator Chart Trade", new C_Mouse("Indicator Mouse Study"));
16.     if (_LastError != ERR_SUCCESS)
17.     {
18.             Print("Error number:", _LastError);
19.             return INIT_FAILED;
20.     }
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.     return rates_total;
28. }
29. //+------------------------------------------------------------------+
30. void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
31. {
32.     (*chart).DispatchMessage(id, lparam, dparam, sparam);
33.     
34.     ChartRedraw();
35. }
36. //+------------------------------------------------------------------+
37. void OnDeinit(const int reason)
38. {
39.     delete chart;
40.     
41.     ChartRedraw();
42. }
43. //+------------------------------------------------------------------+

Wie oben gezeigt, ist der Code für diesen Indikator recht einfach. Natürlich werden wir weitere Informationen hinzufügen, um eine adäquate Beschreibung zu erstellen, aber für den Moment ist dies ausreichend für das, was wir brauchen.

Bitte beachten Sie, dass wir lediglich angeben, dass in Zeile 07 keine Daten angezeigt werden. Der Rest der Arbeit besteht darin, einen Zeiger zu initialisieren, um die Klasse zu verwenden, die den Handel aus dem Chart unterstützt, und denselben Zeiger wieder zu zerstören. Wir werden das Verhalten jedoch in Video 01 demonstrieren lassen.

Ich denke, es sollte keine Schwierigkeiten geben, die Zeilen des Indikator-Codes zu verstehen. Das Einzige, was vielleicht ein wenig mehr Arbeit erfordert, ist Zeile 15. Aber es ist auch ganz einfach. Wir verwenden zwei Operatoren new, um beide Klassen zu initialisieren.

Achten Sie auf die Informationen, die in Form von String-Variablen übergeben werden. Die erste String-Variable bezieht sich auf den Namen, der von MetaTrader 5 erkannt wird, wenn der Indikator im Chart angezeigt wird. Die zweite bezieht sich auf den Namen des Mauszeigers. Dies ist im Code des Mauszeigers definiert. Ausführlichere Informationen finden Sie in diesem Artikel: Entwicklung eines Replay Systems (Teil 41): Beginn der zweiten Phase (II).

Nachdem Sie nun gesehen haben, wie einfach der Code des Chart Trade-Indikators ist, wollen wir uns nun den Code der Klasse ansehen. Bitte denken Sie daran, dass der Code, den Sie sehen werden, der ursprüngliche Code ist und zusätzliche Elemente hinzugefügt werden, um den Indikator wirklich funktionsfähig zu machen.


Die Klasse C_ChartFloatingRAD

Trotz des Namens ist diese Klasse in erster Linie für die Arbeit mit dem Indikator Chart Trade gedacht. Im gegenwärtigen Entwicklungsstadium enthält es bereits die gesamte notwendige Logik, um uns ein Verhalten wie in Video 01 zu ermöglichen. Das heißt, wenn wir suchen, können wir das Fenster nicht verschieben, selbst wenn wir darauf klicken und die Maus ziehen. Das Fenster kann nicht verschoben werden, wenn die Studie läuft.

Es mag den Anschein haben, dass dazu die Erstellung eines komplexen Diagramms sowie eines Bildes im Video erforderlich ist, das bereits das endgültige Aussehen des Indikators zeigt. Wir wollen sehen, ob das stimmt. Schauen Sie sich einfach den Klassencode an. Der vollständige Code lautet wie folgt.

Quellcode der Klasse C_ChartFloatingRAD

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #include "../Auxiliar/C_Terminal.mqh"
05. #include "../Auxiliar/C_Mouse.mqh"
06. //+------------------------------------------------------------------+
07. class C_ChartFloatingRAD : private C_Terminal
08. {
09.     private :
10.             struct st00
11.             {
12.                     int     x, y, cx, cy;
13.                     string  szObj_Chart;
14.                     long    WinHandle;
15.             }m_Info;
16. //+------------------------------------------------------------------+
17.             C_Mouse *m_Mouse;
18. //+------------------------------------------------------------------+
19.             void CreateWindowRAD(int x, int y, int w, int h)
20.                     {
21.                             m_Info.szObj_Chart = (string)ObjectsTotal(GetInfoTerminal().ID);
22.                             ObjectCreate(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJ_CHART, 0, 0, 0);
23.                             ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_XDISTANCE, m_Info.x = x);
24.                             ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_YDISTANCE, m_Info.y = y);
25.                             ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_XSIZE, w);
26.                             ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_YSIZE, h);
27.                             ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_DATE_SCALE, false);
28.                             ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_PRICE_SCALE, false);
29.                             m_Info.WinHandle = ObjectGetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_CHART_ID);
30.                             m_Info.cx = w;
31.                             m_Info.cy = 26;
32.                     };
33. //+------------------------------------------------------------------+
34. inline void UpdateChartTemplate(void)
35.                     {
36.                             ChartApplyTemplate(m_Info.WinHandle, "IDE_RAD.tpl");
37.                             ChartRedraw(m_Info.WinHandle);
38.                     }
39. //+------------------------------------------------------------------+
40.     public  :
41. //+------------------------------------------------------------------+
42.             C_ChartFloatingRAD(string szShortName, C_Mouse *MousePtr)
43.                     :C_Terminal()
44.                     {
45.                             if (!IndicatorCheckPass(szShortName)) SetUserError(C_Terminal::ERR_Unknown);
46.                             m_Mouse = MousePtr;
47.                             CreateWindowRAD(0, 0, 170, 240);
48.                             UpdateChartTemplate();
49.                     }
50. //+------------------------------------------------------------------+
51.             ~C_ChartFloatingRAD()
52.                     {
53.                             ObjectDelete(GetInfoTerminal().ID, m_Info.szObj_Chart);
54.                             delete m_Mouse;
55.                     }
56. //+------------------------------------------------------------------+
57.             void DispatchMessage(const int id, const long &lparam, const double &dparam, const string &sparam)
58.                     {
59.                             static int sx = -1, sy = -1;
60.                             int x, y, mx, my;
61.     
62.                             switch (id)
63.                             {
64.                                     case CHARTEVENT_MOUSE_MOVE:
65.                                             if ((*m_Mouse).CheckClick(C_Mouse::eClickLeft))
66.                                             {
67.                                                     x = (int)lparam;
68.                                                     y = (int)dparam;
69.                                                     if ((x > m_Info.x) && (x < (m_Info.x + m_Info.cx)) && (y > m_Info.y) && (y < (m_Info.y + m_Info.cy)))
70.                                                     {
71.                                                             if (sx < 0)
72.                                                             {
73.                                                                     ChartSetInteger(GetInfoTerminal().ID, CHART_MOUSE_SCROLL, false);
74.                                                                     sx = x - m_Info.x;
75.                                                                     sy = y - m_Info.y;
76.                                                             }
77.                                                             if ((mx = x - sx) > 0) ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_XDISTANCE, m_Info.x = mx);
78.                                                             if ((my = y - sy) > 0) ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_YDISTANCE, m_Info.y = my);
79.                                                     }
80.                                             }else if (sx > 0)
81.                                             {
82.                                                     ChartSetInteger(GetInfoTerminal().ID, CHART_MOUSE_SCROLL, true);                                                
83.                                                     sx = sy = -1;
84.                                             }
85.                                             break;
86.                             }
87.                     }
88. //+------------------------------------------------------------------+
89. };
90. //+------------------------------------------------------------------+
91. 

Ist das alles? Wo sind die Codes für die Objekterstellung? Mausmanipulation?

Ich kann nicht glauben, dass diese beiden einfachen Codes das tun können, was in Video 01 gezeigt wird. Scheint ein Witz zu sein. Aber ich mache keine Witze. Mit diesen wenigen Zeilen kann das in Abbildung 01 gezeigte Fenster wie in Video 01 dargestellt funktionieren.

Sie können das Chart mit der Maus studieren, Sie können klicken und das Chart Trade-Fenster verschieben, und das alles nur dank dieses Codes. Zu diesem Klassencode werden noch einige Dinge hinzugefügt, damit das Fenster funktioniert und das Asset angezeigt werden kann. Die Schaltflächen werden funktionsfähig und Sie können Werte bearbeiten, die noch nicht angezeigt werden. Es fehlen zwar noch ein paar weitere Optimierungen, aber erwarten Sie nicht, dass diese Objekte hier erstellt werden. Ich verwende eine andere Methode, um unser Fenster funktional zu gestalten, und werde sie im nächsten Artikel vorstellen.

Aber halt, wir sind noch nicht fertig. Um wirklich zu verstehen, was hier vor sich geht, sollten wir uns die Erklärung des Klassencodes ansehen und warum er diesen speziellen Code enthält.

Beginnen wir in Zeile 07. Beachten Sie, dass die Klasse C_ChartFloatingRAD von der Klasse C_Terminal erbt. Da wir der Vererbung immer minimale Privilegien einräumen müssen, machen wir die Vererbung privat. Auf diese Weise hat kein anderer Code Zugriff auf die Klasse C_Terminal, zumindest nicht über die Klasse C_ChartFloatingRAD. Dies ist kein Problem, da der Indikator-Code keinen C_Terminal-Klassencode enthält.

Wenn Sie diesen Punkt verstanden haben, können Sie mit dem Konstruktor fortfahren. Dadurch wird der Ausführungsprozess leichter zu verstehen sein.

Der Konstruktor beginnt in Zeile 42. Beachten Sie, dass es eine Zeichenkette und ein Objekt, eigentlich einen Zeiger, benötigt, um auf den Mauszeiger zu verweisen. In Zeile 43 führen wir die notwendige Initialisierung der Klasse C_Terminal durch. Wenn wir zum Konstruktorcode gehen, beginnen wir in Zeile 45 mit einem Aufruf des Verifizierungscodes, um sicherzustellen, dass der Chart Trade-Indikator nicht auf dem Chart ist. Wenn diese Prüfung fehlschlägt, wird dies in der Konstante _LastError mit dem Aufruf SetUserError angezeigt.

Bitte beachten Sie die folgenden Hinweise. Wenn Sie nicht verstehen, was ich jetzt erkläre, werden Sie den Rest dieser Serie nicht mehr verstehen. Deshalb sollten Sie genau aufpassen, was ich sage.

In Zeile 46 speichern wir den Zeiger, der mit dem Aufruf des Operators new übergeben wurde. Dies geschieht im Code des Indikators Chart Trade. Sie können diesen Aufruf in Zeile 15 des Indikator-Codes sehen. Es SPIELT KEINE ROLLE ob der Mausindikator zum Zeitpunkt der Ausführung der Linie 46 auf dem Chart vorhanden ist. Ich wiederhole, weil es wichtig ist: Das Vorhandensein eines Indikators auf dem Chart zum Zeitpunkt des Anrufs SPIELT KEINE ROLLE.

Was wirklich wichtig ist (und was viele vielleicht nicht verstehen), ist der Name, der in dem in Zeile 15 des Chart Trade Indikator-Codes sichtbaren Aufruf übergeben wird. Diese String-Variable, die an den Konstruktor der Klasse C_Mouse übergeben wird, ist das Entscheidende. Aber nicht das Vorhandensein oder Nichtvorhandensein des Indikators auf dem Chart.

Das mag auf den ersten Blick unsinnig erscheinen. Aber es ist so. Um es zu verstehen, müssen Sie zum vorherigen Artikel Entwicklung eines Replay Systems (Teil 41): Beginn der zweiten Phase (II) zurückkehren und achten Sie auf die Zeile 169 im Code der Klasse C_Mouse. Nur diese Zeile gewährleistet das korrekte Funktionieren des in der Klasse C_ChartFloatingRAD dargestellten Codes. Daher ist es notwendig, den Namen des Mausindikators korrekt anzugeben, damit die MetaTrader 5-Plattform ihn finden kann, wenn die Zeile 169 in der Klasse C_Mouse ausgeführt werden muss.

Das mag immer noch verwirrend erscheinen, also erklären wir Ihnen jetzt, wie der Code funktioniert. Wir werden später auf diesen Punkt zurückkommen, um die Dinge zu verdeutlichen.

In Zeile 47 rufen wir die Funktion aus Zeile 19 auf. Diese Funktion in Zeile 19 ist einfach eine Prozedur, die ein OBJ_CHART-Objekt auf dem Chart erstellt. Nur dies. In Zeile 29 speichern wir jedoch die ID dieses Objekts, damit wir es später auf eine ganz bestimmte Weise verwenden können. Ich denke, dass niemand Schwierigkeiten haben wird, die restlichen Zeilen dieses Verfahrens zu verstehen.

Wenn man zum Konstruktor-Code zurückkehrt, findet man einen weiteren Aufruf in Zeile 48. Dieser Aufruf führt aus, was in Zeile 34 angezeigt wird. Im Moment haben wir zwei Zeilen 36 und 37. In Zeile 36 wird nach der von uns angegebenen Vorlage gesucht, die genau der in Abbildung 01 gezeigten entspricht. In Zeile 37 zwingen wir MetaTrader 5, das Objekt OBJ_CHART zu aktualisieren, damit die Vorlage angezeigt wird.

Daher präsentieren wir unseren Chart Trade. Nun, sie ist noch nicht funktionsfähig. Wir können jedoch einige „Manipulationen“ vornehmen, um die Interaktion zwischen dem Mausindikator und dem Chart Trade Indikator zu verstehen.

Der Code des Destruktors ist recht einfach und bedarf keiner großen Erklärung. Schauen wir uns den Code für die Nachrichtenverarbeitung genauer an: Die Prozedur DispatchMessage beginnt in Zeile 57. Hier findet die Interaktion zwischen den beiden Indikatoren statt.

Im Grunde werden wir jetzt nur das Mausbewegungsereignis behandeln, das in Zeile 64 beginnt. Achtung: Wir werden dies nicht auf die übliche Weise tun. Wir werden das Mausbewegungsereignis völlig anders behandeln. Für diejenigen, die es gewohnt sind, auf eine bestimmte Art und Weise zu programmieren, mag dies als sehr verrückt erscheinen.  

Zum besseren Verständnis (und das ist der Grund, warum ich in diesem Artikel keine anderen Dinge zeige), müssen Sie sich auf das vorherige Material Entwicklung eines Replay Systems (Teil 41): Beginn der zweiten Phase (II) beziehen. Wir haben es nicht mit einem, sondern mit zwei Indikatoren gleichzeitig zu tun. Sie interagieren und koexistieren in Harmonie, und der Nutzer kann das tun, was in Video 01 gezeigt wird.

In diesem Code für die Verarbeitung der Indikatormeldungen von Chart Trade wird der Mausindikator nur einmal erwähnt. Er wird in Zeile 65 erwähnt. Versuchen Sie zu verstehen, was vor sich geht. Wenn Sie das verstanden haben, wird der Rest einfach sein.

Hier kann es zwei Situationen geben. Die erste ist, wenn der Mausindikator auf dem Chart ist, die zweite, wenn der Indikator nicht auf dem Chart ist. Ich möchte Sie daran erinnern, dass der Indikator den Namen haben muss, den wir im Konstruktor der Klasse C_ChartFloatingRAD angegeben haben. Wenn der Name anders lautet, hilft uns MetaTrader 5 nicht weiter, und wir stehen vor der Situation, dass der Indikator nicht im Chart angezeigt wird. Achten Sie auf dieses Detail.

Sobald dies klar ist und Sie sich über diese beiden Situationen im Klaren sind, können wir mit weiteren Erklärungen beginnen.

In diesem Fall wird der Aufruf in Zeile 65 den Aufruf in Zeile 158 der Klasse C_Mouse (aus dem vorherigen Artikel) ausführen. In Zeile 15 des Codes des Indikators Chart Trade teilen wir dem Konstruktor der Klasse C_Mouse mit, dass wir die Klasse C_Mouse als Übersetzer verwenden werden. Zeile 158 der Klasse C_Mouse ruft Zeile 163 auf, um zu prüfen, ob die in Zeile 65 der Klasse C_ChartFloatingRAD angegebene Schaltfläche angeklickt wurde.

In dem Moment, in dem Zeile 165 in der Klasse C_Mouse ausgeführt wird, versteht der Code, dass wir einen Übersetzer verwenden. Wir führen dann Zeile 169 aus, um den Mauszeiger-Handle zu erfassen. Zu diesem Zeitpunkt werden wir uns an MetaTrader 5 wenden, um Hilfe zu erhalten, daher müssen die angegebenen Namen übereinstimmen. Wenn MetaTrader 5 den Indikator findet, auf den wir verweisen, erhält das Handle einen Index, um auf den Puffer des Indikators zuzugreifen. Wenn der Puffer gelesen werden kann, werden in Zeile 172 die Mauszeigerdaten erfasst. Wenn der Puffer nicht gelesen werden kann, schlägt die Funktion fehl, was auch die Funktion in Zeile 158 zum Scheitern bringt. Dies führt dazu, dass die Prüfung in Zeile 65 der Klasse C_ChartFloatingRAD fehlschlägt. So erhalten wir einen Hinweis, dass der Klick nicht stattgefunden hat.

Diese Logik funktioniert in zwei Situationen:

  • Wenn der Mauszeiger im Chart fehlt. Vergessen Sie nicht, dass er denselben Namen haben muss wie der angegebene, damit MetaTrader 5 ihn finden kann.
  • Wenn wir mit dem Mausindikator auf dem Chart suchen.

In einer dieser beiden Situationen wird in Zeile 65 der Klasse C_ChartFloatingRAD ein Mausklickfehler angezeigt.

Erscheint Ihnen dieser Teil verwirrend? Aber keine Sorge, ab hier wird es noch interessanter.

Analysieren wir nun eine Situation, in der MetaTrader 5 den Maus-Indikator findet und wir den Chart Trade-Indikator auf dem Chart verschieben wollen, wie in Video 01 gezeigt. Um zu verstehen, wie dies geschehen wird, müssen Sie die folgenden Artikel verstehen:

Jeder dieser Artikel ist eine Vorbereitung auf das, was noch kommen wird. Wenn Sie sie nicht gelesen haben oder den Inhalt nicht verstehen, schlage ich vor, dass Sie sie noch einmal lesen und verstehen, wie Kommunikation funktioniert. Auch wenn es einfach erscheint, sind diese Konzepte in der Praxis schwer zu verstehen, vor allem für diejenigen, die solche Methoden nicht anwenden.

Was ich hier zeige, ist der einfachste Teil von allen. Im Vergleich zu dem, was danach kommt, wird es wie eine Vorschulerziehung erscheinen. Daher ist es sehr wichtig zu verstehen, wie dieser Code funktioniert.

Irgendwann wird der Aufruf von C_ChartFloatingRAD in Zeile 65 auf den Aufruf von C_Mouse in Zeile 181 treffen. In diesem Fall wird in Zeile 160 der Klasse C_Mouse der übergebene Tastencode überprüft. Wenn der Code mit dem übergebenen Code übereinstimmt, gibt die Funktion true zurück. In diesem Moment und solange die Maustaste gedrückt ist, wird der Code zwischen den Zeilen 67 und 79 ausgeführt.

Es gibt einen kleinen Fehler in diesem Code, aber da es sich um einen Demo-Code handelt, können Sie ihn vorerst ignorieren.

Nun stellt sich die Frage: Warum verwende ich in den Zeilen 67 und 68 die vom MetaTrader 5 bereitgestellten Werte und nicht den Mausindikator? Natürlich nicht, weil es hübscher oder einfacher ist. Es gibt einen Grund, die von MetaTrader 5 bereitgestellten Werte zu verwenden und nicht die Indikatorwerte. Um dies zu verstehen, müssen Sie sich den Code in der Klasse C_Mouse zwischen den Zeilen 203 und 206 ansehen. In diesen Zeilen führen wir die Transformation und Anpassung der Mauskoordinaten durch. In diesem Fall sind die Mauskoordinaten nicht mehr auf dem Bildschirm (x und y), sondern werden aktiv (Preis und Zeit).

Dies ist sehr nützlich für die Arbeit mit bestimmten Arten von Problemen, aber problematisch, wenn wir anders arbeiten müssen. Wenn wir in den Zeilen 67 und 68 der Klasse C_ChartFloatingRAD ähnlichen Code wie den folgenden verwenden:

x = (*m_Mouse).GetInfoMouse().Position.X;
y = (*m_Mouse).GetInfoMouse().Position.Y;

Wir erhalten die Bewegung des OBJ_CHART-Objekts, als ob es an die Koordinaten des Vermögenswerts (Preis und Zeit) gebunden wäre. In der Realität verwendet ein solches Objekt jedoch Bildschirmkoordinaten (x, y), sodass die Bewegung ziemlich seltsam und nicht so flüssig wie in Video 01 sein wird. Für einige Arten von Objekten ist es tatsächlich wünschenswert, die vom Mauszeiger gelieferten Koordinaten zu verwenden.


Schlussfolgerung

In diesem Artikel haben wir uns die erste Stufe der Erstellung eines Chart Trade-Indikators angesehen. Ich habe gezeigt, wie Sie den Maus-Indikator in perfekter Harmonie mit dem Chart Trade-Indikator verwenden können, den wir gerade erstellen, der jedoch noch keine anderen Funktionen als die Möglichkeit des Ziehens und Ablegens auf dem Chart hat.

Im nächsten Artikel werden wir uns mit der Erweiterung der Funktionalität von Chart Trade beschäftigen.


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

Beigefügte Dateien |
Anexo.zip (420.65 KB)
Entwicklung eines Replay Systems (Teil 43): Chart Trader Projekt (II) Entwicklung eines Replay Systems (Teil 43): Chart Trader Projekt (II)
Die meisten Menschen, die programmieren lernen wollen oder davon träumen, haben eigentlich keine Ahnung, was sie da tun. Ihre Tätigkeit besteht darin, dass sie versuchen, Dinge auf eine bestimmte Art und Weise zu schaffen. Bei der Programmierung geht es jedoch nicht darum, geeignete Lösungen zu finden. Auf diese Weise können mehr Probleme als Lösungen entstehen. Hier werden wir etwas Fortgeschritteneres und daher etwas anderes machen.
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 24): Gleitende Durchschnitte MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 24): Gleitende Durchschnitte
Gleitende Durchschnitte sind ein sehr verbreiteter Indikator, der von den meisten Händlern verwendet und verstanden wird. Wir erforschen mögliche Anwendungsfälle, die in den mit dem MQL5-Assistenten zusammengestellten Expert Advisors vielleicht nicht so häufig vorkommen.
Eine alternative Log-datei mit der Verwendung der HTML und CSS Eine alternative Log-datei mit der Verwendung der HTML und CSS
In diesem Artikel werden wir eine sehr einfache, aber leistungsfähige Bibliothek zur Erstellung der HTML-Dateien schreiben, dabei lernen wir auch, wie man eine ihre Darstellung einstellen kann (nach seinem Geschmack) und sehen wir, wie man es leicht in seinem Expert Advisor oder Skript hinzufügen oder verwenden kann.
Automatisierte Parameter-Optimierung für Handelsstrategien mit Python und MQL5 Automatisierte Parameter-Optimierung für Handelsstrategien mit Python und MQL5
Es gibt mehrere Arten von Algorithmen zur Selbstoptimierung von Handelsstrategien und Parametern. Diese Algorithmen werden zur automatischen Verbesserung von Handelsstrategien auf der Grundlage historischer und aktueller Marktdaten eingesetzt. In diesem Artikel werden wir uns eine davon mit Python und MQL5-Beispielen ansehen.