[SERVICE DESK] Fehler beim Abrufen der Zeit der älteren TF im Timer! - Seite 5

 
Vitaly Gorbunov:
Mit der iBarShift-Methode können Sie Lücken in der Historie finden, aber Sie müssen die Historie in regelmäßigen Abständen überprüfen. Ich habe für mich eine Prozedur geschrieben, die dies tut, und danach habe ich die Lücken in den MtF-Programmen vergessen.
Es ging nicht darum, "Löcher" aufzuspüren. Die Person wollte den letzten Takt in der Historie ermitteln, und das ist nicht unbedingt der aktuelle Takt in der Zeit.
 
Vitaly Gorbunov:
Die Daten werden mit dem 4066-Fehler geladen, und dann ist es die Schuld der methaquotovs, höchstwahrscheinlich die empfangenen Daten für diese Situation verarbeitet wird, und der Fehler wurde nicht erfunden. Und bis zu diesem Punkt ergibt alles einen Sinn.

Wenn ein Fehler "nicht erfunden" ist, bedeutet das nicht, dass er nicht existiert.

 
Alexey Navoykov:
Es ging nicht darum, "Löcher" zu entdecken. Die Person wollte den letzten Balken in der Historie erhalten. Und das ist nicht unbedingt der aktuelle Zeitbalken.

Es geht nicht um iBarShift(). Sie sendet die gleichen Fehler wie iTime() und SeriesInfoInteger(). Der Haken an der Sache ist, dass die bei der Initialisierung ermittelte Zeit mit der Zeit des Zeitgebers verglichen wird. Das ist es, was es erlaubt, korrekte aktuelle Daten beim Laden des Terminals zu erhalten, nicht IBarShift().

Ja, und wenn die Zeit 15:00:45 ist (zum Beispiel), und es gibt noch keinen Tick auf dem 15:00-Balken, und wenn die Zeit der letzten Stundenbalkenöffnung 14:00 ist - ist alles korrekt, denke ich. Und wenn das System 13:00 Uhr anzeigt, ist das ein Problem.

 
Alexey Kozitsyn:

1) Igor, hast du dir den Code angesehen? Wo bekomme ich etwas in OnInit()?

In Ihrem Fall werden ein oder mehrere OnTimer-Aufrufe direkt nach OnInit() ausgeführt. Es gibt noch kein OnCalculate() Ereignis.

2. Welche Kontrollen? Wo steht geschrieben, dass der Indikator mindestens einmal OnCalculate() verwenden muss, um korrekt zu funktionieren?

Hier müssen wir die Logik des Terminals verstehen. OnInit() wird sofort aufgerufen, wenn der Indikator mit dem Diagramm verbunden wird. Beim Starten des Terminals wird die Verbindung des Indikators mit dem Chart direkt nach der Erstellung des Chartfensters hergestellt. Zu diesem Zeitpunkt hat das Terminal die Anfrage noch nicht einmal an den Server gesendet.

Das erste OnCalculate() wird aufgerufen, nachdem die lokal verfügbaren Kurse gelesen worden sind. In einigen seltenen Fällen kommt es vor, dass es vor Ort nichts gibt. In diesem Fall werden die Indikatoren bei der Adressierung an Time[0] aus dem Array herausgenommen. Daher ist es besser, die Funktion iTime oder eine ähnliche zu verwenden.

Das zweite und das nächste OnCalculate() treten beim Laden der Historie oder beim Eintreffen von echten Ticks auf.

 
Ihor Herasko:

Das erste OnCalculate() wird nach dem Lesen der lokal verfügbaren Kurse aufgerufen. In einigen seltenen Fällen kommt es vor, dass es vor Ort nichts gibt. In diesem Fall werden die Indikatoren, wenn sie sich auf Time[0] beziehen, aus dem Array entfernt. Verwenden Sie daher besser die Funktion iTime oder eine ähnliche Funktion.

Ich vermute, wir sprechen über MQL5, OHLC Vorbereitung ist dort anders als in MT4

Ich schreibe schon seit langem Indikatoren auf der Grundlage einer Vorlage:

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[])
  {
//---
   int i,limit;
   if(prev_calculated==0)
     {
      limit=rates_total-1;    //--- Первый вызов индикатора или смена таймфрейма или подгрузка данных из истории
     }
   else limit=rates_total-prev_calculated+1;
   for(i=limit;i>=0;i--)      //---- Основной цикл расчета
     {                        
     }
   return(rates_total);
  }

ich habe nie einen "Indikator-Absturz" auf OHLC-Arrays in MT4 gehabt, ich denke, dass MT4 OnCalculate() nicht ausführt, bis ein Diagramm zum ersten Mal vorbereitet ist, und wenn die Geschichte geladen ist, habe ich es nicht überprüft, aber prev_calculated==0, in MT5 wird es sein, wie Sie geschrieben haben - Sie brauchen zusätzliche Prüfungen, um zu sehen, ob die OHLC-Daten bereits vorbereitet sind

 
Ihor Herasko:

In Ihrem Fall werden ein oder mehrere OnTimer-Aufrufe direkt nach OnInit() ausgeführt. Es gibt noch kein OnCalculate() Ereignis.

Hier müssen Sie die Logik des Terminals verstehen. OnInit() wird sofort aufgerufen, wenn der Indikator mit dem Diagramm verbunden wird. Beim Starten des Terminals wird die Verbindung des Indikators mit dem Chart direkt nach der Erstellung des Chart-Fensters hergestellt. Zu diesem Zeitpunkt hat das Terminal die Anfrage noch nicht einmal an den Server gesendet.

Das erste OnCalculate() wird aufgerufen, nachdem die verfügbaren Kurse lokal gelesen wurden. In einigen seltenen Fällen kommt es vor, dass es vor Ort nichts gibt. In diesem Fall werden die Indikatoren bei der Adressierung an Time[0] aus dem Array herausgenommen. Daher ist es besser, die iTime-Funktion und andere ähnliche Funktionen zu verwenden.

Das zweite und das nächste OnCalculate() treten beim Laden der Historie oder beim Eintreffen von echten Ticks auf.

Was schlagen Sie vor, um das Problem zu lösen (gibt es Ihrer Meinung nach)? Warten, bis OnCalculate() 1-2 Mal aufgerufen wird?

 
Alexey Kozitsyn:

Was schlagen Sie vor, um das Problem zu lösen (gibt es Ihrer Meinung nach)? Warten, bis OnCalculate() 1-2 Mal aufgerufen wird?

Sie können versuchen, den Wertprev_calculated==0in eine Variable im globalen Bereich zu kopieren und in OnTimer() zu sehen, ob der Indikator berechnet wurde.OnCalculate() - es wird auf jeden Fall berechnet, ich vermute, dass, wenn die TF-Daten nicht bereit waren, dannreturn(rates_total) 0 zurückgeben wird, was im nächsten Aufruf vonOnCalculate()prev_calculated==0 anzeigen wird, ungefähr:

void OnTimer(){
   if(Global_prev_calculated==0)return;
}
 
Igor Makanu:

Sie können versuchen, den Wertprev_calculated==0in eine Variable im globalen Bereich zu kopieren und in OnTimer() zu sehen, ob der Indikator berechnet wurde; ich habe oben geschrieben, dass ich in MT4 nie einen Fehler mit falscher Berechnung gesehen habeOnCalculate() - es wird auf jeden Fall berechnet werden, ich vermute, dass, wenn die TF-Daten nicht bereit war, dannreturn(rates_total) wird 0 zurückgegeben, die in den nächsten Aufruf vonOnCalculate() ein Zeichenprev_calculated==0 sein wird

Es scheint, dass die zuverlässigste Lösung darin besteht, auf den Aufruf von OnCalculate() mit der obligatorischen Überprüfung der Verbindung zum Handelsserver zu warten. Wenn wir die Verbindung nicht überprüfen (IsConnected()), dann werden wir sie auch in OnCalculate() erhalten, wenn das Terminal geladen wird:

2018.09.21 23:45:27.128 test_isNewDayInOnCalculate_iBarShift() EURGBP.e,M1: test_isNewDayInOnCalculate_iBarShift().mq4: Актуальное время открытия бара М15 = 2018.09.21 21:30. Ошибка #0
2018.09.21 23:45:25.990 test_isNewDayInOnCalculate_iBarShift() EURGBP.e,M1: initialized
2018.09.21 23:45:25.975 Custom indicator test_isNewDayInOnCalculate_iBarShift() EURGBP.e,M1: loaded successfully

Allerdings lassen sich damit nicht alle Fragen ausräumen:

1. Warum steht in der Dokumentation zu IsConnected() nicht, dass es unbedingt aufgerufen werden muss, bevor Daten (zumindest) von der Senior TF in OnCalculate() empfangen werden?

2. Warum funktioniert IsConnected() in OnTimer() eigentlich nicht? Sollte die Tatsache, dass eine Verbindung zu einem Handelsserver hergestellt wird, nicht bedeuten, dass Daten abgerufen werden können?

3. Wenn wir eine Verbindung mit dem Handelsserver hergestellt haben und versuchen, Daten in OnTimer() zu empfangen, sollten dann nicht die Funktionen iTime(), iBarShift(), SeriesInfoInteger() und ähnliche Funktionen Fehler zurückgeben, wenn die Daten von diesem bestimmten Handelsserver, von dem sie Informationen beziehen, noch nicht synchronisiert sind? Andernfalls sieht es unsinnig aus, als würden wir einmal den Fehler 4066 zurückgeben und dann die vorhandenen Daten auf beliebige Weise verwenden.

 
Alexey Kozitsyn:

Damit sind jedoch noch nicht alle Fragen geklärt:

1. Warum steht in der Dokumentation zu IsConnected() nicht, dass diese Funktion unbedingt aufgerufen werden muss, bevor Daten (zumindest) von der Senior-TF in OnCalculate() empfangen werden?

2. Warum funktioniert IsConnected() in OnTimer() eigentlich nicht? Sollte die Tatsache, dass eine Verbindung zu einem Handelsserver hergestellt wird, nicht bedeuten, dass Daten abgerufen werden können?

3. Wenn wir eine Verbindung mit dem Handelsserver hergestellt haben und versuchen, Daten in OnTimer() zu empfangen, sollten dann nicht die Funktionen iTime(), iBarShift(), SeriesInfoInteger() und ähnliche Funktionen Fehler zurückgeben, wenn die Daten von diesem bestimmten Handelsserver, von dem sie Informationen beziehen, noch nicht synchronisiert sind? Andernfalls sieht es unsinnig aus, als würden wir einmal den Fehler 4066 zurückgeben und dann die vorhandenen Daten so verwenden, wie Sie es wünschen.

1. nun, niemand hat den Fall des Indikatoraufrufs auf historischen Daten aufgehoben, wenn Sie online arbeiten müssen, dann überprüfen Sie die Verbindung, wenn nicht, oder eher nicht wichtig, dann funktioniert meine Version der Vorlage. Die IsConnected() Funktionsgruppe ist eigentlich ein bisschen schwierig, sie kreuzen IsTradeContextBusy() und IsConnected() selbst manchmal und IsTradeAllowed()... Ich glaube, sie betrügen auf der Serverseite und trennen Terminals zur Nachrichtenzeit oder eine andere Manipulation

2,3. funktioniert, aber Sie vergessen, dass GetLastError() seinen Status nach einem Aufruf zurücksetzt und vielleicht muss GetLastError() zur Aktualisierung des Status die Kontrolle an das Terminal übertragen, vielleicht hatte das Terminal keine Zeit, den Status IsConnected() in GetLastError() vor Ihrem Aufruf vom Timer.... neu zu setzen. Ich denke, die Funktion OnTimer() ist nicht für den Empfang von Daten gedacht: "MQL4 Reference / Status Check - OnTimer() wird aufgerufen, aber die Variablen der Terminalumgebung werden nicht aktualisiert, undOnCalculate() bereitet garantiert alle Daten vom Terminal vor, wenn der Tick kommt

 
Igor Makanu:

1. Nun, niemand hat den Fall des Aufrufs des Indikators auf historischen Daten aufgehoben...

2,3. es funktioniert, aber Sie vergessen, dass GetLastError() seinen Status nach dem Aufruf zurücksetzt, und vielleicht muss GetLastError() zur Aktualisierung des Status die Kontrolle an das Terminal übergeben, vielleicht hat das Terminal keine Zeit, den Status IsConnected() in GetLastError() vor Ihrem Aufruf von timer.... neu zu setzen Ich denke, die Funktion OnTimer() ist nicht für den Empfang von Daten gedacht: "Die MQL4 Referenz / Status Check - OnTimer() wird aufgerufen, aber die Variablen der Terminalumgebung werden nicht aktualisiert, und es ist garantiert, dass das Terminal alle Daten vorbereitet, wenn der Tick kommt-OnCalculate().

1. Glauben Sie, dass, wenn die Taktnummer 0 eine falsche Zeit hat, der Rest des Verlaufs eine korrekte Zeit haben wird?)

2,3. Wenn Datenzugriffsfunktionen nicht genug Zeit haben, um einen aussagekräftigen Fehler zu setzen, sollten sie ihn irgendwie melden, aber sicher nicht durch Rückgabe des Fehlercodes = 0 (kein Fehler). Der Rest des "Vielleicht" ist reine Spekulation. Und ohne Beweise gibt es nichts zu besprechen.

Die Funktion OnTimer() ist nicht dazu gedacht, Daten abzurufen...

Kein Kommentar.

OnTimer() wird aufgerufen, aber die Variablen der Terminalumgebung werden nicht unbedingt aktualisiert

Wozu brauchen wir den 4066-Fehler?
Grund der Beschwerde: