Остановившееся время. Что показывает GetTickCount()?

 

Вот такой кусок кода в "Эксперте" (он же "Советник"?)

void OnTick(){
   Spread=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD);
   TickTime = GetTickCount();
   FileWrite(ExtHandle, TickTime, Ask, Bid, Spread);
}

выдал две такие строчки

29096484 1.06568 1.06558 10
29096484 1.06568 1.06556 12

Так что показывает GetTickCount()?

Мне казалось, что время в миллисекундах. А что на самом деле?

Я собирался вычислить мгновенную скорость изменения цены, а получил деление на ноль.

 
arkadytokaev:

Вот такой кусок кода в "Эксперте" (он же "Советник"?)

выдал две такие строчки

29096484 1.06568 1.06558 10
29096484 1.06568 1.06556 12

Так что показывает GetTickCount()?

Мне казалось, что время в миллисекундах. А что на самом деле?

Я собирался вычислить мгновенную скорость изменения цены, а получил деление на ноль.


https://www.mql5.com/ru/docs/common/gettickcount
Документация по MQL5: Общие функции / GetTickCount
Документация по MQL5: Общие функции / GetTickCount
  • www.mql5.com
Общие функции / GetTickCount - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Vitalii Ananev:

https://www.mql5.com/ru/docs/common/gettickcount


За ссылку, спасибо, но главный вопрос: Почему время за один тик не изменилось?

Это практически невозможно, да и теоретически (пинги больше одной миллисекунды)

 

Точность GetTickCount около 16 мс.

Такова разрешающая способность системного таймера Windows. Поэтому нельзя с его помощью замерять время в пределах 32 мс из-за погрешности.

А вот функция GetMicrosecondsCount очень хорошо подходит для замеров очень мелких переодов времени.

 
arkadytokaev:


За ссылку, спасибо, но главный вопрос: Почему время за один тик не изменилось?

Это практически невозможно, да и теоретически (пинги больше одной миллисекунды)

Это заложено в архитектуре IBM PC - микросхема таймера (8253 изначально, сейчас - это просто часть микросхемы системного чипсета, но все функции поддерживаются по-прежнему) вызывала прерывания, в ходе которых в BIOSе просто увеличивался счетчик каждый раз на единицу.

Функция GetTickCount() возвращает как раз значение этого счетчика.

И поскольку микросхема вызывает прерывания 18.2 раза в секунду - то более частое вызывание функции GetTickCount() - периодически будет возвращать одно и то же значение счетчика.  

P.S. Сейчас почитал - точное значение частоты  1193180/65536, числитель - это четверть частоты процессора IBM PC (4.77 МГц), что в свою очередь, равно 4/3 частоты NTSC color burst (3.5 МГц). IBM PC мог подключаться к телевизору, и использование таймера, связанного с выходным видео сигналом, экономило несколько долларов на материнской плате.. Кроме того, 2^16 тактов почти точно соответствуют одному часу. Что также использовалось в BIOSe, и позволяло проще организовать проверку на переход через сутки с экономией нескольких байт.

 

Так, господа!

Давайте говорить об одном. Вначале о GetTickCount()

Он увеличивается на 1 один раз за 1/1000 секунды. То есть время переполнения равно 2^32 миллисекунд = 4,294,967.296 секунд = [4,294,967.296/(60*60*24) ]дней = [4,294,967.296/86,400] дней = 49.7 дней

Как и написано в документации.

OnTick() срабатывает по приходу информации с сервера. Ну так мне казалось по логике вещей. Так это, видимо, не так!

А как? Куда ещё можно посмотреть? Похоже, сервер посылает информацию терминалу сразу о нескольких тиках?

 
arkadytokaev:

Так, господа!

Давайте говорить об одном. Вначале о GetTickCount()

Он увеличивается на 1 один раз за 1/1000 секунды. То есть время переполнения равно 2^32 миллисекунд = 4,294,967.296 секунд = [4,294,967.296/(60*60*24) ]дней = [4,294,967.296/86,400] дней = 49.7 дней

Как и написано в документации.

OnTick() срабатывает по приходу информации с сервера. Ну так мне казалось по логике вещей. Так это, видимо, не так!

А как? Куда ещё можно посмотреть? Похоже, сервер посылает информацию терминалу сразу о нескольких тиках?


Вы пишите о совсем разных вещах. Событие OnTick() происходит при изменении цены, а функция GetTickCount() возвращает количество миллисекунд, прошедших с момента старта системы. Цена может меняться несколько раз за секунду, а может и стоять на месте несколько секунд, особенно это видно на 4-х значных котировках.

Если вам надо получить время прихода последнего тика, то в в функции OnTick() можно просто запомнить текущее время.

...
datetime LastTick = TimeCurrent()

....
https://www.mql5.com/ru/docs/dateandtime/timecurrent
Документация по MQL5: Дата и время / TimeCurrent
Документация по MQL5: Дата и время / TimeCurrent
  • www.mql5.com
Дата и время / TimeCurrent - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 

Да. О разных. Просто хотелось завершить (очень интересную) тему архитектуры IBM PC.

И если вернуться к началу этого обсуждения, то видим, что пришло два тика в одно и то же время.

Вот ещё любопытные две строчки из получившегося файла:

34916296 1.06545 1.06535 10
34916296 1.06545 1.06535 10

и ещё две

35802375 1.06613 1.06603 10
35802375 1.06613 1.06603 10


То есть случилось событие OnTick, а ничего не изменилось.

Всего записей с одинаковым временем события OnTick — 90

Вывод, который нужно исследовать:

Сервер посылает в терминал сразу несколько событий OnTick

Иногда за два события OnTick ничего не меняется.

Прикрепляю файл, который, надеюсь, кто-нибудь прогонит в течение дня на своей машине и своём брокере и поделится результатом.

(Одинаковость чисел в первой колонке искал в Экселе с помощью формулы в свободной колонке "=A2=A3"  (Простите за банальность))

Файлы:
 

Почитайте справку по OnTick.

Вам бы индикатор больше подошел, но все равно точного времени тика с помощью GetTickCount вы не получите.

ps: чем не устраивает CopyTicks из MQL5?

 
Renat Fatkhullin:

Точность GetTickCount около 16 мс.

Такова разрешающая способность системного таймера Windows. Поэтому нельзя с его помощью замерять время в пределах 32 мс из-за погрешности.

А вот функция GetMicrosecondsCount очень хорошо подходит для замеров очень мелких переодов времени.


Ренат, можно вопросик Вам, как специалисту в системных вещах?

Эти 16 мс, как были со времен Win 2000 ( по книжке Рихтера сужу, да и по своему опыту), так и будут далее без изменений?

----

Просто Вы общаетесь с большим кругом разработчиков, что -то слышно о приближении Windows к системе реального времени?

Если да или нет, расскажите пожалуйста, как будут решаться вопросы HFT на платформе MT5 независимо от real-time of windows.

Спасибо авансом! 

 
Есть таймеры древние, а есть современные с высокой точностью.

GetTickCount - один из древнейших. Его можно(сразу для всей операционки) разогнать до 1 мс разрешающей точности, но не стоит этого делать.

В рамках MQL5 используйте GetMicrosecondsCount(), у которого точность 1 микросекунда.

Внутри платформы мы тюним латенси на уровне микросекунд.