如何在 MetaTrader4 终端中获取当前毫秒数?

问题描述 投票:0回答:7

如何使用 Expert Advisor 从 MQL4 获取当前毫秒数。

即:在 Java 中,我们可以使用

system.currenttimemillis()

获取当前毫秒数
mql4 mql5 mt4
7个回答
3
投票

这个 MT4“获取毫秒”问题已经存在很长时间了。这是我为了解决这个问题而创建的一个 hack。

//+------------------------------------------------------------------+
//|                                                     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 milliseconds [see EventSetMillisecondTimer() in OnInit()]
void OnTimer() {
    // If a new "second" occurs, record GetTickCount()
    if(TimeLocal() > prevSecondTime) {
        prevSecondTick  = GetTickCount();
        prevSecondTime  = TimeLocal();
    }
}

2
投票

可以有亲戚[ms]甚至[us]:

请小心,因为两者都是相对的,但一个与系统启动有关,另一个与 MQL4 代码执行单元启动有关。

GetTickCount()
函数返回自系统启动以来经过的毫秒数。

uint  GetTickCount();

计数器受系统定时器的限制。时间存储为无符号整数,因此如果计算机不间断工作,每 49.7 天就会溢出。


GetMicrosecondCount()
函数返回自MQL程序启动以来已经过去的微秒数。

ulong GetMicrosecondCount();



可以有绝对 [ms] 甚至 [us],使用 const(!) 绝对错误,

在精确测量时间时不会表现出任何漂移或抖动。

这对于外汇领域来说不是很棒吗?在外汇领域,毫秒

“充满事件”

而微秒(最近专业级设计中的纳秒)很重要?! // ----------------------------------------------------------------- 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 |专家顾问 |自定义指标}


0
投票

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

    


0
投票
完成后可以从0.000开始计时


0
投票
ulong

并确保将

TimeGMT()
1000
 相乘
打印结果转换为

string

:

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



0
投票
kernel32.dll

)。通过使用

#include <WinAPI/windef.mqh>
,这似乎与 MQL5 更加集成,但也可以通过定义所需的结构与 MQL4 一起使用。
以下代码片段展示了如何在 MQL4 中获取它——在 MQL5 中,您无需定义结构,因为它们可以包含在内:

// MQL5 seems to have Include/WinAPI/windef.mqh - constants, structures and enumerations #ifdef __MQL4__ //+------------------------------------------------------------------+ //| MQL4 equivalent of Windows _FILETIME struct: GetSystemTimeAsFileTime(). //| @see: https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime //+------------------------------------------------------------------+ struct FILETIME { uint dwLowDateTime; uint dwHighDateTime; }; //+------------------------------------------------------------------+ //| MQL4 equivalent of Windows GetSystemTime()/GetLocalTime()/... struct. //| Credits: https://www.mql5.com/en/forum/146837/page3#comment_3702187 //+------------------------------------------------------------------+ struct SYSTEMTIME { ushort wYear; // 2014 etc ushort wMonth; // 1 - 12 ushort wDayOfWeek; // 0 - 6 with 0 = Sunday ushort wDay; // 1 - 31 ushort wHour; // 0 - 23 ushort wMinute; // 0 - 59 ushort wSecond; // 0 - 59 ushort wMilliseconds; // 0 - 999 string toString() { return StringFormat("%hu-%02hu-%02hu %02hu:%02hu:%02hu.%03hu", wYear, wMonth, wDay, wHour, wMinute, wSecond, wMilliseconds); } }; #endif #import "kernel32.dll" // Millisecond (ms) precision, but limited by Windows timer configuration?? (15-16 ms by default) void GetSystemTime(SYSTEMTIME &time); // (struct version) void GetLocalTime(SYSTEMTIME &time); // (struct version) // Microsecond (us) precision, limited by Windows timer configuration?? (15-16 ms by default) void GetSystemTimeAsFileTime(FILETIME& t); // (ulong version) Returns the system time in 100-nsec units #import

然后您可以定义用户友好的函数来获取上述函数的时间,例如

//+------------------------------------------------------------------+ //| Get the system time (UTC) in milliseconds. //| Credits: https://www.mql5.com/en/forum/146837/page4#comment_13522420 //+------------------------------------------------------------------+ ulong systemTimeMillis(){ FILETIME t; // time measured in 100-nano second units GetSystemTimeAsFileTime(t); ulong time = (long)t.dwHighDateTime << 32 | t.dwLowDateTime; ulong diffTo1970 = 11644473600000; // FILETIME starts at January 1, 1601 (UTC) return (ulong)(time * 0.0001 - diffTo1970); // 100-ns to ms (divide 10_000) } ulong localTimeMillis() { return systemTimeMillis() - TimeGMTOffset() * 1000; }

更多参考

    https://www.mql5.com/en/forum/146837/page3#comment_3702187
  • Windows 计时器分辨率:浪费兆瓦
  • 定时器、定时器分辨率和高效代码的开发

0
投票
© www.soinside.com 2019 - 2024. All rights reserved.