Бага таймера, при работе тестера стратегий? - страница 2

 

Mikalas

Сформулируйте свою цель. Что Вам требуется?

 

Добрый день!

 Требуется установить таймер на определённое время.

При установке таймера, иногда, происходит сбой. 

Настройка тестера стратегий: 

Настройка 

 И сходный код:

 

//+------------------------------------------------------------------+
//|                                                    Timer_bug.mq5 |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//
bool                timer_done;
//
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
    timer_done = true;   
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
    EventKillTimer();  
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- variables
    MqlTick  current_tick;
    
//--- Check for tick Synchronized with server 
    if ( SymbolIsSynchronized( _Symbol ) )
    {
//--- Take tick    
      if ( SymbolInfoTick( _Symbol, current_tick ) )
      {
//--- Check timer done      
        if ( timer_done )
        {
          timer_done = false;
          Print("Set time ", CheckTime( current_tick.time ) );
          EventSetTimer( CheckTime( current_tick.time ) );
        }
      }
    }
  }
//+------------------------------------------------------------------+
void OnTimer()
  {
    timer_done = true;
    Print( "Timer done at = ", TimeCurrent() );
  }
//+------------------------------------------------------------------+

uint CheckTime( const datetime aTime )
  {
//--- Variables
    MqlDateTime  struct_time;
    uint         curr_time, delta_time, value_time; 
    uint         trade_time;
    uint         i, factor; 
    uint         DAY_TIME = 86400; 

//--- Take time frame in seconds
    trade_time = ( PeriodSeconds( PERIOD_CURRENT ) );

    TimeToStruct( aTime, struct_time );

    curr_time = struct_time.hour * 3600 + struct_time.min * 60 + struct_time.sec;

//--- Calc factor   
    factor = DAY_TIME / trade_time;  
    
//--- Set timer for next candle
    for ( i = 0; i < factor; i++ )
    {
      if ( ( curr_time >= trade_time * i ) && ( curr_time <= trade_time * ( i + 1 ) - 1 ) )
      {
        delta_time = i + 1;
        break;
      } 
    }
    value_time = trade_time * delta_time - ( DAY_TIME - ( DAY_TIME - curr_time ) );
   
    if ( value_time <= 0 ) value_time = 1;

    return( value_time );    

 

Не правильный результат отмечен красным цветом (таймер установливается на 2 ч. 59 мин. 38 сек.  - 10788 сек, а срабатывает менее чем через час! ):

Результат 

Михаил 

 

Обычное использование таймера - запуск его в OnInit с определённым интервалом. Смена интервала таймера в процессе работы эксперта - это уже экзотика.

Что происходит в тестере? События в тестере формируются часовыми порциями из разных источников (тики разных инструментов и таймер - регулярные источники; торговые события и пользовательские события - нерегулярные источники). Вот и получается, что при смене периода таймера в очереди событий уже есть "старые" события от таймера и никто их оттуда не вынимает.

Перевод же таймера из разряда регулярных источников в разряд нерегулярных (то есть непредсказуемых) источников сильно замедлит тестирование, а на это мы не пойдём.

Какое решение? При установке таймера установить время первого прихода события от этого таймера и раньше этого времени таймерные события не обрабатывать. Что-то типа этого

void OnTimer()
  {
   if(TimeLocal()<g_firstevent_time)
      return;
   ...
  }
Документация по MQL5: Стандартные константы, перечисления и структуры / Константы графиков / Типы событий графика
Документация по MQL5: Стандартные константы, перечисления и структуры / Константы графиков / Типы событий графика
  • www.mql5.com
Стандартные константы, перечисления и структуры / Константы графиков / Типы событий графика - Документация по MQL5
 
Mikalas:

Добрый день!

 Требуется установить таймер на определённое время.

При установке таймера, иногда, происходит сбой. 

Настройка тестера стратегий: 

 

 И сходный код:

 

 

Не правильный результат отмечен красным цветом (таймер установливается на 2 ч. 59 мин. 38 сек.  - 10788 сек, а срабатывает менее чем через час! ):

 

Михаил 

Может можно зайти с другой стороны - чуть проще? Что если сделать, как и предлагает stringo: "Обычное использование таймера - запуск его в OnInit с определённым интервалом...." , задать интервал, обеспечивающий необходимую точность отсчёта, а в коде, где до этого выставлялось значение таймера, поставить счётчики на необходимое время?
Как-то так, если я правильно понял, что требуется...
 

Wangelys:
Может можно зайти с другой стороны - чуть проще? Что если сделать, как и предлагает stringo: "Обычное использование таймера - запуск его в OnInit с определённым интервалом...." , задать интервал, обеспечивающий необходимую точность отсчёта, а в коде, где до этого выставлялось значение таймера, поставить счётчики на необходимое время?
Как-то так, если я правильно понял, что требуется...

 

stringo:

Обычное использование таймера - запуск его в OnInit с определённым интервалом. Смена интервала таймера в процессе работы эксперта - это уже экзотика.

Что происходит в тестере? События в тестере формируются часовыми порциями из разных источников (тики разных инструментов и таймер - регулярные источники; торговые события и пользовательские события - нерегулярные источники). Вот и получается, что при смене периода таймера в очереди событий уже есть "старые" события от таймера и никто их оттуда не вынимает.

Перевод же таймера из разряда регулярных источников в разряд нерегулярных (то есть непредсказуемых) источников сильно замедлит тестирование, а на это мы не пойдём.

Какое решение? При установке таймера установить время первого прихода события от этого таймера и раньше этого времени таймерные события не обрабатывать. Что-то типа этого

Добрый день!

Тогда зачем вообще нужен таймер, если его нельзя использовать?

Можно ли подключать СВОЮ DLL, а не dll загружаемую Windows?

Михаил

  

 

 

Нормальным решением бдет являться создание одного таймера с минимально допустимым временем. при этом создовать его нужно как и положено в блоке инициализации (OnInit).

Если нужно отслеживать несколько периодов то это следует сделать самостоятельно, с помощью обработки в OnTimer (возможно с использованием пользовательских событий).

Также можно использовать индикаторы отслеживающие использующие таймеры (но насколько я помню в них есть ограничения, связанные с тестером стратегий). 

Документация по MQL5: Стандартные константы, перечисления и структуры / Константы графиков / Типы событий графика
Документация по MQL5: Стандартные константы, перечисления и структуры / Константы графиков / Типы событий графика
  • www.mql5.com
Стандартные константы, перечисления и структуры / Константы графиков / Типы событий графика - Документация по MQL5