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

 
Es würde mich sehr interessieren, was die Entwickler darüber denken.
 
 ResetLastError();
      if(iBarShift(Symbol(),PERIOD_M15,TimeCurrent(),true)==-1)
        {
         Print(__FILE__+": Данные истории по последнему часу отсутствуют! Ошибка #",GetLastError());
         return( false );
        }
      //---
      if(GetLastError()==ERR_NO_ERROR)
        {
         ResetLastError();
         //--- Запоминаем время открытия бара
         _m15OpenTime=iTime(NULL,PERIOD_M15,0);
         //---
         Print(__FILE__,": Актуальное время открытия бара М15 = "+TimeToString(_m15OpenTime)+". Ошибка #",GetLastError());
         //--- Возвращаем истину
         return( true );
        }
 
Alexey Kozitsyn:

Es scheint, dass die zuverlässigste Lösung wirklich auf den Aufruf von OnCalculate() mit der obligatorischen Überprüfung der Verbindung zum Handelsserver zu warten ist. Wenn wir nicht prüfen, ob eine Verbindung besteht (IsConnected()), dann werden wir sie sogar in OnCalculate() beim Laden des Terminals erhalten:

Allerdings lassen sich damit nicht alle Fragen ausräumen:

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? Sonst kommt irgendein Unsinn dabei heraus, wie z.B. dass wir Ihnen einmal den Fehler 4066 zurückgeben und Sie dann die Daten, die Sie haben, verwenden können.

Ich habe mit den Entwicklern und einem meiner Freunde dort gesprochen und sage ihnen Folgendes: 1 Was soll ich tun?

1 Unsinn, Sie können es jederzeit und von überall aus anrufen.

2 IsConnected kann von überall im Code aufgerufen werden und funktioniert, aber es ist eine Funktion, die nichts in den Fehlerstapel schreibt, sondern true/false zurückgibt und das war's. Da der Verbindungsvorgang recht lang ist (mindestens 1 Sekunde) und IsConnected zum Zeitpunkt der Anmeldung ausgelöst wird, ist es notwendig, den Verbindungsstatus zu prüfen und beim Starten des Terminals auf den Beginn des Zitatenflusses zu warten.

3 Diese Funktionen schreiben nichts in den Fehlerstapel, sondern geben das Ergebnis selbst zurück.

Die Fehlermeldung 4066 wurde durch die Funktion TimeCurrent verursacht. Terminal eingeloggt und Zeit vom Server angefordert, je nach Qualität der Verbindung dauert es auch einige Zeit, so vergessen Sie nicht über unsere schnellen Timer. Und dann erhielten wir 4066 auf unsere Anfrage von TimeCurrent. Und dann haben wir die Zeit bekommen und unsere Funktionen haben angefangen, normal zu arbeiten, und sie geben selbst einen Fehler zurück, weil sie den Fehlerstapel umgangen haben.

Als Empfehlung in einer solchen Situation, schnelle Timer und Terminal-Start, sicher sein, zu überprüfen, dass wir begonnen, um Daten vom Server. Meine Version ist ein bisschen krüppelig, es wäre richtig, ein Signal von OnCalculate zu erhalten, um Daten zu empfangen.

 
Es ist einfacher als das.
 
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?

Ja, genau. In OnInit() rufen Sie einfach die erforderlichen TFs auf, ohne das Ergebnis zu überprüfen (Sie können sich dort nicht darauf verlassen), und in OnCalculate rufen Sie die Funktion IsTFDataReady() auf. Sobald für alle angeforderten TFs true zurückgegeben wird, können Sie mit der Ausführung des Algorithmus des Indikators beginnen.

 
Alexey Kozitsyn:

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

IsConnected() ist eine ziemlich komplizierte Funktion. Er gibt nur den Status einer Verbindung zum Server zurück. Das Terminal verwendet jedoch mehr als eine Verbindung. Es gibt allein 8 Handelsfäden. Selbst wenn IsConnected() den Wert true zurückgibt, ist also nicht ganz klar, was das bedeutet. Zumindest können wir nicht erwarten, dass Zeitreihen angefordert und erstellt werden. Wenn IsConnected() jedoch false zurückgibt, können wir sicher sein, dass das Terminal noch offline ist.

Was ist die Aufgabe, für die das Vorhandensein des Terminalanschlusses so entscheidend ist? Soweit ich das verstanden habe, ist der Indikator ein Instrument zur Visualisierung von Daten. Die Daten, die verfügbar sind. Wenn neue Daten eintreffen, wird die Visualisierung aktualisiert. Es sollte nicht erforderlich sein, die Aktualität der Daten zu überprüfen. Das ist die Aufgabe des Terminals.

 
Igor Makanu:

Ich denke, wir sprechen über MQL5, OHLC Vorbereitung ist nicht das gleiche wie in MT4

Ich spreche von MT4. Vor etwa 2-3 Jahren habe ich mir einen Fehler mit Time[0] eingefangen. Die Entwickler schienen das Problem behoben zu haben, aber mit der Zeit tauchte es wieder auf. Das Problem ist, dass es unmöglich ist, diesen Fehler eindeutig zu reproduzieren.

 
Ihor Herasko:

IsConnected() ist eine ziemlich komplizierte Funktion. Sie gibt nur den Status einer der Verbindungen zum Server zurück. Das Terminal verwendet jedoch mehr als eine Verbindung. Es gibt allein 8 Handels-Threads. Selbst wenn IsConnected() den Wert true zurückgibt, ist also nicht ganz klar, was das bedeutet. Zumindest können wir nicht erwarten, dass Zeitreihen angefordert und erstellt werden. Wenn IsConnected() jedoch false zurückgibt, können wir sicher sein, dass das Terminal noch offline ist.

Was ist die Aufgabe, für die das Vorhandensein des Terminalanschlusses so entscheidend ist? Soweit ich das verstanden habe, ist der Indikator ein Instrument zur Visualisierung von Daten. Die Daten, die verfügbar sind. Wenn neue Daten eintreffen, wird die Visualisierung aktualisiert. Es sollte nicht erforderlich sein, die Relevanz der Daten zu überprüfen. Dies ist die Aufgabe des Terminals.

Für Indikatoren erinnere ich mich nicht an die Notwendigkeit, die Verbindung mit dem Server zu überprüfen, was wir in der Geschichte haben, wird gezeichnet, wenn die Geschichte geladen wird, bedeutet es, dass alle Indikatorpuffer neu berechnet werden

Ich habe die folgende Funktion entwickelt und verwende sie in meinem EA. Sie ist allgemein zufriedenstellend und prüft die Verbindung mit dem Server korrekt:

bool ServerDisable(int count=10){
   if(IsTesting()||IsOptimization())return(false);
   for(int i=0;i<count;i++){
      if(IsConnected())
         if(IsTradeAllowed())
            if(!IsTradeContextBusy()){RefreshRates(); return(false);}
      Sleep(157);
   }
   Print(__FUNCTION__," Торговый сервер не отвечает");
return(true);}

Ich verwende speziell Sleep(), um die Kontrolle an das Terminal zu übertragen und dann die Verbindung zum Server und die Möglichkeit des Handels zu überprüfen

 
Ihor Herasko:

Ich spreche von MT4. Vor etwa 2-3 Jahren habe ich mir einen Fehler mit Time[0] eingefangen. Die Entwickler schienen das Problem behoben zu haben, aber dann tauchte es mit der Zeit wieder auf. Das Problem ist, dass es unmöglich ist, diesen Fehler eindeutig zu reproduzieren.

Wenn es nicht zu viel Mühe, hier ist das Thema des Themas - korrekte Herunterladen der Geschichte von der großen TF, hier ist der Indikator: "Ich brauche, um die MA" von der großen TF auf die Balken der kleinen TF zu ziehen, machte ich es innerhalb von 5 Minuten, wird es für 98% richtig funktionieren, wo in diesem Code 2% "Fallstricke", die Fehler verursachen wird?

Ich bin an einem korrekten Code für MT4 interessiert

#property copyright "IgorM"
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot line1
#property indicator_label1  "line1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input ENUM_TIMEFRAMES   TimeFrame   =  PERIOD_H4;
input int               MAPeriod    =  25;
//--- indicator buffers
double         BufMA[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   double cl[];
//--- indicator buffers mapping
   SetIndexBuffer(0,BufMA);
   IndicatorDigits(Digits);
// запускаем подгрузку истории и выходим, даже не проверяя подгружена она или нет, история тут еще не нужна
   CopyClose(_Symbol,TimeFrame,0,iBars(_Symbol,TimeFrame),cl);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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,resultcopy;
   double closetf[];
   if(prev_calculated==0)
     {
      resultcopy=CopyClose(_Symbol,TimeFrame,0,iBars(_Symbol,TimeFrame),closetf);
      if(resultcopy<0)
        {
         Print("Подгрузка истории....");
         return(0);
        }
      if(resultcopy<MAPeriod)
        {
         Comment("Большой период МА!!!, в истории доступно ", resultcopy," баров");
         return(resultcopy);
        }
      limit=resultcopy-1;
        }else{
      resultcopy=CopyClose(_Symbol,TimeFrame,0,iBars(_Symbol,TimeFrame),closetf);
      if(resultcopy<0)
        {
         Print("Подгрузка истории....");
         return(0);
        }
      if(resultcopy<MAPeriod)
        {
         Comment("Большой период МА!!!, в истории доступно ", resultcopy," баров");
         return(resultcopy);
        }
      limit=resultcopy-prev_calculated+1;
     }
   limit = fmin(rates_total-1,limit);
// основной цикл расчета индикатора
   for(i=limit; i>=0 && !IsStopped(); i--)
     {
      BufMA[i]=iMA(_Symbol,TimeFrame,MAPeriod,0,MODE_SMA,PRICE_CLOSE,i);
     }
//---
   return(resultcopy);

  }
 
Vitaly Gorbunov:

Ich habe mit den Entwicklern und einem Freund gesprochen, den ich dort kenne, und ich werde Ihnen eins nach dem anderen erzählen.

1 Unsinn, Sie können es jederzeit und von jedem Ort aus anrufen.

2 IsConnected kann von überall im Code aufgerufen werden und funktioniert, aber es ist eine Funktion, die nichts auf den Fehlerstapel legt, sondern true/false zurückgibt, und das war's. Da der Verbindungsvorgang recht lang ist (mindestens 1 Sekunde) und IsConnected zum Zeitpunkt der Anmeldung ausgelöst wird, ist es notwendig, den Verbindungsstatus zu prüfen und beim Starten des Terminals auf den Beginn des Zitatenflusses zu warten.

3 Diese Funktionen schreiben nichts in den Fehlerstapel, sondern geben das Ergebnis selbst zurück.

Die Fehlermeldung 4066 wurde durch die Funktion TimeCurrent verursacht. Terminal eingeloggt und Zeit vom Server angefordert, je nach Qualität der Verbindung dauert es auch einige Zeit, so vergessen Sie nicht über unsere schnellen Timer. Und dann erhielten wir 4066 auf unsere Anfrage von TimeCurrent. Und dann bekamen wir die Zeit und unsere Funktionen begannen normal zu arbeiten und geben selbst einen Fehler als Ergebnis ihrer Arbeit zurück, indem sie den Fehlerstapel umgehen.

Als Empfehlung in einer solchen Situation, schnelle Timer und Terminal-Start, sicher sein, zu überprüfen, dass wir begonnen, um Daten vom Server. Meine Variante ist ein bisschen krüppelig, es wäre richtig, ein Signal von OnCalculate zu bekommen, um Daten zu empfangen.

1. Lesen Sie sorgfältig, was ich schreibe. Das sage ich Ihnen nicht zum ersten Mal! Ich habe nichts davon gesagt, nicht irgendwo anzurufen!

Wollen Sie damit sagen, dass alle Funktionen iBarShift(), iTime(), SeriesInfo...() TimeCurrent() anfordern?