[SERVICE DESK] Errore nell'ottenere il tempo del TF senior nel timer! - pagina 2

 
Alexey Kozitsyn:

Ancora una volta. Non c'è scritto da nessuna parte. Questo è prima di tutto. In secondo luogo, perché poi è fuorviante mostrando prima un codice di errore 4066 e poi no?

I dati vengono pompati in batch e poi elaborati dal terminale, e dato che stai lavorando su un timer, sei in pausa. Non lo vedo esplicitamente da nessuna parte, ma molti programmatori che scrivono applicazioni MTF di solito lo sanno e ve ne ho parlato subito.

https://docs.mql4.com/ru/series/timeseries_access leggere attentamente.

Bene, sopra ci hai già dato una variante di controllo dell'accessibilità della storia. Non è perfetto, ma è semplice e ovvio.

Se questa variante non funziona, controllate come segue.

if(iBarShift(Symbol(),PERIOD_H1,TimeCurrent(),true)==-1){Print("Данные истории по последнему часу отсутствуют!");}
Организация доступа к данным - Доступ к таймсериям и индикаторам - Справочник MQL4
Организация доступа к данным - Доступ к таймсериям и индикаторам - Справочник MQL4
  • docs.mql4.com
Прежде чем ценовые данные будут доступны в терминале MetaTrader 4, их необходимо получить и обработать. Для получения данных требуется подключение к торговому серверу MetaTrader 4. Данные поступают с сервера по запросу терминала в виде экономно упакованных блоков минутных баров. Механизм обращения к серверу за данными не зависит от того, каким...
 
Vitaly Gorbunov:

I dati vengono pompati in porzioni e poi elaborati dal terminale, e dato che sei su un timer, vieni messo in pausa. Sì, non è esplicitamente menzionato da nessuna parte, ma molti programmatori che scrivono applicazioni MTF di solito lo sanno e ve ne ho parlato subito.

https://docs.mql4.com/ru/series/timeseries_access leggere attentamente.

Bene, sopra ci hai già dato una variante di controllo dell'accessibilità della storia. Non è perfetto, ma è semplice e ovvio.

Riguardo all'entrare "in una pausa", dove sono le prove?

L'ho letto attentamente (e l'ho letto prima). Sono consapevole del fatto che i dati (specialmente i TF più vecchi) non sono sempre immediatamente disponibili. Nessun problema. Ma perché allora la funzione SeriesInfoInteger() non restituisce alcun errore? Ecco la domanda!

Supponendo che la richiesta cada su qualche pausa/swap/aggiornamento/interruzione ecc., allora lasciamo che restituisca il codice di errore != 0. E non ci saranno problemi!

 
Vitaly Gorbunov:

E sopra avete già dato la possibilità di controllare l'accessibilità della storia. Non è perfetto, ma è semplice e diretto.

Ha risposto sopra @Ihor Herasko su questo punto.

 
Alexey Kozitsyn:

Ha già risposto @Ihor Herasko sopra su questo punto.

Sopra ha dato la sua versione del test. Perché questa domanda agli sviluppatori, ma questo punto è noto da molto tempo!
 
Vitaly Gorbunov:
Ho dato la mia versione del test qui sopra. Perché questa domanda agli sviluppatori, ma questo punto è noto da molto tempo!

Proverò sicuramente la tua versione del test e riferirò i risultati.

 
Alexey Kozitsyn:

Proverò sicuramente la tua versione del test e ti riferirò i risultati.

Farò sicuramente rapporto! Per me funziona! Ma ci possono essere tutti i tipi di insidie se non funziona e penseremo a cos'altro possiamo fare.
 

Prima una risposta da @Ihor Herasko. Codice per la riproduzione:

#property version   "1.00"
#property strict
#property indicator_chart_window
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//--- Время открытия текущего часа, дня и недели
datetime _m15OpenTime=0;
//--- Вести лог журнала
const bool inpFileLog=true;
//--- Количество секунд в одном дне
const int SEC_PER_DAY=86400;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Запускаем таймер
   if(!EventSetMillisecondTimer(20))
     {
      Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": таймер с частотой 20 ms не установлен!");
      return( INIT_FAILED );
     }
//--- Сбрасываем время открытия текущего бара м15, часа, дня
   _m15OpenTime = 0;
//---
   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[])
  {

   return( rates_total );
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- Проверяем, записано ли время открытия текущего бара М15
   if(!CheckCurrentM15OpenTime())                        // Если время не записано
      return;                                                // Выходим                                                                                                                         // Выходим
  }
//+------------------------------------------------------------------+
//| Проверяем, записано ли время открытия текущего бара М15             |
//+------------------------------------------------------------------+
bool CheckCurrentM15OpenTime()
  {
//--- Проверяем, записано ли время
   if(_m15OpenTime==0) // Если время не записано
     {
      //---
      ResetLastError();
      iTime(NULL,PERIOD_M15,1);
      //---
      if(GetLastError()==ERR_NO_ERROR)
        {
         ResetLastError();
         //--- Запоминаем время открытия бара
         _m15OpenTime=iTime(NULL,PERIOD_M15,0);
         //---
         Print(__FILE__,": Актуальное время открытия бара М15 = "+TimeToString(_m15OpenTime)+". Ошибка #",GetLastError());
         //--- Возвращаем истину
         return( true );
        }
      else
         return( false );
     }
//--- Время открытия М15 ранее записано. Возвращаем истину
   return( true );
  }

Risultato:

2018.09.21 14:25:02.793 Custom indicator test_isNewDayInTimer_iTime() EURGBP.e,M1: removed
2018.09.21 14:30:44.120 Custom indicator test_isNewDayInTimer_iTime() EURGBP.e,M1: loaded successfully
2018.09.21 14:30:44.149 test_isNewDayInTimer_iTime() EURGBP.e,M1: initialized
2018.09.21 14:30:44.262 test_isNewDayInTimer_iTime() EURGBP.e,M1: test_isNewDayInTimer_iTime().mq4: Актуальное время открытия бара М15 = 2018.09.21 12:15. Ошибка #0

Secondo le voci di registro. Il terminale è stato spento alle 14:25. Poi, acceso alle 14:30. Controlliamo l'ora della barra M15. Abbiamo iniziato con TF M1. L'indicatore (codice sopra) ha mostrato l'orario effettivo di apertura alle 12:15 (orario del terminale, in ritardo rispetto al mio orario locale di 2 ore). Il risultato avrebbe dovuto essere 12:30! Conclusione: l'errore è presente. E questo metodo suggerito da @Ihor Herasko non funziona.

 
Vitaly Gorbunov:
Assicurati di fare rapporto! Per me funziona! Ma ci possono essere tutti i tipi di insidie, se non funziona penseremo a cos'altro possiamo fare.

Io chiudo. Codice:

#property version   "1.00"
#property strict
#property indicator_chart_window
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//--- Время открытия текущего часа, дня и недели
datetime _m15OpenTime=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Запускаем таймер
   if(!EventSetMillisecondTimer(20))
     {
      Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": таймер с частотой 20 ms не установлен!");
      return( INIT_FAILED );
     }
//--- Сбрасываем время открытия текущего бара м15
   _m15OpenTime=0;
//---
   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[])
  {

   return( rates_total );
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- Проверяем, записано ли время открытия текущего бара М15
   if(!CheckCurrentM15OpenTime())                        // Если время не записано
      return;                                                // Выходим
  }
//+------------------------------------------------------------------+
//| Проверяем, записано ли время открытия текущего бара М15             |
//+------------------------------------------------------------------+
bool CheckCurrentM15OpenTime()
  {
//--- Проверяем, записано ли время
   if(_m15OpenTime==0) // Если время не записано
     {
      //---
      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 );
        }
      else
         return( false );
     }
//--- Время открытия недели ранее записано. Возвращаем истину
   return( true );
  }
//+------------------------------------------------------------------+

Risultato:

2018.09.21 14:48:46.485 Custom indicator test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: removed
2018.09.21 15:01:23.158 Custom indicator test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: loaded successfully
2018.09.21 15:01:23.175 test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: initialized
2018.09.21 15:01:23.295 test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: test_isNewDayInTimer_iBarShirt().mq4: Актуальное время открытия бара М15 = 2018.09.21 12:45. Ошибка #0

Ho spento il terminale alle 14:48 e l'ho riacceso alle 15:01. Avrebbe dovuto prendere l'ora alle 13:00. Ho le 12:45. Ci sono altre domande?

Ho cambiato TF da M1 a M5 e ho ottenuto il risultato corretto:

2018.09.21 15:01:23.295 test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: test_isNewDayInTimer_iBarShirt().mq4: Актуальное время открытия бара М15 = 2018.09.21 12:45. Ошибка #0
2018.09.21 15:05:50.057 test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: uninit reason 3
2018.09.21 15:05:50.058 test_isNewDayInTimer_iBarShirt() EURGBP.e,M5: initialized
2018.09.21 15:05:50.094 test_isNewDayInTimer_iBarShirt() EURGBP.e,M5: test_isNewDayInTimer_iBarShirt().mq4: Актуальное время открытия бара М15 = 2018.09.21 13:00. Ошибка #0
 
Ancora una volta chiedo agli sviluppatori(@Slava, @Alexander, @Renat Fatkhullin) di prestare attenzione a questo problema.
 

Penso di avercela fatta! L'indicatore viene avviato immediatamente con il terminale? Se è così, prima di controllare aspetta una connessione al server IsConnected() hai un timer molto veloce che non ha il tempo di sincronizzarsi!

Oppure fai così

if(iBarShift(Symbol(),PERIOD_M15,TimeLocal(),true)==-1)
        {
         Print(__FILE__+": Данные истории по последнему часу отсутствуют! Ошибка #",GetLastError());
         return( false );
        }
Ma devi tenere conto della differenza tra l'ora del server e l'ora locale. Rispondete con i risultati!
Motivazione: