English Русский 中文 Español 日本語 Português 한국어 Français Italiano Türkçe
preview
Mehrere Indikatoren in einem Chart (Teil 04): Weiterentwicklung zum Expert Advisor

Mehrere Indikatoren in einem Chart (Teil 04): Weiterentwicklung zum Expert Advisor

MetaTrader 5Handel |
379 5
Daniel Jose
Daniel Jose

Einführung

In meinen früheren Artikeln habe ich erklärt, wie man einen Indikator mit mehreren Unterfenstern erstellt, was bei der Verwendung von nutzerdefinierten Indikatoren interessant wird. Das war ziemlich einfach zu bewerkstelligen. Wenn wir jedoch versuchen, die gleiche Funktionsweise in einem Expert Advisor zu implementieren, wird es etwas komplizierter, da wir nicht über die Werkzeuge verfügen, die wir in einem nutzerdefinierten Indikator verwendet haben. An diesem Punkt wird das Programmieren unabdingbar: Die Fähigkeit, den richtigen Code zur Erstellung eines Unterfensters zu schreiben, ist von größter Bedeutung. Auch wenn diese Aufgabe nicht ganz einfach ist, erfordert das Wissen, wie man ein Unterfenster in einen EA einfügt, nicht viel Programmierarbeit, sondern nur einige Kenntnisse über die Arbeitsweise von MQL5.


Planung

Unser nutzerdefinierter Indikator funktioniert bereits, d. h. unsere Objektklasse ist bereits funktionsfähig, und da es sich um eine Objektklasse handelt, können wir sie problemlos auf andere Modelle übertragen. Wenn wir die Klasse jedoch einfach deklarieren und versuchen, sie in unserem EA zu verwenden, werden die Dinge nicht so funktionieren wie in unserem nutzerdefinierten Indikator, und der Grund dafür ist, dass wir in unserem EA keine Fähigkeit zu Unterfenstern haben. Aber dann kam die Idee: "Was wäre, wenn wir einen bereits kompilierten und funktionierenden nutzerdefinierten Indikator verwenden und ihn vom EA aus mit dem Befehl iCustom aufrufen? Nun, das könnte tatsächlich funktionieren, da das Unterfenster nicht benötigt wird und der Befehl wie folgt aussehen würde:

#property copyright "Daniel Jose"
//+------------------------------------------------------------------+
input string user01 = "";                //Used indicators
input string user02 = "";                //Assets to follow
//+------------------------------------------------------------------+
int OnInit()
{
        int m_handleSub;

//... Expert Advisor code ...

        if ((m_handleSub = iCustom(NULL, 0, "Chart In SubWindows\\Chart In SubWindow.ex5", user01, user02)) == INVALID_HANDLE) return INIT_FAILED;
        if (!ChartIndicatorAdd(ChartID(), 0, m_handleSub)) return INIT_FAILED;
//... Expert Advisor code ...

        ChartRedraw();
        
        return(INIT_SUCCEEDED);
}
//...The rest of the Expert Advisor code ...

Dieses einfache Codeschnipsel ist in der Lage, unseren nutzerdefinierten Indikator zu laden, obwohl er nicht richtig funktioniert, weil wir kein Unterfenster haben. In diesem Fall, wenn der Code im EA ausgeführt wird, läuft unser Indikator durch den EA direkt im Hauptfenster, was bedeutet, dass unser Chart durch die vom Indikator geladenen Vorlagen verdeckt wird, was definitiv nicht das ist, was wir wollen.

Unser reales Hauptproblem besteht also darin, ein Unterfenster zu erstellen, in dem wir unseren bereits funktionierenden Indikator verwenden können. Aber warum ein Unterfenster für den späteren Start unseres Indikators erstellen? Das macht keinen Sinn, es ist besser, die Funktion direkt in unseren EA einzubauen und so eventuelle Einschränkungen zu überwinden.

Auf dieser Grundlage müssen wir mehrere Aufgaben erfüllen:

Aufgabe Zweck
1 => Erstellen eines Allzweckindikators. Er ermöglicht das Erstellen und Verwenden des iCustom-Befehls, ohne den Chart zu verderben.
2 => Binden Sie diesen Indikator auf irgendeine Weise in den EA ein.  So können Sie den Expert Advisor mit voller Funktionalität problemlos übertragen.
3 => Generieren Sie eine allgemeine Objektklasse für das Unterfenster.  Ermöglicht das Hinzufügen von Unterfenstern über den EA.
4 => Holen Sie sich unsere Klasse C_TemplateChart, die an die Fensterklasse gebunden ist. So können wir den Inhalt von Unterfenstern verwalten, ohne etwas am bereits laufenden Code zu ändern.

Obwohl dies schwierig erscheinen mag, sind die Schwierigkeiten recht einfach zu lösen. Gehen wir also auf jeden der Punkte ein.


Die Implementierung: Erstellen eines Allzweckindikators

Dieser Teil kann durch die Erstellung eines völlig sauberen, aber funktionalen, nutzerdefinierten Indikatorcodes gelöst werden. Der Code sieht in diesem Fall wie folgt aus:

#property copyright "Daniel Jose"
#property version   "1.00"
#property description "This file only enables support of indicators in SubWin."
#property indicator_chart_window
#property indicator_plots 0
//+------------------------------------------------------------------+
int OnInit()
{
        return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
{
        return rates_total;
}
//+------------------------------------------------------------------+


Nur dies und nichts weiter. Wir speichern diese Datei unter dem Namen SubSupport.mq5. Aber sie wird nicht zusammen mit anderen Indikatoren gespeichert, sondern im Verzeichnis RESOURCE unseres Expert Advisors. Die Dateistruktur sieht dann wie in der folgenden Abbildung aus:


Es gibt einen guten Grund dafür, aber lassen wir ihn vorerst beiseite. Gehen wir nun zur nächsten Aufgabe über.


Implementierung: Einbinden des allgemeinen Indikators in den EA

Dazu müssen wir den folgenden Code oben in unseren EA einfügen.

//+------------------------------------------------------------------+
#define def_Resource "Resources\\SubSupport.ex5"
//+------------------------------------------------------------------+
#resource def_Resource
//+------------------------------------------------------------------+

Dadurch wird der kompilierte Code des allgemeinen Indikators in unseren EA aufgenommen. Sobald dies geschehen ist, wird die .ex5-Datei des allgemeinen Indikators gelöscht, da sie nicht mehr benötigt wird. Nun sollten Sie darauf achten, dass, wenn die SubSupport.ex5 Datei zum Zeitpunkt der Kompilierung des EA-Codes nicht gefunden wird, der Compiler automatisch den Code des SubSupport.mq5 allgemeinen Indikators kompilieren und diese neu kompilierte ausführbare Datei zu unserem Expert Advisor hinzufügen. Wenn Sie also die Datei SubSupport.mq5 bearbeiten und die Änderungen in den Expert Advisor einfügen möchten, sollten Sie SubSupport.ex5 löschen; andernfalls werden die Änderungen nicht hinzugefügt.

Dieses Detail ist wichtig: Manchmal muss man wirklich wissen, wie man neu implementierte Änderungen zur Ressource hinzufügt.

Nun, der allgemeine Indikator ist jetzt Teil des Expert Advisors, also gehen wir zur nächsten Aufgabe über.


Implementierung : Erstellen einer Unterfenster-Objektklasse

Auch dieser Teil ist einfach. Hier müssen wir vor der Codierung einige Punkte definieren, nämlich: welche Funktionen brauchen wir wirklich in dieser Klasse? Ursprünglich habe ich mich für Folgendes entschieden:

Funktion Beschreibung
Init Ermöglicht das Hinzufügen von Unterfenstern über den EA.
Close Ermöglicht das Hinzufügen von Unterfenstern über den EA.

Diese Funktionen werden nicht getestet, daher gehe ich davon aus, dass sie während der Lebensdauer des EA nur einmal aufgerufen werden. Aber da unser EA umfangreicher wird, ist es gut, darüber nachzudenken, wie wir ihn in Zukunft noch praktischer machen können. Deshalb erstellen wir eine neue Objektklasse mit dem Namen C_Terminal - diese Klasse wird ein paar Dinge im Zusammenhang mit dem grafischen Terminal unterstützen. Wir werden später mehr darüber erfahren. Sehen wir uns die letzte Aufgabe an, da es keine Möglichkeit gibt, die Lösung teilweise zu implementieren.


Implementierung: C_TemplateChart Klassenvererbung

Als ich mich entschied, etwas Neues mit Hilfe von OOP (Objektorientierte Programmierung) zu erstellen, tat ich dies, weil ich bereits wusste, dass dieser Ansatz große Vorteile bietet, einschließlich Sicherheit und Vererbung. Es gibt auch Polymorphismus, aber wir werden ihn später bei der Erstellung eines auftragsübergreifenden Systems verwenden. In diesem speziellen Fall werden wir einen der Vorteile von OOP nutzen - die Vererbung. C_TemplateChart ist bereits eine voll funktionsfähige Klasse. Da möchte man sich nicht die Mühe machen, alles noch einmal neu zu programmieren, oder das Risiko eingehen, der Klasse Code hinzuzufügen, der verhindert, dass die Klasse an anderen Stellen verwendet werden kann. Die Lösung ist die Vererbung, die das Hinzufügen von neuem Code oder neuen Funktionen ermöglicht, ohne den ursprünglichen Code zu verändern.

Die Verwendung von Vererbung hat eine Reihe von Vorteilen, darunter die folgenden: bereits getesteter Code bleibt getestet; die Komplexität wächst, ohne dass die Größe des Codes im gleichen Maße zunimmt; nur neue Funktionen müssen wirklich getestet werden; was sich nicht ändert, wird einfach vererbt, was für Stabilität sorgt. Mit anderen Worten: Die Dinge verbessern sich mit minimalem Aufwand, aber mit maximaler Sicherheit. Um dies zu verstehen, sehen wir uns das folgende Diagramm an.


Die Großelternklasse ist die einfachste Klasse mit dem niedrigsten Level an Datenmanipulation, aber wenn die Elternklasse etwas von der Großelternklasse erbt, können alle Dinge, die in der Großelternklasse als öffentlich deklariert sind, von der Elternklasse gesehen und verwendet werden. Und wir können der Elternklasse auch neue Dinge hinzufügen, ohne dass dies Auswirkungen auf das hat, was geerbt und durch Vererbung unterstützt wird. Wenn die übergeordnete Klasse bereits fertig ist und funktioniert und wir sie erweitern wollen, ohne etwas an den darunter liegenden Klassen zu ändern, dann erstellen wir eine untergeordnete Klasse, die alle Funktionen der vorherigen Klassen hat. Wir können auch die Art und Weise ändern, wie die Dinge funktionieren, und das ist das Interessante an der Vererbung, denn diese Änderungen werden sich nicht auf andere Klassen auswirken. Allerdings gibt es hier eine Einschränkung, im Gegensatz zu C++, das Mehrfachvererbung erlaubt. Wenn ein Kind Funktionen sowohl von der Vater- als auch von der Mutterseite erben kann, ist dies in MQL5 nicht möglich. Aber man profitiert trotzdem von der Vererbung. Ein Beispiel für Mehrfachvererbung ist unten zu sehen:

Okay, aber wie macht man das in MQL5? Wie kann man eine Vererbung deklarieren, so dass wir den Vorteil daraus ziehen können? Der genaueste Weg, dies zu verstehen, ist, den Inhalt der objektorientierten Programmierung (OOP) zu lesen, aber hier kommen wir direkt auf den Punkt. Die Vererbung wird mit den folgenden Zeilen durchgeführt:

#include "C_TemplateChart.mqh"
//+------------------------------------------------------------------+
class C_SubWindow : public C_TemplateChart
{
// ... Class code
};

Sie sehen, dass die Klasse C_SubWindow die Klasse C_TemplateChart öffentlich erbt, so dass wir jetzt die Klasse C_SubWindow verwenden können, um auf die Funktionsweise der Klasse C_TemplateChart zuzugreifen.

In dem obigen Codeschnipsel habe ich eine Sache hervorgehoben. Beachten Sie, dass es in Anführungszeichen ( " ) und nicht wie üblich in spitzen Klammern ( < > ) steht. Warum habe ich das getan? Wie die Sprache C++ hat auch MQL5 einige sehr interessante Dinge, aber einige Dinge verwirren diejenigen, die gerade erst anfangen, die Kunst des Programmierens zu lernen. Wenn wir eine Header-Datei zwischen spitze Klammern ( < > ) setzen, meinen wir einen absoluten Pfad - in diesem Fall folgt der Compiler genau dem von uns angegebenen Pfad. Wenn wir jedoch Anführungszeichen verwenden (wie in diesem Fall), verwendet der Compiler einen relativen Pfad, oder, um es deutlicher zu machen, er beginnt mit dem aktuellen Verzeichnis, in dem sich die Arbeitsdatei befindet. Es mag seltsam erscheinen, aber es kommt vor, dass wir denselben Namen für Dateien mit unterschiedlichem Inhalt haben, die sich in verschiedenen Verzeichnissen befinden, aber wir wollen uns trotzdem auf das aktuelle Verzeichnis beziehen, also verwenden wir Anführungszeichen dafür.

Die beiden Funktionen, die wir früher verwenden wollen, INIT und CLOSE, sind unten dargestellt:

//+------------------------------------------------------------------+
bool Init(void)
{
        if (m_handleSub != INVALID_HANDLE) return true;
        if ((m_handleSub = iCustom(NULL, 0, "::" + def_Resource)) == INVALID_HANDLE) return false;
        m_IdSub = (int) ChartGetInteger(Terminal.Get_ID(), CHART_WINDOWS_TOTAL);
        if (!ChartIndicatorAdd(Terminal.Get_ID(), m_IdSub, m_handleSub)) return false;
                
        return true;
}
//+------------------------------------------------------------------+
void Close(void)
{
        ClearTemplateChart();
        if (m_handleSub == INVALID_HANDLE) return;
        IndicatorRelease(m_IdSub);
        ChartIndicatorDelete(Terminal.Get_ID(), m_IdSub, ChartIndicatorName(Terminal.Get_ID(), m_IdSub, 0));
        ChartRedraw();
        m_handleSub = INVALID_HANDLE;
}
//+------------------------------------------------------------------+

Sehen Sie, der Code ist sehr einfach und kurz. Aber es gibt etwas, auf das wir aufpassen müssen, achten Sie auf den hervorgehobenen Teil. Sie müssen aufpassen, dass Sie beim Hinzufügen dieses Teils keinen Fehler machen, denn wenn Sie ihn nicht so lassen, wie er ist, wird die ausführbare Datei SubSupport.ex5, um deren Hinzufügen zum EA wir gebeten haben, nicht innerhalb des EA sichtbar sein - stattdessen wird sie außerhalb des EA sichtbar sein. Für weitere Details lesen Sie über Ressourcen. Aber im Grunde genommen bedeutet die Verwendung von ( :: ), dass der EA die interne Ressource verwenden soll, die in ihm verfügbar ist. Wenn wir jedoch nur den Namen der Ressource angeben, sucht der EA im MQL5-Verzeichnis danach, und wenn die Datei am angegebenen Ort nicht existiert, schlägt die Funktion fehl, selbst wenn die Datei als EA-Ressource hinzugefügt wurde.

Sobald die Ressource geladen ist, wird die Anzahl der vorhandenen Unterfenster überprüft und ein Indikator zu diesem Unterfenster hinzugefügt.

Was der Code tatsächlich tut, ist unten zu sehen:

input string user01 = "";               //Used indicators
input string user02 = "";               //Assets to follows
//+------------------------------------------------------------------+
int OnInit()
{
        int m_handleSub;

//...   

        if ((m_handleSub = iCustom(NULL, 0, "Chart In SubWindows\\Chart In SubWindow.ex5", user01, user02)) == INVALID_HANDLE) return INIT_FAILED;
        if (!ChartIndicatorAdd(ChartID(), (int) ChartGetInteger(ChartID(), CHART_WINDOWS_TOTAL), m_handleSub)) return INIT_FAILED;

//...

        ChartRedraw();
        
   return(INIT_SUCCEEDED);
}
//...The rest of the Expert Advisor code ...


Beide Codes funktionieren gleich, aber die Objektklassenversion ermöglicht es uns, im Laufe der Zeit mehr Dinge hinzuzufügen, da die oben gezeigte Version die konsolidierte Version ist und sich nicht ändern wird. Beide Versionen tun das Gleiche: Sie erstellen ein Unterfenster des EA und legen alle zuvor erstellten nutzerdefinierten Indikatoren in diesem Unterfenster ab. Achten Sie auf die Änderungen im Code im Vergleich zum Code am Anfang des Artikels - die Änderungen sind farblich hervorgehoben.


Schlussfolgerung

Es ist sehr interessant, wie wir uns entscheiden, den Weg zur Erreichung unserer Ziele zu gehen. Manchmal stoßen wir auf Schwierigkeiten und denken, dass es schwierig ist, unsere Ziele zu erreichen, aber mit ein wenig Geduld und Hingabe können wir Hindernisse überwinden, die zunächst unüberwindbar schienen. In diesem Artikel zeige ich, wie man die Funktionalität einer Klasse erweitern kann, ohne sie verändern zu müssen - durch Vererbung. Gleichzeitig zeige ich, wie man Indikatoren zu Charts hinzufügen kann, so dass sie wie bereits getestet funktionieren. Wir fügen das ex5-Programm in unseren EA ein und verwenden es, ohne das ursprüngliche ex5 portieren zu müssen, indem wir einfach den EA laden.

Die angehängte Datei enthält alle Verbesserungen, die bisher entwickelt wurden, aber es wird bald noch mehr interessante Dinge in diesem Code geben. 😁👍


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

Beigefügte Dateien |
Letzte Kommentare | Zur Diskussion im Händlerforum (5)
Mateus Cerqueira Lopes
Mateus Cerqueira Lopes | 25 Feb. 2022 in 17:50
MetaQuotes:

Neuer Artikel Mehrere Indikatoren auf einem Chart (Teil 04): Start mit EA wurde veröffentlicht:

Autor: Daniel Jose

Hallo Daniel, ich habe deine Artikel verfolgt, aber was ist mit Teil 03?
Daniel Jose
Daniel Jose | 26 Feb. 2022 in 13:28
Mateus Lopes #:
Hallo Daniel, ich habe deine Artikel verfolgt, aber was ist mit Teil 03?

Es gab ein kleines Problem bei der Beantragung der Freigabe zur Veröffentlichung, aber ich habe die Veröffentlichung von Teil 03 bereits genehmigt, er wird auch bald verfügbar sein, dieses Problem wurde eher durch die Anzahl der Artikel verursacht, die ich bereits geschickt habe ... es gibt derzeit noch 15 weitere Artikel zu analysieren, die alle mit der Entwicklung dieses EA zu tun haben, und mit jedem Artikel werden die Dinge komplexer .... aber danke, dass Sie die Serie verfolgt haben ... freuen Sie sich auf viel Neues ab Artikel 05, ab dann wird es sich wirklich lohnen, denn es wird etwas Großes werden, diese ersten paar sind nur eine Einführung in das, was kommen wird...😁👍

CapeCoddah
CapeCoddah | 13 Mai 2022 in 13:00

Hallo Daniel,

ich habe Probleme mit mehrfarbigen Indikatoren und deine Artikel, die ich sehr schätze, deuten darauf hin, dass du vielleicht die Lösung kennst.

Ich möchte eine Funktion erstellen, die alle Indikatorattribute setzt, ohne die #property Optionen zu verwenden, z.B. #property indicator_color1 clrCrimson,clrWhite,clrLime

In dem unten stehenden Testprogramm stelle ich fest, dass das Programm mit dem #property indicator_color1 clrCrimson,clrWhite,clrLime richtig funktioniert, während das Programm nicht richtig funktioniert, wenn ich es auskommentiere.In diesem Fall scheint es, dass nur einige der Datenpunkte geplottet werden, als ob ein "höherer" Zeitrahmen verwendet wird oder mehrere Datenpunkte übersprungen werden. Ich vermute, dass die Eigenschaft color directive weitere Attribute setzt, die ich nicht identifiziert habe, wenn mehrere Farben angegeben werden.

Das zweite Problem ist, dass ich offensichtlich die Details und Anforderungen der Verwendung von mehrfarbigen Diagrammen nicht verstehe. Ich habe die Dokumentation durchsucht und keine Artikel gefunden, die einen Überblick über die Verwendung von mehrfarbigen Indikatoren geben. Während das erste Diagramm die Farbe korrekt ändert, ändert das zweite Diagramm, das die Tiefststände aufzeichnet, die Farben nicht entsprechend meinem Funktionsaufruf. Für diese Darstellung sind alle drei Eigenschaften erforderlich: type2, color2 und width2. Ich bin auch ratlos, warum die Eigenschaftsdeklarationen 2 statt 3 verwenden. Ich habe den Laguerre Adaptive Filter Indikator von Mladen verwendet, um festzustellen, dass die Eigenschaftsindikatoren die Plotnummer 2 und nicht die Indikatornummer 3 verwenden, um korrekt angezeigt zu werden.

Für Vorschläge, Hinweise oder Hilfe bin ich sehr dankbar.

Mit freundlichen Grüßen, CapeCoddah

Daniel Jose
Daniel Jose | 21 Mai 2022 in 17:18
CapeCoddah Indikatoren geben. Während die erste Grafik die Farbe korrekt ändert, ändert die zweite Grafik, die die Tiefpunkte nachzeichnet, die Farbe nicht entsprechend meinem Funktionsaufruf. Diese Grafik benötigt alle drei Eigenschaften: type2, color2 und width2, um richtig zu funktionieren. Ich frage mich auch, warum die Eigenschaftsdeklarationen 2 statt 3 verwenden. Ich habe den Laguerre Adaptive Filter Indikator von Mladen verwendet, um herauszufinden, dass Eigenschaftsindikatoren die Diagrammnummer 2 und nicht die Indikatornummer 3 verwenden, um korrekt angezeigt zu werden.

Für Vorschläge, Hinweise oder Hilfe bin ich sehr dankbar.

Mit freundlichen Grüßen, CapeCoddah

Ich kann verstehen, dass Sie ein wenig verwirrt sind... aber die ganze Verwirrung liegt darin, dass Sie nicht wirklich auf die Details in Ihrem Code achten. Ich werde versuchen, einige der Details zu erklären, die in dem Kommentar stehen, dann werde ich ein wenig über Ihren Code sprechen....

Der erste Punkt ist, dass Sie sogar einen mehrfarbigen Indikator erzeugen können, ohne #property indicator_colorN zu verwenden, aber für den Benutzer und auch für Sie ist es praktischer, sicherer und einfacher, den Code zu verstehen und zu ändern, denn alles, was Sie tun müssen, ist, zu den Eigenschaften zu gehen, um die dort vorhandenen Farben zu ändern, und für den Benutzer ist es einfacher, weil er nur die zu ändernde Farbe auswählen und die Änderung vornehmen muss, und zwar in dem Standardfenster, das MT5 für die Indikatoren erstellt. Sie machen es schon irgendwie richtig, wenn Sie den Befehl PlotIndexSetInteger verwenden, um die Farbänderungen zu generieren, und das ist der Weg, wenn wir #property indicator_colorN nicht verwenden, aber wenn wir die Eigenschaften verwenden, macht es oft keinen Sinn, den Befehl PlotIndexSetInteger zu verwenden, um andere Farben zu setzen, Das liegt daran, dass die Sache komplizierter zu pflegen und verwirrender für den Benutzer sein kann, da er vielleicht nicht wirklich versteht, was der Farbstandard zu sagen versucht, selbst wenn der Code Ihnen gehört und Sie der einzige sind, der den Indikator verwendet, macht es nicht viel Sinn, außer in seltenen Fällen, wenn Sie ein dynamisches Farbmuster erstellen.

Nun zum zweiten Punkt: Das Problem in diesem Fall ist, dass Sie die Anzahl der Dinge, die der Indikator plotten wird ( 2 für 2 Linien ) mit den Objekteigenschaften ( in diesem Fall Linie ) verwechseln und für die Linie, die geplottet werden soll, müssen Sie tatsächlich mindestens 3 Informationen deklarieren, nämlich TypeN, ColorN, WidthN, wobei das N die Nummer des Objekts angibt, mit Übung und Zeit werden Sie am Ende diese kleinen Unterschiede zwischen der Indikatoreigenschaft und den Eigenschaften der Objekte, die er verwendet, verstehen... Gib nicht auf... lerne weiter und bald werden die Dinge klarer werden... 😁👍

Jetzt zeige ich dir mal einen Teil deines Codes... Ich werde dir nicht genau zeigen, wie du ihn reparieren kannst (wenn ich das tue, macht es keinen Spaß... .... 😁👍✌ ), aber ich möchte, dass du auf die folgende Tatsache achtest, und das ist wichtig:

      Buf=Set_IndexBuffer5(Buf, dataHi, INDICATOR_DATA , DRAW_COLOR_LINE , 4 ,
"High" , clrYellow , clrWhite , clrDodgerBlue );
      Buf=Set_IndexBuffer5(Buf, dataHic, INDICATOR_COLOR_INDEX );
      Buf=Set_IndexBuffer5(Buf, dataLo, INDICATOR_DATA , DRAW_COLOR_LINE , 4 ,
"Low" , clrYellow , clrWhite , clrDodgerBlue );
      Buf=Set_IndexBuffer5(Buf, dataLoc, INDICATOR_COLOR_INDEX );

Beachten Sie, dass ich zwei Dinge in Ihrem Code markiert habe... sehen wir uns nun an, was passiert, wenn der Code im Diagramm abgespielt wird....


Sehen Sie, dass nur eine der Beschriftungen so ist, wie Sie es im Code deklariert haben, nur die HIGH .... und die LOW ?!?! wo ist sie ?!?! das ist der erste Punkt, den Sie korrigieren sollten, denn die Tatsache, dass die LOW-Marke nicht angezeigt wird, zeigt an, dass das verwendete Farbmuster das ist, was in #property indicator_color2 deklariert ist, d.h. Sie haben an diesem Punkt einen Fehler, wenn Sie versuchen, die Eigenschaften von Indikator 2 zu entfernen, die tatsächlich die LOW-Linie erzeugen, auch wenn Sie den Rest des Codes beibehalten, wird die HIGH-Linie gezeichnet, aber die LOW-Linie wird nicht....warum?!?! weil Sie in der Tat nicht die Informationen definieren, die notwendig sind, um die LOW-Linie zu plotten, und zwar dynamisch über die Verwendung des PlotIndexSetInteger-Aufrufs... es scheint seltsam ... aber das ist, was passiert ....

Wenn es Ihnen gelingt, dies zu beheben, können Sie, wenn Sie wirklich den dynamischen Weg der Deklaration der Daten des Zeilenobjekts mit PlotIndexSetInteger nutzen wollen, die #property indicator_color Kompilierungsbefehle aus der Szene entfernen, da die notwendigen Daten dynamisch gesetzt werden, aber wenn Sie sich diese Mühe nicht machen wollen, ist das in Ordnung....

Jetzt möchte ich, dass du dir das obige Bild ansiehst und es mit den Farben vergleichst, die du in #property indicator_color verwendest ... beobachte diese Farben sehr genau .... wenn du das tust, wirst du dort etwas Seltsames bemerken .... noch einmal, ich werde nicht sagen, dass du den Spaß nicht verlieren sollst, aber versuche, verschiedene Farben zu verwenden, ohne eine von ihnen zu wiederholen ... wenn du sie wiederholst, wird es schwieriger zu verstehen, wo der Fehler liegt ... 😁👍

Nun noch ein letztes Detail: Die Tatsache, dass du denkst, dass er nur einige Punkte aufzeichnet und andere überspringt, kann zwei Gründe haben: Das Farbmuster kontrastiert nicht mit dem Hintergrund des Diagramms, versuchen Sie, Farben zu verwenden, die mit dem Hintergrund des Diagramms kontrastieren, und der zweite, aber ich glaube nicht, dass es tatsächlich der Fall ist, ist, dass es einen Fehler im OnCalcule-Ereignis geben kann, Sie geben -1 oder den Wert von i zurück, das Richtige ist, rates_total zurückzugeben, also ändern Sie dies im Code, um Probleme in der Zukunft zu vermeiden...

CapeCoddah
CapeCoddah | 26 Mai 2022 in 13:24

Hallo Daniel,

ich war verwirrt: Ich dachte, die Zeicheneigenschaften würden wie bei MQ4 über die Pufferspezifikation definiert, während zumindest bei den DRAW_COLOR... Spezifikationen die Zeicheneigenschaften über den sequentiellen Plot-Identifier definiert werden. Ich habe nicht herausgefunden, ob die DRAW_LINE usw. auch Plot-Spezifikationen erfordern. Außerdem hat die indicator_colorX-Eigenschaft eigentlich zwei Funktionen, zunächst zum Zählen und Einstellen der Anzahl der Farben und dann zum Einstellen jeder angegebenen Farbe in die richtige Array-Position.Ich hänge zwei Dateien an, Color Test, das jetzt korrekt funktioniert, obwohl es noch weitere Verfeinerungen benötigt, und MACD Original2_1 von MLADEN, das leicht modifiziert wurde. Das Programm von Mladen ist interessant, da er zwei Plots definiert hat, aber nur einen Farbindexpuffer verwendet.


Vielen Dank für Ihre Hilfe

Grafiken in der DoEasy-Bibliothek (Teil 99): Verschieben eines erweiterten grafischen Objekts mit einem einzigen Steuerpunkt Grafiken in der DoEasy-Bibliothek (Teil 99): Verschieben eines erweiterten grafischen Objekts mit einem einzigen Steuerpunkt
Im vorigen Artikel habe ich die Möglichkeit implementiert, Angelpunkte eines erweiterten grafischen Objekts mithilfe von Steuerformularen zu verschieben. Jetzt werde ich die Möglichkeit implementieren, ein zusammengesetztes grafisches Objekt mithilfe eines einzelnen grafischen Objektsteuerungspunkts (Formulars) zu verschieben.
Lernen Sie, wie Sie ein Handelssystem mit Hilfe des ATR entwickeln Lernen Sie, wie Sie ein Handelssystem mit Hilfe des ATR entwickeln
In diesem Artikel werden wir ein neues technisches Instrument kennenlernen, das beim Handel verwendet werden kann, als Fortsetzung der Serie, in der wir lernen, wie man einfache Handelssysteme entwickelt. Diesmal werden wir mit einem anderen beliebten technischen Indikator arbeiten: Average True Range (ATR).
Mehrere Indikatoren in einem Chart (Teil 05): Umwandlung des MetaTrader 5 in ein RAD-System (I) Mehrere Indikatoren in einem Chart (Teil 05): Umwandlung des MetaTrader 5 in ein RAD-System (I)
Es gibt viele Menschen, die keine Ahnung vom Programmieren haben, aber sehr kreativ sind und tolle Ideen haben. Der Mangel an Programmierkenntnissen hindert sie jedoch daran, diese Ideen umzusetzen. Schauen wir uns gemeinsam an, wie man einen Chart Trade mit der MetaTrader 5 Plattform selbst erstellt, als wäre es eine IDE (integrierte Entwicklungsumgebung).
Lernen Sie, wie Sie ein Handelssystem mit Hilfe von ADX entwickeln Lernen Sie, wie Sie ein Handelssystem mit Hilfe von ADX entwickeln
In diesem Artikel werden wir unsere Serie über die Entwicklung eines Handelssystems mit den beliebtesten Indikatoren fortsetzen und über den Average Directional Index (ADX) sprechen. Wir werden diesen Indikator im Detail lernen, um ihn gut zu verstehen, und wir werden lernen, wie wir ihn durch eine einfache Strategie nutzen können. Indem wir etwas gründlich lernen, können wir mehr Einsichten gewinnen und ihn besser nutzen.