[SERVICE DESK] Error in getting the time of the senior TF in the timer! - page 15

 
Taras Slobodyanik:

Your indicator does not track the data update.
New bars are coming from the broker and you don't check them.
I've added a couple of lines to show that when you check, everything is displayed correctly.

It's a working situation - checking out the new bar.

You don't say! What makes you think that I have to keep track of new bars? Is it written in the documentation? I mean that I MUST obtain the value of the function, and then I must necessarily compare it with the previous value? There is a function, the function is designed to work with high timeframes. The function may return an error when it has no data, or return an incorrect value (equal to 0 in this case). That's all. The programmers do not have to do anything to get a 100% correct value.

But look what I found in the documentation for SeriesInfoInteger():

To get more information about the error, you need to call GetLastError() function.

Do you see GetLastError() in my code? Here is the check. This check must be necessary and REALLY necessary! All the rest are crutch solutions.
 
Alexey Kozitsyn:

And you look at my very first post. Do you see error 4066 there? Then error 0 and return incorrect data. Why doesn't the function (in this case, SeriesInfoInteger()) check for relevance before sending the data? Why doesn't it set the error flag? You see, I'd rather wait a bit longer for internal checks to pass than look for errors later.

But after that I've been given a lot of advice, with which I still haven't got any result. And it turned out it wasn't even about the timer.

Ok, read the help)

SeriesInfoInteger

Returns information about the state of historical data.

The word historical means what?
If history is loaded - there is no error.


Alexey Kozitsyn:

No way! And what makes you think that I should necessarily track new bars? Is it written in the documentation? I mean, I MUST get the value of the function, and then I must necessarily compare it with the previous one? There is a function, the function is designed to work with high timeframes. The function may return an error when it has no data, or return an incorrect value (equal to 0 in this case). That's all. The programmers do not have to do anything to get a 100% correct value.

But look what I found in the documentation for SeriesInfoInteger():

In my code see GetLastError()? Here is a check. This check must be necessary and REAL! All the rest are crutch solutions.

You don't have to do anything).
...broker sends you updated data - if you want, use it for calculation, if not - no problem, use the existing history.)


ps. it's the weekend, the market is closed, you have incorrect data in your terminal!
and there is no error!!!)

 
Taras Slobodyanik:

ok, read the help)

What does the word history mean?
If the history is loaded - there is no error.


You do not owe anything.)
...the broker sends you updated data - if you want to use it to calculate, if not - no problem, use History)

Every tick that comes into the terminal is already a story. And I want to get its actual values or error. If that suits you - ok.

 
Alexey Kozitsyn:

Every tick that comes into the terminal is already a story. And I want to receive its actual values or error. If that suits you, that's fine.

Yes, the history is what has already been downloaded or what is being downloaded in the past.
And what is updated only now (after the last quote) is not the history, it is the new raw data.

 
Taras Slobodyanik:

Check the candle time, not the calculation of the bars.
This is how it will update correctly (checked).

Taras, here is the result of your code:

2018.10.08 11:11:39.080 test_isNewDayInOnCalculate GBPUSD,M1: initialized
2018.10.08 11:11:39.788 test_isNewDayInOnCalculate GBPUSD,M1: test_isNewDayInOnCalculate.mq4: Время открытия недельного бара = 2018.09.30 00:00. Ошибка #0
2018.10.08 11:11:39.788 test_isNewDayInOnCalculate GBPUSD,M1: test_isNewDayInOnCalculate.mq4: Актуальное время открытия текущей недели = 2018.10.01 00:00. Ошибка #0
2018.10.08 11:11:39.788 test_isNewDayInOnCalculate GBPUSD,M1: test_isNewDayInOnCalculate.mq4: Время открытия текущего дня = 2018.10.05 00:00. Ошибка #0
2018.10.08 11:11:39.788 test_isNewDayInOnCalculate GBPUSD,M1: test_isNewDayInOnCalculate.mq4: Актуальное время открытия текущего дня = 2018.10.05 00:00. Ошибка #0
2018.10.08 11:11:39.788 test_isNewDayInOnCalculate GBPUSD,M1: test_isNewDayInOnCalculate.mq4: Время открытия текущего часа = 2018.10.05 23:00. Ошибка #0
2018.10.08 11:11:39.788 test_isNewDayInOnCalculate GBPUSD,M1: test_isNewDayInOnCalculate.mq4: Актуальное время открытия текущего часа = 2018.10.05 23:00. Ошибка #0
2018.10.08 11:11:39.788 test_isNewDayInOnCalculate GBPUSD,M1: OnCalculate: Данные старших ТФ загружены!
 
Alexey Kozitsyn:

Taras, here is the result of your code:

Yes, it's the first tick, the one that produces the finished story, the one that is available.
After this tick (if there are new bars), immediately comes the second tick, in which my code updates your variables and they show the correct data.

ps. you can insert your own function to check the new bar, it will be the same.

I, myself, constantly check the number of bars, if the number has changed by more than 1, it means you need to recalculate everything again, if the number has changed by 1, it means just a new bar. And I check only the most critical errors, and I don't see this delay-error.

 
Taras Slobodyanik:

Yes, this is the first tick, the one that gives the ready history.
After this tick (if there are new bars), immediately comes the second tick, in which my code updates your variables and they show the correct data.

If the number has changed by more than 1, then it's just a new bar.

I, myself, constantly check the number of bars, if the number has changed by more than 1, it means you need to recalculate everything again, if the number has changed by 1, it means just a new bar. And I check only the most critical errors, and I don't see this delay-error.

And here, by the way, is another argument in favour of the error happening. It is ERROR in calculation in the indicator! I wrote an Expert Advisor:

#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//--- Время открытия текущего часа, дня и недели
datetime _weekOpenTime = 0;
datetime _hourOpenTime = 0;
datetime _dayOpenTime=0;
//--- Вести лог журнала
const bool inpFileLog=true;
//--- Количество секунд в одном дне
const int SEC_PER_DAY=86400;
//--- Флаг работоспособности индикатора
bool _isWorking=true;
//--- Флаг соединения с торговым сервером (для таймера, получаем в OnCalculate())
bool _isConnected=false;
//---
bool _firstLaunch = true;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   //--- Устанавливаем флаг первого запуска
   _firstLaunch = true;
//--- Сбрасываем время открытия текущего часа, дня и недели
   _weekOpenTime= 0;
   _dayOpenTime = 0;
   _hourOpenTime= 0;
//--- Устанавливаем флаг работоспособности
   _isWorking=true;
//--- Сбрасываем флаг установки соединения
   _isConnected=false;
////--- Запускаем таймер
//   if(!EventSetMillisecondTimer(20))
//     {
//      Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": таймер с частотой 20 не установлен!");
//      //--- Устанавливаем флаг неработоспособности индикатора
//      _isWorking=false;
//     }
//--- Запрос данных
   SeriesInfoInteger(_Symbol,PERIOD_W1,SERIES_LASTBAR_DATE);
   SeriesInfoInteger(_Symbol,PERIOD_D1,SERIES_LASTBAR_DATE);
   SeriesInfoInteger(_Symbol,PERIOD_H1,SERIES_LASTBAR_DATE);
//---
   return( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//|                                                                   |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
////--- Выключаем таймер
//   EventKillTimer();
  }
////+------------------------------------------------------------------+
////|                                                                  |
////+------------------------------------------------------------------+
//void OnTimer()
//  {
////---
//   if(!_isWorking)
//      return;
////---
//   if(!_isConnected)
//      return;
////---
//   Print(__FUNCTION__,": Данные старших ТФ загружены!");
////--- Отключаем таймер
//   EventKillTimer();
//  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Проверяем связь с сервером
   if(!IsConnected())                              // Если не удалось установить связь с сервером
     {
      //--- Сбрасываем флаг соединения с сервером
      _isConnected=false;
      //--- Выходим
      return;
     }
        //--- Проверяем первый запуск эксперта
        if( _firstLaunch )
                {
            //--- Проверяем, записано ли время открытия текущей недели
            if(!CheckCurrentWeekOpenTime())                              // Если время не записано
              return;                                                // Выходим
            //--- Проверяем, записано ли время открытия текущего дня
            if(!CheckCurrentDayOpenTime())                              // Если время не записано
              return;                                                // Выходим
            //--- Проверяем, записано ли время открытия текущего часа
            if(!CheckCurrentHourOpenTime())                              // Если время не записано
              return;                                                // Выходим
            ////--- Устанавливаем флаг соединения с сервером для запуска таймера
            //_isConnected=true;
            //---
            Print(__FUNCTION__,": Данные старших ТФ загружены!");
            //--- Сбрасываем флаг первого запуска
            _firstLaunch = false;
                }
  }
//+------------------------------------------------------------------+
//| Проверяем, записано ли время открытия текущей недели             |
//+------------------------------------------------------------------+
bool CheckCurrentWeekOpenTime()
  {
//--- Проверяем, записано ли время
   if(_weekOpenTime==0) // Если время не записано
     {
      //--- Получаем время открытия недельного бара
      ResetLastError();
      const datetime weekBarOpenTime=(datetime)SeriesInfoInteger(_Symbol,PERIOD_W1,SERIES_LASTBAR_DATE);
      const int err=GetLastError();
      //---
      if(inpFileLog)
        {
         Print(__FILE__,": Время открытия недельного бара = "+TimeToString(weekBarOpenTime)+". Ошибка #",err);
        }
      //--- Проверяем, получено ли время открытия недельного бара
      if(weekBarOpenTime==0 || err!=0) // Если время бара не получено или история обновляется
         return(false);                              // Возвращаем ложь
      //--- Запоминаем время открытия текущей недели (время открытия недельного бара - воскресенье)
      _weekOpenTime=weekBarOpenTime+SEC_PER_DAY;
      //---
      if(inpFileLog)
        {
         Print(__FILE__,": Актуальное время открытия текущей недели = "+TimeToString(_weekOpenTime)+". Ошибка #",err);
        }
      //--- Возвращаем истину
      return( true );
     }
//--- Время открытия недели ранее записано. Возвращаем истину
   return( true );
  }
//+------------------------------------------------------------------+
//| Проверяем, записано ли время открытия текущего дня                  |
//+------------------------------------------------------------------+
bool CheckCurrentDayOpenTime()
  {
//--- Проверяем, записано ли время
   if(_dayOpenTime==0) // Если время не записано
     {
      //--- Получаем время открытия дневного бара
      ResetLastError();
      const datetime tempDayOpenTime=(datetime)SeriesInfoInteger(_Symbol,PERIOD_D1,SERIES_LASTBAR_DATE);
      const int err=GetLastError();
      //---
      if(inpFileLog)
        {
         Print(__FILE__,": Время открытия текущего дня = "+TimeToString(tempDayOpenTime)+". Ошибка #",err);
        }
      //--- Проверяем, получено ли время открытия дневного бара
      if(tempDayOpenTime==0 || err!=0) // Если время бара не получено
         return(false);                                 // Возвращаем ложь
      //--- Сохраняем в глобальную переменную значение открытия текущего дня
      _dayOpenTime=tempDayOpenTime;
      //---
      if(inpFileLog)
        {
         Print(__FILE__,": Актуальное время открытия текущего дня = "+TimeToString(_dayOpenTime)+". Ошибка #",err);
        }
      //--- Возвращаем истину
      return( true );
     }
//--- Время открытия дня ранее записано. Возвращаем истину
   return( true );
  }
//+------------------------------------------------------------------+
//| Проверяем, записано ли время открытия текущего часа              |
//+------------------------------------------------------------------+
bool CheckCurrentHourOpenTime()
  {
//--- Проверяем, записано ли время
   if(_hourOpenTime==0) // Если время не записано
     {
      //--- Получаем время открытия часового бара
      ResetLastError();
      const datetime tempHourOpenTime=(datetime)SeriesInfoInteger(_Symbol,PERIOD_H1,SERIES_LASTBAR_DATE);
      const int err=GetLastError();
      //---
      if(inpFileLog)
        {
         Print(__FILE__,": Время открытия текущего часа = "+TimeToString(tempHourOpenTime)+". Ошибка #",err);
        }
      //--- Проверяем, получено ли время открытия часового бара
      if(tempHourOpenTime==0 || err!=0) // Если время бара не получено
         return(false);                                 // Возвращаем ложь
      //---
      _hourOpenTime=tempHourOpenTime;
      //---
      if(inpFileLog)
        {
         Print(__FILE__,": Актуальное время открытия текущего часа = "+TimeToString(_hourOpenTime)+". Ошибка #",err);
        }
      //--- Возвращаем истину
      return( true );
     }
//--- Время открытия часа ранее записано. Возвращаем истину
   return( true );
  }
//+------------------------------------------------------------------+

Runs from the same chart as the indicator. Let's see the results:

2018.10.09 08:45:42.627 test_isNewDayInOnTick GBPUSD,M1: OnTick: Данные старших ТФ загружены!
2018.10.09 08:45:42.627 test_isNewDayInOnTick GBPUSD,M1: test_isNewDayInOnTick.mq4: Актуальное время открытия текущего часа = 2018.10.09 06:00. Ошибка #0
2018.10.09 08:45:42.627 test_isNewDayInOnTick GBPUSD,M1: test_isNewDayInOnTick.mq4: Время открытия текущего часа = 2018.10.09 06:00. Ошибка #0
2018.10.09 08:45:42.627 test_isNewDayInOnTick GBPUSD,M1: test_isNewDayInOnTick.mq4: Актуальное время открытия текущего дня = 2018.10.09 00:00. Ошибка #0
2018.10.09 08:45:42.627 test_isNewDayInOnTick GBPUSD,M1: test_isNewDayInOnTick.mq4: Время открытия текущего дня = 2018.10.09 00:00. Ошибка #0
2018.10.09 08:45:42.627 test_isNewDayInOnTick GBPUSD,M1: test_isNewDayInOnTick.mq4: Актуальное время открытия текущей недели = 2018.10.08 00:00. Ошибка #0
2018.10.09 08:45:42.627 test_isNewDayInOnTick GBPUSD,M1: test_isNewDayInOnTick.mq4: Время открытия недельного бара = 2018.10.07 00:00. Ошибка #0
2018.10.09 08:45:41.479 test_isNewDayInOnTick GBPUSD,M1: initialized

2018.10.09 08:45:40.822	GBPUSD,M1: CheckCurrentHourOpenTime: Время открытия текущего часа = 2018.10.08 11:00
2018.10.09 08:45:40.822	GBPUSD,M1: CheckCurrentDayOpenTime: Время открытия текущего дня = 2018.10.08 00:00
2018.10.09 08:45:40.822	GBPUSD,M1: CheckCurrentWeekOpenTime: Время открытия текущей недели = 2018.10.08 00:00
2018.10.09 08:45:40.064	GBPUSD,M1: initialized

2018.10.09 08:45:40.022 Expert Other\test_isNewDayInOnTick GBPUSD,M1: loaded successfully

What we see. We see that everything is fine. All loaded, and note that there are no errors, the data is immediately updated! The main question is why the GMT data can be obtained normally, while the indicator should "play with diamonds"? Shouldn't the programs work equally? Why the same code works differently in an indicator and in an Expert Advisor? This should not be the case.

 
Alexey Kozitsyn:

And here, by the way, is another argument in favour of an error occurring. It is the ERROR in the calculation in the indicator! I have written an Expert Advisor:

Runs from the same chart as the indicator. Let's see the results:

What we see. We see that everything is fine. All loaded, and note that there are no errors, the data is immediately updated! The main question is why the GMT data can be obtained normally, while the indicator should "play with diamonds"? Shouldn't the programs work equally? Why the same code works differently in an indicator and in an Expert Advisor? This should not be the case.

All indicators are in a single thread, and nothing new will happen until the end of the flow (in fact, until the next call of Opsalure). Expert Advisor is in its own separate thread, so when it starts, it is allowed to postpone its startup for data updates, update data - everything else in the terminal is unaffected. It has been like this since birth and there is no way to fix it, as the metatrader4 environment has been buried.

 
Unicornis:

Because it's up to terminal to connect and do something with loading, checking, etc., all indicators are in one thread, and nothing new happens until everything in the thread ends (in fact, until the next call of OpCalculate), i.e. being in this thread, you will not get anything faster than the end of the thread anyway. Expert Advisor is in its own separate thread, so when it starts, it is allowed to delay its start for data updates, update data - everything else in the terminal is unaffected. It has been like this since birth and there is no way to fix it, because the metatrader4 environment has been buried.

I am aware of the fact that all indicators of one symbol are in one thread while each expert has its own thread. But this is not the case. The developers are the very developers who fix errors in their creations. Programs should not work differently! If the indicators have missed something, it is an error and there is no problem. The Expert Advisor has somehow received the correct data without errors! So we can implement it. @Slava, can you give your opinion on whether the obviously erroneous behavior will be corrected? Or, at least, documentation addition (that with prev_calculated = 0 no correct data of senior TFs can be obtained)?

 
Alexey Kozitsyn:

Yes I am aware that all indicators of one symbol are in one thread, and a different thread is allocated to each expert. But this is not the case. The developers are the developers who fix errors in their creations. Programs should not work differently! If the indicators have missed something, it is an error and there is no problem. The Expert Advisor has somehow received the correct data without errors! So we can implement it. @Slava, can you give your opinion on whether the obviously erroneous behavior will be corrected? Or at least, will it be added to documentation (when prev_calculated = 0, we cannot get correct data of senior TFs)?

The documentation says that Expert Advisor has as much as 5 seconds before start to receive data and during this time the terminal tries to receive data for the Expert Advisor. The indicator is not given such a possibility and the same way it should not request history refresh, it is not critical for it, if it is critical, then it must be calculated in an Expert Advisor. The main idea is that the desired situation is not possible in the current implementation. Basically, TFs are timers and there are periods where these multiple timers coincide at one moment - this is 100% coincident synchronous process (except opening/closing time), because the first tick of a minute of the current TF coincides with the first minute of five-minute, hour etc. - it is just writing the same value in several variables, and it is logical to set a set of needed TFs and get all necessary data at once. Why developers have done so and not vice versa, I do not know. Maybe, it cannot (will not) be done in the existing terminal operation model because of the client-server division, as if we now allow experts to use indicators, they will hang the terminal.

You may see at the end of the day, if you are interested, how indicator call works, indicator calls another indicator, expert(_asktfexp) calls indicator(_asktf_sample) calling indicator(_asktf). When calling an indicator from an expert, the timer in the indicator will not start, so solutions with a timer in the indicator are only for cases where this indicator will only hang on the chart and will not be called (which is logical in general).

Files:
Reason: