Fehler, Irrtümer, Fragen - Seite 2146

 
fxsaber:

OnCalculate - wird bei diesem Diagramm nicht ausgeführt. Sie haben ein Handle erstellt, dort ist es untergebracht.

Wenn nicht in diesem, warum wird dann im rechten Unterfenster normal gezeichnet (Pufferzeichnung)?

 
A100:

Im Indikator.

::ChartWindowFind() gibt -1 zurück (mit anderen Worten: funktioniert nicht)


Solange der Indikator nicht initialisiert ist, kennt er nicht die Nummer des Teilfensters, in dem er arbeitet. Er wird erst nach erfolgreicher Initialisierung an das Fenster angehängt

Mit anderen Worten, es ist nutzlos , ChartWindowFind() im Indikator OnInit aufzurufen.

 
Slava:
Mit anderen Worten, es ist nutzlos, ChartWindowFind() im Indikator OnInit aufzurufen.

Aufruf von ChartWindowFind() im Indikator OnInit (gleicher Indikator)

void OnStart()
{
        string name = "Test_i";
        int sub_window = 1;
        ChartIndicatorAdd( 0, sub_window, iCustom( NULL, PERIOD_CURRENT, name ));
}

Ergebnis: 1:wahr:0
2:1:0

Alles ist gut erkannt, lassen Sie mich Sie an den Code des Indikators OnInit erinnern

void OnInit()
{
//...
        ResetLastError();
        int sub_window = ChartWindowFind();
        Print( "2:", sub_window, ":", GetLastError());
}
 
A100:

Wenn das nicht der Fall ist, warum wird dann im gewünschten Teilfenster normal gezeichnet (Pufferzeichnung)?

Die Berechnung des Indikators und sein zeichnerischer Teil sind also unterschiedliche Dinge. ChartWindowFind ist ein Verweis auf den Mechanismus, der für das Zeichnen des Indikators verantwortlich ist. D.h. es ist nicht einmal der Indikator selbst.

 
Slava:

Solange der Indikator nicht initialisiert ist, kennt er die Nummer des Teilfensters nicht, in dem er arbeitet. Sie wird erst nach erfolgreicher Initialisierung an das Fenster angehängt.

Aufruf vonChartWindowFind() nach OnInit (von OnCalculate)

//Test.mq5//Скрипт
void OnStart()
{
        string name = "Test_i";
        ObjectCreate( 0, name, OBJ_CHART, 0, 0, 0 );
        long chart_id  = ObjectGetInteger( 0, name, OBJPROP_CHART_ID );
        int sub_window = 1;
        ChartIndicatorAdd( chart_id, sub_window, iCustom( NULL, PERIOD_CURRENT, name ));
}
//Test_i.mq5//Индикатор
void OnInit() { Print( __FUNCTION__, ":end" ); }
int OnCalculate( const int, const int, const int, const double& [] )
{
        Print( __FUNCTION__ );
        ResetLastError();
        int sub_window = ChartWindowFind();
        Print( "3:", sub_window, ":", GetLastError());
        return 0;
}

Ergebnis: OnInit:Ende
OnCalculate
3:-1:4113

Mit anderen Worten: Der Indikator kennt bereits die Nummer des Teilfensters, in dem er arbeitet, meldet sie aber nicht.
 
A100:

Mit anderen Worten, der Indikator kennt bereits die Nummer des Fensters, in dem er arbeitet, meldet sie aber nicht

Kennt es ChartID()?

 
fxsaber:

Kennt es ChartID()?

Wird nicht benötigt - ChartWindowFind() Funktion ohne Parameter
 
A100:
Wird nicht benötigt - ChartWindowFind() Funktion ohne Parameter

Ich bin mir nur ziemlich sicher, dass es auch ChartID() nicht kennt (keine Parameter).

 
fxsaber:

Ich bin mir ziemlich sicher, dass es auch ChartID() nicht kennt (keine Parameter).

Dies ist ein offensichtlicher Fehler, zumal die Funktionsunfähigkeit nicht nur eintritt, wenn

        ObjectCreate( 0, name, OBJ_CHART, 0, 0, 0 );
        long chart_id = ObjectGetInteger( 0, name, OBJPROP_CHART_ID );

aber wenn

        long chart_id = ChartOpen( NULL, PERIOD_CURRENT );

Wenn ich z. B. manuell ein Diagrammfenster hinzufüge und den Indikator daran hänge, ist alles in Ordnung.

Aber wenn ich es automatisch mache, funktioniert es nicht.

Dies widerspricht dem eigentlichen Konzept des Algotrading

 
A100:

Dies ist ein eklatanter Mangel, zumal er nicht nur unwirksam ist, wenn

aber wenn

Wenn ich z. B. manuell ein Diagrammfenster hinzufüge und den Indikator daran hänge, ist alles in Ordnung.

Aber wenn ich es automatisch mache, funktioniert es nicht.

Dies widerspricht dem eigentlichen Konzept des Algotrading

Es ist gut, dass die Architektur der Indikatoren klarer geworden ist. Es ist seltsam, dass in der Dokumentation so wenig Informationen darüber zu finden sind.

Der Berechnungsteil des Indikators und der Zeichnungsteil sind unterschiedliche Einheiten. Der Griff ist der Berechnungsteil. Die rechnende Seite weiß nichts über die zeichnende Seite, und das sollte sie auch nicht.

Stellen Sie sich vor, Sie haben einen Handle erstellt, ihn aber nicht auf einem, sondern auf zwei Charts platziert. Offensichtlich gibt es einen Indikator, aber er wird auf zwei Charts mit unterschiedlichen ChartID und SubWindow gezeichnet. Dem Handle Indicator ist dies egal, da er nicht weiß, wo dieser Indikator gezeichnet wird und ob er überhaupt gezeichnet wird. Es ist nicht der Indikator, der für das Rendering verantwortlich ist.

Wenn Sie den Indikator manuell oder über eine Vorlage auf dem Diagramm platzieren, geschieht etwas ganz anderes. Ein Griff wird zusammen mit dem Zeichnungsteil erstellt. Wenn Sie den Indikator manuell mit denselben Eingabeparametern auf einem anderen Chart mit demselben Symbol und derselben Periode starten, wird ein weiterer Handle mit dem Zeichnungsteil erstellt.

Dies ist bei MMS nicht der Fall. Wenn Sie einen Indikator erstellen und dann einen anderen, wird nichts mehr erstellt. Der Berechnungsteil bleibt unangetastet.

Die einzige Möglichkeit, den Indikator in MQL auf die gleiche Weise wie von Hand auszuführen, z. B. in einem neuen Diagramm oder OBJ_CHART, ist LoadTemplate.