[SERVICE DESK]在获取计时器中的高级TF的时间时出错! - 页 15

 
Taras Slobodyanik:

你的指标没有跟踪数据的更新。
新的酒吧 来自经纪人,而你没有检查它们。
我加了几行,以表明当你检查时,一切都显示正确。

这是一个工作情况--检查新酒吧。

你不说!你怎么会认为我必须跟踪新的酒吧?文件中写了吗?我的意思是,我必须获得函数的值,然后我一定要把它与之前的值进行比较?有一个函数,该函数被设计为在高时间框架下工作。当没有数据时,该函数可能会返回一个错误,或者返回一个不正确的值(在这种情况下等于0)。这就是全部。程序员不需要做任何事情就可以得到一个100%正确的数值。

但看看我在SeriesInfoInteger()的文档中发现了什么。

为了获得更多的错误信息,你需要调用GetLastError() 函数。

你在我的代码中看到GetLastError()吗?这里是支票。这种检查必须是必要的,而且是真正必要的。其他的都是拐杖式的解决方案。
 
Alexey Kozitsyn:

而你看看我的第一篇帖子。你在那里看到错误4066吗?然后出错0,并返回不正确的数据。为什么函数(在本例中,SeriesInfoInteger())在发送数据之前不检查其相关性?为什么它不设置错误标志?你看,我宁愿多等一会儿,等内部检查通过,也不愿意以后再找错误。

但在那之后,我得到了很多建议,但我仍然没有得到任何结果。而事实证明,这甚至不是关于计时器的问题。

好的,阅读帮助)

系列信息Integer

返回有关历史数据 状态的信息。

历史这个词的意思是什么?
如果历史被加载 - 没有错误。


阿列克谢-科齐岑

不可能!而你为什么认为我应该一定要跟踪新的酒吧?文件中写了吗?我的意思是,我必须得到函数的值,然后我一定要把它与前一个函数进行比较?有一个函数,该函数被设计为在高时间框架下工作。当没有数据时,该函数可能会返回一个错误,或者返回一个不正确的值(在这种情况下等于0)。这就是全部。程序员不需要做任何事情就可以得到一个100%正确的数值。

但看看我在SeriesInfoInteger()的文档中发现了什么。

在我的代码中看到GetLastError()?这里有一张支票。这种检查必须是必要的和真实的!其他的都是拐杖式的解决方案。

你不需要做任何事情)。
...经纪人向你发送更新的数据--如果你愿意,就用它来计算,如果不愿意--没问题,就用现有的历史数据)。


ps.今天是周末,市场休市,你的终端有错误的数据!
而且没有任何错误!!!)

 
Taras Slobodyanik:

好的,阅读帮助)

历史这个词是什么意思?
如果历史被加载 - 没有错误。


你不欠任何东西)。
...经纪人向你发送更新的数据--如果你想用它来计算,如果不是--没问题,使用历史记录)

每一个 进入终端的蜱虫 都已经是一个故事。而我想得到它的实际值或错误。如果这适合你--好的。

 
Alexey Kozitsyn:

每一个 进入终端的蜱虫 都已经是一个故事。我想收到它的实际值或错误。如果这适合你,这很好。

是的,历史记录是已经下载的内容或正在下载的内容,在过去。
而现在才更新的(上次引用后)不是历史,是新的原始数据。

 
Taras Slobodyanik:

检查蜡烛的时间,而不是条形图的计算。
这样才能正确更新(检查)。

塔拉斯,这是你的代码的结果。

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:

塔拉斯,这是你的代码的结果。

是的,这是第一次打勾,产生成品的故事,是可以使用的。
在这个刻度线之后(如果有新的条形图),马上就会出现第二个刻度线,在这个刻度线中,我的代码会更新你的变量,它们会显示正确的数据。

ps.你可以插入你自己的函数来检查新条,它将是相同的。

我自己不断地检查条数,如果条数变化超过1,就意味着你需要重新计算一切,如果条数变化1,就意味着只是一个新的条数。而且我只检查最关键的错误,我没有看到这个延迟错误。

 
Taras Slobodyanik:

是的,这是第一个勾,即提供准备好的历史的那个勾。
在这个刻度线之后(如果有新的条形图),马上就会出现第二个刻度线,在这个刻度线中,我的代码会更新你的变量,它们会显示正确的数据。

如果数字的变化超过了1,那么就只是一个新条。

我自己不断地检查条数,如果条数变化超过1,就意味着你需要重新计算一切,如果条数变化1,就意味着只是一个新的条数。而且我只检查最关键的错误,我没有看到这个延迟错误。

顺便说一下,这里是支持错误发生的另一个论据。这是指标中的计算错误!我写了一个专家顾问。

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

从与指标相同的图表中运行。让我们看看结果。

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

我们看到了什么。我们看到,一切都很好。全部加载完毕,并注意到没有错误,数据立即更新!主要问题是为什么GMT数据可以正常获得,而指标却要 "玩钻石"?这些项目不应该同样发挥作用吗?为什么同样的代码在指标和专家顾问中的作用不同?情况不应该是这样的。

 
Alexey Kozitsyn:

顺便说一下,这里有另一个有利于发生错误的论据。它是指标中计算的错误!我已经写了一个专家顾问。

从与指标相同的图表中运行。让我们看看结果。

我们看到了什么。我们看到,一切都很好。全部加载完毕,并注意到没有错误,数据立即更新!主要问题是为什么GMT数据可以正常获得,而指标却要 "玩钻石"?这些项目不应该同样发挥作用吗?为什么同样的代码在指标和专家顾问中的作用不同?情况不应该是这样的。

所有的指标都在一个线程中,在流程结束之前(事实上,在下一次调用Opsalure之前)不会有新的情况发生。专家顾问是在自己独立的线程中,所以当它启动时,允许它推迟启动以进行数据更新,更新数据--终端中的其他一切都不受影响。自出生以来就一直如此,而且没有办法解决,因为metatrader4环境已经被埋葬。

 
Unicornis:

因为要靠终端连接并做一些加载、检查等工作,所有的指标都在一个线程中,在线程中的一切结束之前(事实上,直到OpCalculate的下一次调用),没有任何新的事情发生,也就是说,在这个线程中,无论如何你不会得到比线程结束更快的东西。专家顾问是在自己独立的线程中,所以当它启动时,允许它延迟启动以进行数据更新,更新数据--终端中的其他一切都不受影响。自出生以来就一直如此,而且没有办法解决,因为metatrader4环境已经被埋葬。

我知道一个符号的所有指标都在一条线上,而每个专家都有自己的线。但事实并非如此。开发者正是在他们的创作中修复错误的开发者。程序不应该以不同的方式工作!如果指标遗漏了什么,那是一个错误,没有问题。专家顾问以某种方式收到了正确的数据,没有出现任何错误!这就是所谓的专家顾问。因此,我们可以实施它。@Slava,你能对明显错误的行为是否会被纠正给出你的看法吗?或者,至少是文件的补充(在prev_calculated = 0的情况下,无法获得高级TFs的正确数据)?

 
Alexey Kozitsyn:

是的,我知道一个符号的所有指标都在一个线程中,而每个专家都被分配了不同的线程。但事实并非如此。开发者是在他们的创作中修复错误的开发者。程序不应该以不同的方式工作!如果指标遗漏了什么,那是一个错误,没有问题。专家顾问以某种方式收到了正确的数据,没有出现任何错误!这就是所谓的专家顾问。因此,我们可以实施它。@Slava,你能对明显错误的行为是否会被纠正给出你的看法吗?或者至少,它将被添加到文档中(当prev_calculated = 0时,我们无法获得正确的高级TFs数据)?

在文件中说,专家顾问在开始接收数据之前有整整5秒钟的时间,在这段时间内,终端试图为专家顾问接收数据。该指标没有被赋予这样的可能性,同样,它也不应该要求刷新历史记录,这对它来说并不关键,如果它很关键,那么它必须在专家顾问中计算。主要的想法是,在目前的实施中,所期望的情况是不可能的。从本质上讲,TF是计时器,有一些时期,这些多个计时器在某一时刻重合--这是100%重合的同步过程(除了开盘/收盘时间),因为当前TF的分钟的第一个刻度与5分钟、小时等的第一个分钟重合。- 它只是在几个变量中写入相同的值,而设置一组需要的TF并一次性获得所有必要的数据是合乎逻辑的。为什么开发者这样做,而不是反过来,我不知道。 也许,它不能(不会)在现有的终端操作模式下进行,因为客户-服务器的划分,因为如果我们现在允许专家使用指标,他们会挂掉终端。

如果你有兴趣,你可以在最后看到指标调用是如何工作的,指标调用另一个指标,专家(_asktfexp)调用指标(_asktf_sample)调用指标(_asktf)。当从专家中调用一个指标时,指标中的定时器不会启动,所以在指标中带有定时器的解决方案只适用于该指标只在图表上挂起而不被调用的情况(这在一般情况下是符合逻辑的)。

附加的文件: