Как получить текущие миллисекунды в терминале MetaTrader4?

Как получить текущие миллисекунды из MQL4 с помощью советника.

то есть: в Java мы можем получить текущие миллисекунды, используя system.currenttimemillis()


person Nitin    schedule 20.05.2017    source источник
comment
Ниже приведено решение для точного определения времени с постоянной абсолютной ошибкой. Никакой блокировки, никакой непредсказуемой случайности, никакого дрожания, никакого блуждания, ничего похожего на использование OnTimer()-зависимой лотерейной машины, управляемой событиями. Просто с точностью до микросекунды [даже если вы запрашиваете миллисекунды :o)].   -  person user3666197    schedule 13.06.2017


Ответы (5)


Эта проблема MT4 «Получить миллисекунду» существовала целую вечность. Это хак, который я создал, чтобы решить эту проблему.

//+------------------------------------------------------------------+
//|                                                     timeInMs.mq4 |
//|                                       Copyright 2017, Joseph Lee |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, Joseph Lee"
#property link      "https://www.facebook.com/joseph.fhlee"
#property version   "1.00"
#property strict

int     prevSecondTime      = 0;
uint    prevSecondTick      = 0;


int OnInit()    {
    //Create an Event that triggers every 1 millisecond.
    // **NOTE: GetTickCount() is accurate to +-16ms only, so
    // in practice, no need to trigger every 1ms.
    EventSetMillisecondTimer(1);
    return(INIT_SUCCEEDED);
}

void OnTick() {
    Comment( "Now: " + TimeLocal() + " :: " + getCurrentMs() + " ms. +- 16ms accuracy.");
}

int getCurrentMs() {
    return(GetTickCount() - prevSecondTick);
}

//This is an EVENT function that will be called every
// x millisecond(s) [as stated in teh EventSetMillisecondTimer()
// in the OnInit()
void OnTimer() {
    //If a new "second" occurs, record down the GetTickCount()
    if(TimeLocal() > prevSecondTime) {
        prevSecondTick  = GetTickCount();
        prevSecondTime  = TimeLocal();
    }
}
person Joseph Lee    schedule 09.06.2017
comment
Это решение работает для меня. Я использую TimeGMT() и конвертирую эту строку времени в текущую миллисекунду в моем приложении node. - person Nitin; 10.06.2017
comment
Если бы это было правдой, о чем говорит ваш (cit.:) // **NOTE: GetTickCount() is accurate to +-16ms only,, не было бы абсолютно никакого смысла в субмиллисекундном разрешении TimeDOMAIN, т.к. доступен из GetMicrosecondCount(), что является очевидным противоречием, по причине которого только что была доказана ошибочность исходной гипотезы ( и проблема заключается в OnTimer() неточности, а не в GetTickCount() или GetMicrosecondCount() ). QED - person user3666197; 12.06.2017
comment
Я упоминал, что это никогда не будет работать в режиме тестера стратегий? - person user3666197; 13.06.2017
comment
Вы слишком усложняете вещи :) Это работает для 98% сценариев. Если мы хотим быть «точными», нам также нужно синхронизировать время ПК с атомными часами (время Windows имеет точность до 30 с). Но это работает для большинства случаев использования. Конечно, я открыт для лучших альтернативных решений. - person Joseph Lee; 13.06.2017
comment
Не подскажете, чувак, ты не синхронизируешь свои FOREX-платформы хотя бы с парой эталонных часов STRATUM-1 + пользуешься непрерывным сервисом коррекции CLOCK_MONOTONIC в режиме 24/7/365? - person user3666197; 13.06.2017
comment
Я знаю, и я знаю, что вы тоже :) НО 99% большинства не знают (и они понятия не имеют, о чем вы говорите: D) - person Joseph Lee; 13.06.2017
comment
Ну, в случае, если кто-то хочет запустить анализ событий, вам нужно точное, абсолютное время, которое позволяет объединить любой выровненный по микросекундам журнал событий в надежную, точно выровненную по времени, последовательность. -событий. Недостаточное выполнение этой работы приведет к простому хаосу, а не к серьезному журналу, в котором обеспечен причинно-следственный порядок. Каждый может себе представить ценность такого бессмысленного Havoc-вместо-The-Journal :o) В любом случае, следите за обновлениями! - person user3666197; 13.06.2017
comment
Страшно то, что я не уверен, шутите ли вы, ребята, о компьютерной синхронизации STRATUM-1, но если нет, то как бы вы это сделали? - person not2qubit; 06.01.2020
comment
@ not2qubit, это не шутка. Вам нужно синхронизировать время вашего ПК. В противном случае вы отстаете на несколько секунд, что не сработает для высокоточных операций, таких как торговля новостями. Вы можете попробовать timesynctool.com и настроить частую повторную синхронизацию. - person Joseph Lee; 08.01.2020

Может иметь относительный [мс] или даже [нас]:

Будьте осторожны, так как оба являются относительными, но один относительно запуска системы, другой относительно запуска модуля выполнения кода MQL4.

Функция GetTickCount() возвращает количество миллисекунд, прошедших с момента запуска системы.

uint GetTickCount();

Счетчик ограничен ограничениями системного таймера. Время хранится в виде целого числа без знака, поэтому оно переполняется каждые 49,7 дня, если компьютер работает бесперебойно.


Функция GetMicrosecondCount() возвращает количество микросекунд, прошедших с момента запуска MQL-программы.

ulong GetMicrosecondCount();


Может иметь абсолютное значение [мс] или даже [нас], с const(!) АБСОЛЮТНАЯ ОШИБКА,

в котором не будет ни дрейфа, ни дрожания при точном измерении времени.

Разве это не здорово для домена FOREX, где миллисекунды "полны событий", а микросекунды (наносекунды в недавних разработках профессионального уровня) имеют значение?!

// -----------------------------------------------------------------
ulong system_currenttimemillis(){
      return(   OnStart_GLOB_MILLISECONDS       // ABS [ms] SYNC-ed OnStart() WITH [s]-EDGE-ALIGNMENT
            + (           GetMicrosecondCount() // + DELTA ------------------
              - OnStart_BASE_MICROSECONDS       //   since SYNC-ing OnStart()
                ) / 1000 // =================== //   DELTA [ms] =============
              );
}
// -----------------------------------------------------------------
static ulong    OnStart_GLOB_MICROSECONDS;
static ulong    OnStart_GLOB_MILLISECONDS;
static ulong    OnStart_EoDY_MICROSECONDS;
static datetime OnStart_EoDY_DATETIME;
static datetime OnStart_BASE_DATETIME;
static uint     OnStart_BASE_MILLISECONDS;
static ulong    OnStart_BASE_MICROSECONDS;
// -----------------------------------------------------------------
void            OnStart(){ /* { SCRIPT | EXPERT ADVISOR | CUSTOM INDICATOR } CALL
                                                                             THIS */
                OnStart_BASE_DATETIME      = TimeLocal();           // .SET int == the number of seconds elapsed since January 01, 1970.
         while( OnStart_BASE_DATETIME     == TimeLocal() ){ // ---- // EDGE-ALIGNMENT -------------------------------------------------------
                OnStart_BASE_MICROSECONDS  = GetMicrosecondCount(); //      .SET ulong, since MQL4 program launch
                OnStart_BASE_MILLISECONDS  = GetTickCount();        //      .SET uint,  since system start
         } // ==[ MAX 1 SECOND ]=============================== NOW // EDGE-ALIGNED TO [s] ==================================================
                OnStart_BASE_DATETIME      = TimeLocal();           // .SET date and time as the number of seconds elapsed since January 01, 1970.
                OnStart_GLOB_MICROSECONDS  = (       (ulong) OnStart_BASE_DATETIME ) * 1000000;
                OnStart_GLOB_MILLISECONDS  = (       (ulong) OnStart_BASE_DATETIME ) * 1000;
                OnStart_EoDY_DATETIME      =                 OnStart_BASE_DATETIME
                                           - (               OnStart_BASE_DATETIME % 86400 );
                OnStart_EoDY_MICROSECONDS  = (   TimeSecond( OnStart_BASE_DATETIME )
                                             + ( TimeMinute( OnStart_BASE_DATETIME )
                                               + TimeHour(   OnStart_BASE_DATETIME ) * 60 ) * 60 ) * 1000000;
}
// -----------------------------------------------------------------
int OnInit()    {
    OnStart();             /*   HACK 4 { EXPERT ADVISOR | CUSTOM INDICATOR } CALL
    ...                                                                      THAT */
    ..
    return( INIT_SUCCEEDED );
}
// -----------------------------------------------------------------
ulong Get_a_Microsecond_of_a_Day(){           // THIS HAS A !!_CONSTANT_!! ONLY ABSOLUTE SYSTEMATIC TIMING ERROR
      return( (   OnStart_EoDY_MICROSECONDS   // EDGE-SYNC OnStart_EoDY + DELTA-SINCE-OnStart-SYNC-ed:
              + (           GetMicrosecondCount()                       // == NOW ( 8B ulong ) ROLL-OVER ~ 213M504 DAYS AFTER THE PROGRAM START, WAY LONGER, THAN WE WILL LIVE UNDER THE SUN
                - OnStart_BASE_MICROSECONDS   //                        //  - OnStart_BASE_MICROSECONDS
                  )
                ) // ================== // SECONDS-EDGE-SYNC-ed DISTANCE FROM EoDY-EDGE
              % 86400000000             // MODULO DAY-LENGTH ROLL-OVER
              );                        // ALL DST-MOVs TAKE PLACE OVER WEEKENDS, SO NOT DURING TRADING-HOURS, SHOULD BE JUST-ENOUGH GOOD SOLUTION :o)
}
// -----------------------------------------------------------------
uint Get_a_Millisecond_of_a_Day(){      // IMMUNE TO A uint ROLL-OVER ~ 49.7 DAYS
     return( Get_a_Microsecond_of_a_Day()
           / 1000
             );
}

+ Это решение работает во всех { Script | Советник | Пользовательский индикатор }

person user3666197    schedule 23.05.2017
comment
Я не заставляю вас, сэр, считать это ( цит.: ) тем, что вам нужно. Я помогу вам найти то, что доступно в экосистеме терминала MetaTrader4. Это встроено. Остальное должно быть спроектировано и реализовано (от частного настраиваемого клиента ntp до самонастраивающихся локальных часов с использованием только относительных [мс] или [нас] таймеров). - person user3666197; 23.05.2017

что-то вроде этого:

ulong time = GetTickCount(); // function(); time = GetTickCount()-time;

person Daniel Kniaz    schedule 20.05.2017
comment
Не работает. ulong time=GetTickCount(); time=GetTickCount()-time; Print("Time : ", time); . Он всегда печатает 0 - person Nitin; 23.05.2017
comment
может потому что 0 миллисекунд между операциями? посмотрите: gyazo.com/717aae7eb5d9f0ccd7693a892243c916 он спал ~ 160 мс и печатает 156. Я думаю, что GetTickCount () больше точным, затем Sleep() - person Daniel Kniaz; 23.05.2017
comment
@DanielKniaz — вызов system.currenttimemillis() возвращает абсолютное расстояние TimeDOMAIN от точки отсчета эпохи (т. е. от 1970-01-01T00:00:00ZULU). Относительная синхронизация раздела кода здесь бесполезна. - person user3666197; 13.06.2017

dt1 = TimeLocal()+2;
do
{
  dt2 = TimeLocal();
}
while(TimeSecons(dt2) < TimeSecons(dt1));

после финиша можно считать время с 0.000

person Sova    schedule 29.08.2019

Просто приведите значения к ulong и обязательно умножьте TimeGMT() на 1000.

для результата печати, приведенного к string :

ulong time = (ulong) TimeGMT()*1000 - (ulong) GetTickCount() ; 
Print("milliseconds: ",  (string)time);
person josef    schedule 05.05.2021