Есть ли система прерываний при обработки событий MT4. Если при обработке события NewTick обработчиком OnTick, происходит событие Timer, то какой сценарий выполняется: - страница 3

 
Sergey Gritsay:

На счет прерывания не могу точно сказать, из справки

Timer

Событие Timer периодически генерируется клиентским терминалом для эксперта, который активизировал таймер при помощи функции EventSetTimer. Обычно эта функция вызывается в функции OnInit. Обработка события Timer производится функцией OnTimer. При завершении работы эксперта необходимо уничтожить созданный таймер при помощи EventKillTimer, которую обычно вызывают в функции OnDeinit.

 проверочный код

//+------------------------------------------------------------------+
//|                                                       test10.mq4 |
//|                                                   Sergey Gritsay |
//|                         https://www.mql5.com/ru/users/sergey1294 |
//+------------------------------------------------------------------+
#property copyright "Sergey Gritsay"
#property link      "https://www.mql5.com/ru/users/sergey1294"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetTimer(1); // зададим таймер с переодичностью 1 секунду
      
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
      
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
Print("Пришло событие OnTick(): ",TimeLocal());
  
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   Print("Пришло событие OnTimer(): ",TimeLocal());
  }
//+------------------------------------------------------------------+


 Результат

2017.01.22 17:31:32.752 Expert test10 USDCHF,H1: loaded successfully
2017.01.22 17:31:34.645 test10 USDCHF,H1: initialized
2017.01.22 17:31:35.689 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:35
2017.01.22 17:31:36.654 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:36
2017.01.22 17:31:37.669 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:37
2017.01.22 17:31:38.684 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:38
2017.01.22 17:31:39.701 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:39
2017.01.22 17:31:40.708 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:40
2017.01.22 17:31:41.726 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:41
2017.01.22 17:31:42.741 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:42
2017.01.22 17:31:43.907 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:43
2017.01.22 17:31:44.895 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:44
2017.01.22 17:31:45.911 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:45
2017.01.22 17:31:46.865 test10 USDCHF,H1: uninit reason 1
2017.01.22 17:31:46.875 Expert test10 USDCHF,H1: removed


 Как видите сегодня выходной, тиков нет, а таймер работает, значит он не зависит от прихода тиков.

когда придет тик, в зависимости от веса кода в онтик, может пропускать таймер. Они по череди работают. Пока онтик работает онтаймер не запустится
 
Сергей:
когда придет тик, в зависимости от веса кода в онтик, может пропускать таймер. Они по череди работают. Пока онтик работает онтаймер не запустится
А вот в цикле все равно, даже посреди тика можно таймер отловить. И наоборот
 
Sergey Gritsay:

На счет прерывания не могу точно сказать, из справки

Timer

Событие Timer периодически генерируется клиентским терминалом для эксперта, который активизировал таймер при помощи функции EventSetTimer. Обычно эта функция вызывается в функции OnInit. Обработка события Timer производится функцией OnTimer. При завершении работы эксперта необходимо уничтожить созданный таймер при помощи EventKillTimer, которую обычно вызывают в функции OnDeinit.

 проверочный код

//+------------------------------------------------------------------+
//|                                                       test10.mq4 |
//|                                                   Sergey Gritsay |
//|                         https://www.mql5.com/ru/users/sergey1294 |
//+------------------------------------------------------------------+
#property copyright "Sergey Gritsay"
#property link      "https://www.mql5.com/ru/users/sergey1294"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetTimer(1); // зададим таймер с переодичностью 1 секунду
      
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
      
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
Print("Пришло событие OnTick(): ",TimeLocal());
  
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   Print("Пришло событие OnTimer(): ",TimeLocal());
  }
//+------------------------------------------------------------------+


 Результат

2017.01.22 17:31:32.752 Expert test10 USDCHF,H1: loaded successfully
2017.01.22 17:31:34.645 test10 USDCHF,H1: initialized
2017.01.22 17:31:35.689 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:35
2017.01.22 17:31:36.654 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:36
2017.01.22 17:31:37.669 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:37
2017.01.22 17:31:38.684 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:38
2017.01.22 17:31:39.701 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:39
2017.01.22 17:31:40.708 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:40
2017.01.22 17:31:41.726 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:41
2017.01.22 17:31:42.741 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:42
2017.01.22 17:31:43.907 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:43
2017.01.22 17:31:44.895 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:44
2017.01.22 17:31:45.911 test10 USDCHF,H1: Пришло событие OnTimer(): 2017.01.22 17:31:45
2017.01.22 17:31:46.865 test10 USDCHF,H1: uninit reason 1
2017.01.22 17:31:46.875 Expert test10 USDCHF,H1: removed


 Как видите сегодня выходной, тиков нет, а таймер работает, значит он не зависит от прихода тиков.

Несколько странная логика: Сегодня выходной, на работу мне не надо, я сижу на диване, значит моё сидение на диване не зависит нужно мне на работу или нет.

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

 
Сергей:
А вот в цикле все равно, даже посреди тика можно таймер отловить. И наоборот
То есть при зацикленном OnTick события таймера всё же вызывают прерывание обработчика OnTick? Я правильно понял?
 
Yury Kirillov:
То есть при зацикленном OnTick события таймера всё же вызывают прерывание обработчика OnTick? Я правильно понял?
да, там онтик вызываете Вы функцией рефрешрэйтс. Поэтому как логику кода сделаете, так и будет. Можете через строчку кода вызывать таймер, если очень надо. Будет тысячу раз в секунду проверять. Задержка по таймеру будет в одну тысячную максимум, если это так важно. Будет немного ресурсы процессора подгружать, но не критично.

что важнее ...

еще один момент, ошибки в цикле надо самому проверять. Но по уму в любом коде все равно свой обработчик пишешь. Просто онеррор он тоже запускается после онтик.
 
Сергей:
да, там онтик вызываете Вы функцией рефрешрэйтс. Поэтому как логику кода сделаете, так и будет. Можете через строчку кода вызывать таймер, если очень надо. Будет тысячу раз в секунду проверять. Задержка по таймеру будет в одну тысячную максимум, если это так важно. Будет немного ресурсы процессора подгружать, но не критично.

что важнее ...

еще один момент, ошибки в цикле надо самому проверять. Но по уму в любом коде все равно свой обработчик пишешь. Просто онеррор он тоже запускается после онтик.
чтобы много не писать, нашел статью в интернете. Много воды и не совсем согласен, но по вашему вопросу неплохо тема расскрыта.

http://www.microbik.ru/dostc/Сергей%20Ковалёв%20Программирование%20на%20алгоритмическом%20языке%20mql4c/shk-53.html
 
А для чего нужно то? В основном, задержки идет от OrderSend. Поэтому можно сделать простую его перегрузку, где будет вызывать OnTimer. И тогда даже сложно придумать жизненные ситуации, когда такого решения будет мало.
 
fxsaber:
А для чего нужно то? В основном, задержки идет от OrderSend. Поэтому можно сделать простую его перегрузку, где будет вызывать OnTimer. И тогда даже сложно придумать жизненные ситуации, когда такого решения будет мало.
В моём советнике критичные к скорости выполнения расчеты должны выполняться по приходу нового тика. Прочие расчеты и различного рода отображения информации должны выполняться во время простоя советника между завершением обработки прошлого тика и приходом будущего. Я использую миллисекундный таймер для инициирования попыток обработки некритичных расчетов. Поэтому мне важно, чтобы расчеты по таймеру не мешали расчетам по приходу тиков. Отсюда и интерес к системе обработчиков и порядку их взаимодействия.
 
Сергей:
да, там онтик вызываете Вы функцией рефрешрэйтс. Поэтому как логику кода сделаете, так и будет. Можете через строчку кода вызывать таймер, если очень надо. Будет тысячу раз в секунду проверять. Задержка по таймеру будет в одну тысячную максимум, если это так важно. Будет немного ресурсы процессора подгружать, но не критично.

что важнее ...

еще один момент, ошибки в цикле надо самому проверять. Но по уму в любом коде все равно свой обработчик пишешь. Просто онеррор он тоже запускается после онтик.
Мне не очень нравится идея зацикливания. По-моему при этом обработка таймера не будет выполняться.
 
Yury Kirillov:
Мне не очень нравится идея зацикливания. По-моему при этом обработка таймера не будет выполняться.
будет, никуда не денется. Только таймер будет пользовательский. Код таймера я выложил Вам выше.

другого способа дать таймеру полный приоритет над тиками я не вижу. В штатном режиме таймер может терять секунды две на каждом входящем тике. Тик приходит в среднем раз в пять секунд. Если эти секунды критичны, то сделать можно. Известный мне метод я и описал выше.
Причина обращения: