ChartNavigate während der Initialisierung

Ihor Herasko  

Ich bin auf ein Problem mit der Funktion ChartNavigate gestoßen. Mache ich etwas falsch oder gibt es wirklich ein Problem mit der Funktion. Schreiben Sie zurück, wenn Sie es oft genug benutzt haben.

Hier liegt also der Kern des Problems: ChartNavigate verschiebt das Diagramm nicht Beim Starten des Terminals wenn die Funktion in OnInit() aufgerufen wird. Ich habe die Dokumentation mehrmals gründlich gelesen. Nirgendwo steht, dass die Funktion nicht während der Initialisierung aufgerufen werden kann.

Code Anzeige für die Wiedergabe:

#property indicator_chart_window 
int OnInit()
{
   if (ChartNavigate(0, CHART_END, -1000))
      Alert("Успешно");
   else
      Alert("Ошибка №", GetLastError());

   return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
}
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   return(rates_total);
}

Die Schritte zum Spiel:

  1. Schalten Sie die automatische Wiedergabe von Diagrammen aus.
  2. Befestigen Sie den Indikator am Diagramm. ChartNavigate wird ausgelöst, indem das Diagramm an die gewünschte Position verschoben wird.
  3. Entladen Sie das Terminal.
  4. Laden Sie das Terminal. ChartNavigate funktioniert nicht, wenn das Diagramm ohne einen Offset angezeigt wird.
OK, wenn die Funktion einen Fehler verursachen würde. Aber das ist nicht der Fall. Alle Aufrufe sind erfolgreich, aber erst wenn das Terminal neu geladen wird, tritt der Diagrammversatz nicht auf.

Vladimir Karputov  
Sie wenden eine Funktion an, die mit dem Diagramm arbeitet. Bei einem Indikator ist die Chart-Erstellungsgarantie der erste Eintrag in OnCalculate, bei einem EA ist es der erste Eintrag in OnTick(). Aber nicht vorher.
Ihor Herasko  
Vladimir Karputov:
Sie wenden eine Funktion an, die mit dem Diagramm arbeitet. Für den Indikator ist die Garantie der Chart-Erstellung die erste Eingabe in OnCalculate, für den Expert Advisor - die erste Eingabe in OnTick(). Aber nicht vorher.

Kein Problem. Wenn es noch keinen Graphen gibt, soll die Funktion false und den entsprechenden Fehlercode zurückgeben. Dies ist jedoch nicht der Fall, die Funktion meldet stolz die erfolgreiche Ausführung. Beachten Sie, dass die Dokumentation nicht besagt, dass dies ein Zeichen für das erfolgreiche Senden der Nachricht an den Graphen ist. Es heißt eindeutig: erfolgreiche Ausführung der Funktion.

Außerdem ist dies ein Code für die Wiedergabe. Tatsächlich habe ich sogar vor dem ChartNavigate-Aufruf einen Aufruf an die Zeitreihe. Und alle sind korrekt ausgefüllt, wie sich herausstellt. Das heißt, es gibt bereits ein Diagramm und seine Daten. Außerdem ist es möglich, die grafischen Objekte, die vor dem Schließen des Terminals auf der Karte platziert wurden, abzulesen.

Allem Anschein nach existiert die Karte also bereits.

Alexey Viktorov  

Das ist seltsam. Bei mir funktioniert das ohne Probleme.

Und noch ein Hinweis: Sie müssen die automatische Verschiebung CHART_AUTOSCROLL deaktivieren, bevor Sie das Diagramm verschieben

Vladimir Karputov  
Ihor Herasko:

Kein Problem. Wenn es noch keinen Graphen gibt, soll die Funktion false und den entsprechenden Fehlercode zurückgeben. Dies ist jedoch nicht der Fall, die Funktion meldet stolz die erfolgreiche Ausführung. Beachten Sie, dass die Dokumentation nicht besagt, dass dies ein Zeichen für das erfolgreiche Senden der Nachricht an den Graphen ist. Es heißt eindeutig: erfolgreiche Ausführung der Funktion.

Außerdem ist dies ein Code für die Wiedergabe. Tatsächlich habe ich sogar vor dem ChartNavigate-Aufruf einen Aufruf an die Zeitreihe. Und alle sind korrekt ausgefüllt, wie sich herausstellt. Das heißt, es gibt bereits ein Diagramm und seine Daten. Außerdem ist es möglich, die grafischen Objekte, die vor dem Schließen des Terminals auf der Karte platziert wurden, abzulesen.

Allem Anschein nach existiert die Karte also bereits.

Grafik und Daten sind zwei große Unterschiede.

Alle Funktionen, die sich auf Diagramme beziehen, sind asynchron: d.h. einseitig - aufgenommen und vergessen. Und wahr bedeutet in diesem Fall nur, dass Sie die Felder dieser Funktion korrekt ausgefüllt haben, mehr nicht.

Das Zeichen, wenn alle Daten fertig sind und die Diagramme gezeichnet sind, ist die erste Eingabe für Oncalculate/OnTick.

Alexey Viktorov  
Vladimir Karputov:

Ein Diagramm und Daten sind zwei große Unterschiede.

Alle Funktionen für den Zugriff auf den Graphen sind asynchron, d. h. sie werden nur in eine Richtung ausgeführt, d. h. sie werden aufgenommen und vergessen. In diesem Fall bedeutet wahr nur, dass Sie die Felder dieser Funktion korrekt ausgefüllt haben, mehr nicht.

Das Zeichen, wenn alle Daten fertig sind und die Diagramme gezeichnet sind, ist die erste Eingabe für Oncalculate/OnTick.

Wie erklären Sie sich dann die Tatsache, dass es bei mir einwandfrei funktioniert? In OnInit() genau wie im ersten Beitrag des Threads... Warum denken Sie sich diesen Unsinn aus?

Ihor Herasko  
Alexey Viktorov:

Das ist seltsam. Bei mir funktioniert das ohne Probleme.

Welche Bauart haben Sie? Ich habe 1861.

Und noch ein Hinweis: Sie sollten die automatische Verschiebung CHART_AUTOSCROLL deaktivieren, bevor Sie die Grafik verschieben

Ja, darauf habe ich im ersten Schritt zur Wiedergabe hingewiesen.

Alexey Viktorov  
Ihor Herasko:

Was ist Ihr Körperbau? Ich habe 1861.

Ja, darauf habe ich im ersten Schritt zur Wiederholung hingewiesen.

Ich habe auch 1861. Es ist mir nur einmal gelungen, es zu reproduzieren. Alle anderen Versuche haben gut funktioniert.

Ihor Herasko  
Vladimir Karputov:

Ein Diagramm und Daten sind zwei große Unterschiede.

Alle Funktionen für den Zugriff auf den Graphen sind asynchron, d. h. sie werden nur in eine Richtung ausgeführt, d. h. sie werden aufgenommen und vergessen.

Nein, nicht alle von ihnen. Diejenigen, die dies tun, sind ausdrücklich auskommentiert. Zum Beispiel kann das gleiche ChartApplyTemplate.

In diesem Fall bedeutet wahr nur, dass Sie die Felder dieser Funktion korrekt ausgefüllt haben, mehr nicht.

Wie hat die Funktion festgestellt, dass die Diagramm-ID korrekt ist, wenn das Diagramm selbst noch nicht existiert?

Das Zeichen, wenn alle Daten fertig sind und die Diagramme gezeichnet werden, ist die erste Eingabe für Oncalculate/OnTick.

Leider nein. Hier ist der Code:

#property indicator_chart_window 
int OnInit()
{
   Print(__FUNCTION__, ", баров: ", Bars(Symbol(), PERIOD_CURRENT));

   return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
}
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   Print(__FUNCTION__, ", баров: ", Bars(Symbol(), PERIOD_CURRENT));
   return(rates_total);
}

Es funktioniert folgendermaßen:

16:01:31.765    Test (XBNUSD,M1)        OnInit, баров: 0
16:01:33.531    Test (XBNUSD,M1)        OnCalculate, баров: 37026
16:01:34.010    Test (XBNUSD,M1)        OnCalculate, баров: 46484

Ich lasse den Indikator auf einem neuen Symbol laufen, dessen Chart noch nie geöffnet wurde, d.h. es wurden noch keine Daten darauf generiert.

In der ersten Zeile (OnInit) gibt es tatsächlich keine Daten. Allerdings gibt es die Diagramm-ID und wir können Objekte in OnInit() erstellen, die erfolgreich im Diagramm angezeigt werden.

Die zweite Zeile enthält bereits Daten, aber sie sind unvollständig. Die Daten sind bei der dritten Iteration vollständig.

Daraus kann man schließen, dass der erste Aufruf von OnCalculate keine Garantie für das Laden von Daten ist. Es handelt sich einfach um den ersten Tick des Symbols nach dem Öffnen des Diagramms, der entweder nach einer bestimmten Anzahl von Daten oder ohne andere Daten erfolgen kann.

Um auf das im Thema angesprochene Problem zurückzukommen, müssen wir feststellen, dass die Funktion ChartNavigate() die Korrektheit der Parameter nicht überprüft. Wenn bei OnInit() noch keine Daten vorliegen (0 Balken) und der Wert -1000 an die Funktion übergeben wird, wie kann dieser Wert dann als korrekt angesehen werden, wenn es keine Balken gibt? Denn jede andere Funktion würde einen Fehler zurückgeben, wenn sie auf den Balken mit einem nicht vorhandenen Index zugreift. Aber sie ist hier erfolgreich. Was genau ist erfolgreich?

Vladimir Karputov  

Hier ist der Indikator - speziell setzen eine Verzögerung von neun Ticks, zwei Arten von Chart-Bewegung und die Flagge der erzwungenen Re-Drawing (on/off).

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2012, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#property indicator_chart_window 
#property indicator_plots 0
//--- input parameters
input bool redraw=true;
input ENUM_CHART_POSITION position=CHART_BEGIN;
//---
long count=0;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   count=0;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   count++;
   Comment(count);
   if(count==9)
     {
      ResetLastError();
      if(position==CHART_BEGIN)
        {
         if(ChartNavigate(0,CHART_BEGIN,100))
            Print("Успешно. redraw ",redraw,". position ",EnumToString(position));
         else
            Print("Ошибка №",GetLastError(),". redraw ",redraw,". position ",EnumToString(position));
        }
      if(position==CHART_END)
        {
         if(ChartNavigate(0,CHART_END,-100))
            Print("Успешно. redraw ",redraw,". position ",EnumToString(position));
         else
            Print("Ошибка №",GetLastError(),". redraw ",redraw,". position ",EnumToString(position));
        }
      if(redraw)
         ChartRedraw();
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+


Vorläufig:CHART_BEGIN iststabil.

Dateien:
Test.mq5  6 kb
Ihor Herasko  
Vladimir Karputov:

Hier ist der Indikator - speziell setzen eine Verzögerung von neun Ticks, zwei Arten von Chart-Bewegung und die Flagge der erzwungenen Re-Drawing (on/off).


Vorläufig:CHART_BEGIN arbeitet stabil.

Aber was ist, wenn es keine Zecken gibt und es Wochenende ist? Dann muss die Zeitschaltuhr angeschlossen werden.

Es bleibt nur noch eine Frage zu klären: Wie lässt sich feststellen, ob ChartNavigate erfolgreich ausgeführt wurde? Die Tatsache, dass er true zurückgibt, ist nur ein "Ticken", es hilft nicht bei der wirklichen Arbeit.

Grund der Beschwerde: