如何在 MetaTrader4 终端中获取当前毫秒数?
How to get current milliseconds in MetaTrader4 Terminal?
如何使用智能交易系统从 MQL4 获取当前毫秒数。
即:在 Java 中,我们可以使用 system.currenttimemillis()
获取当前毫秒数
像这样:
ulong time = GetTickCount();
// function();
time = GetTickCount()-time;
可以有相对[ms]甚至[us]:
注意两者是相对的,但一个与系统启动有关,另一个与 MQL4 代码执行单元启动有关。
The GetTickCount()
function returns the number of milliseconds that elapsed since the system start.
uint GetTickCount();
Counter is limited by the restrictions of the system timer. Time is stored as an unsigned integer, so it's overfilled every 49.7 days if a computer works uninterruptedly.
The GetMicrosecondCount()
function returns the number of microseconds that have elapsed since the start of MQL program.
ulong GetMicrosecondCount();
可以有绝对 [ms] 甚至 [us],带有 const(!) ABSOLUTE ERROR,
在精确测量时间时,既不会出现任何漂移,也不会出现抖动。
这对外汇领域来说不是很好吗,其中毫秒是 "full of events" 而微秒(在最近的专业级设计中是纳秒)很重要?!
// -----------------------------------------------------------------
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 |专家顾问 |自定义指标}
这个 MT4 "Get millisecond" 问题已经存在很久了。这是我为解决这个问题而创建的 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 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();
}
}
dt1 = TimeLocal()+2;
do
{
dt2 = TimeLocal();
}
while(TimeSecons(dt2) < TimeSecons(dt1));
完成后您可以从 0.000 开始计时
只需将值转换为 ulong
并确保将 TimeGMT()
乘以 1000
将打印结果转换为 string
:
ulong time = (ulong) TimeGMT()*1000 - (ulong) GetTickCount() ;
Print("milliseconds: ", (string)time);
如何使用智能交易系统从 MQL4 获取当前毫秒数。
即:在 Java 中,我们可以使用 system.currenttimemillis()
像这样:
ulong time = GetTickCount();
// function();
time = GetTickCount()-time;
可以有相对[ms]甚至[us]:
注意两者是相对的,但一个与系统启动有关,另一个与 MQL4 代码执行单元启动有关。
The
GetTickCount()
function returns the number of milliseconds that elapsed since the system start.
uint GetTickCount();
Counter is limited by the restrictions of the system timer. Time is stored as an unsigned integer, so it's overfilled every 49.7 days if a computer works uninterruptedly.
The
GetMicrosecondCount()
function returns the number of microseconds that have elapsed since the start of MQL program.
ulong GetMicrosecondCount();
可以有绝对 [ms] 甚至 [us],带有 const(!) ABSOLUTE ERROR,
在精确测量时间时,既不会出现任何漂移,也不会出现抖动。
这对外汇领域来说不是很好吗,其中毫秒是 "full of events" 而微秒(在最近的专业级设计中是纳秒)很重要?!
// -----------------------------------------------------------------
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 |专家顾问 |自定义指标}
这个 MT4 "Get millisecond" 问题已经存在很久了。这是我为解决这个问题而创建的 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 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();
}
}
dt1 = TimeLocal()+2;
do
{
dt2 = TimeLocal();
}
while(TimeSecons(dt2) < TimeSecons(dt1));
完成后您可以从 0.000 开始计时
只需将值转换为 ulong
并确保将 TimeGMT()
乘以 1000
将打印结果转换为 string
:
ulong time = (ulong) TimeGMT()*1000 - (ulong) GetTickCount() ;
Print("milliseconds: ", (string)time);