[Erro em obter o tempo do TF sênior no temporizador! - página 2

 
Alexey Kozitsyn:

Mais uma vez. Não diz isso em nenhum lugar. Isso é o primeiro de tudo. Em segundo lugar, por que depois é enganador ao mostrar primeiro um código de erro 4066 e depois não?

Os dados são bombeados em lotes e depois processados pelo terminal, e já que você está trabalhando em um timer, você é pausado. Não vejo isso explicitamente em nenhum lugar, mas muitos programadores que escrevem aplicações MTF geralmente sabem disso e eu já lhes falei sobre isso de uma só vez.

https://docs.mql4.com/ru/series/timeseries_access leia-o com atenção.

Bem, acima de tudo você já nos deu uma variante de verificação de acessibilidade do histórico. Não é perfeito, mas é simples e óbvio.

Se esta variante não funcionar, verifique como a seguir.

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

Os dados são bombeados em porções e depois processados pelo terminal, e como você está em um timer, você é pausado. Sim, não é mencionado explicitamente em nenhum lugar, mas muitos programadores que escrevem aplicações MTF geralmente sabem sobre isso e eu lhes falei sobre isso imediatamente.

https://docs.mql4.com/ru/series/timeseries_access leia-o com atenção.

Bem, acima de tudo você já nos deu uma variante de verificação de acessibilidade do histórico. Não é perfeito, mas é simples e óbvio.

Sobre entrar "em uma pausa", onde estão as provas?

Eu o li cuidadosamente (e já o li antes). Estou ciente de que os dados (especialmente os TFs mais antigos) nem sempre estão imediatamente disponíveis. Não há problema. Mas por que então a função SeriesInfoInteger() não retorna nenhum erro!? Aqui está a questão!

Assumindo que o pedido cai em alguma pausa/swap/update/break etc., então deixe-o retornar o código de erro != 0. E não haverá nenhum problema!

 
Vitaly Gorbunov:

E, acima, você já deu a opção de verificar a acessibilidade da história. Não é perfeito, mas é simples e direto.

Respondeu acima @Ihor Herasko sobre este ponto.

 
Alexey Kozitsyn:

Já respondeu @Ihor Herasko acima sobre este ponto.

Acima deu sua versão do teste. Por que perguntar tanto aos desenvolvedores, mas este ponto já é conhecido há muito tempo!
 
Vitaly Gorbunov:
Eu dei minha versão do teste acima. Por que perguntar tanto aos desenvolvedores, mas este ponto já é conhecido há muito tempo!

Tentarei certamente sua versão do teste e relatarei os resultados.

 
Alexey Kozitsyn:

Tentarei certamente a sua versão do teste e apresentarei um relatório com os resultados.

Com certeza, irá relatar de volta! Funciona para mim! Mas pode haver todo tipo de armadilhas se não funcionar e vamos pensar no que mais podemos fazer.
 

Primeiro uma resposta de @Ihor Herasko. Código para reprodução:

#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 );
  }

Resultado:

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

De acordo com as entradas dos registros. O terminal foi desligado às 14:25. A seguir, ligado às 14h30min. Verificamos o horário do bar M15. Começamos com a TF M1. O indicador (código acima) mostrava o tempo real de abertura 12:15 (hora do terminal, atrasado em 2 horas em relação à minha hora local). O resultado deveria ter sido 12:30! Conclusão - o erro está presente. E este método sugerido por @Ihor Herasko não funciona.

 
Vitaly Gorbunov:
Não deixe de fazer um relatório! Funciona para mim! Mas pode haver todo tipo de armadilhas se não funcionar, vamos pensar no que mais podemos fazer.

Vou assinar. Código:

#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 );
  }
//+------------------------------------------------------------------+

Resultado:

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

Desligou o terminal às 14:48h, religou-o às 15:01h. Deveria ter chegado a hora às 13:00 horas. Eu tenho 12:45. Alguma outra pergunta?

Mudei a TF de M1 para M5 e obtive o resultado correto:

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
 
Mais uma vez, peço aos desenvolvedores(@Slava, @Alexander, @Renat Fatkhullin) que prestem atenção a este problema.
 

Acho que consegui! O indicador é iniciado imediatamente com o terminal? Se sim, antes de verificar a conexão com o servidor IsConnected() você tem um timer muito rápido que não tem tempo para sincronizar!

Ou faça isso

if(iBarShift(Symbol(),PERIOD_M15,TimeLocal(),true)==-1)
        {
         Print(__FILE__+": Данные истории по последнему часу отсутствуют! Ошибка #",GetLastError());
         return( false );
        }
Mas é preciso levar em conta a diferença entre a hora do servidor e a hora local. Escreva de volta com os resultados!