MQL5 定時器(EventSetTimer)與 OnTimer() 應用
📌 本文重點
學習 MQL5 的定時器功能:EventSetTimer()、OnTimer()、EventSetMillisecondTimer(),以及常見的定時任務應用場景。
學習 MQL5 的定時器功能:EventSetTimer()、OnTimer()、EventSetMillisecondTimer(),以及常見的定時任務應用場景。
什麼是定時器?
OnTick() 只在新報價時觸發。但有些任務需要按固定時間間隔執行(如每分鐘發送報告、每小時重建網格)。MQL5 的定時器讓你可以按時間觸發任務,不依賴報價。
int OnInit()
{
// 設定每 60 秒觸發一次 OnTimer()
if (!EventSetTimer(60))
{
Print("定時器設定失敗!");
return INIT_FAILED;
}
Print("定時器已設定,每 60 秒執行一次");
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
EventKillTimer(); // 務必在 OnDeinit 中關閉定時器
}
// 每 60 秒執行一次
void OnTimer()
{
datetime now = TimeCurrent();
Print("OnTimer 觸發:", TimeToString(now, TIME_DATE|TIME_SECONDS));
// 每小時整點執行特殊任務
MqlDateTime dt;
TimeToStruct(now, dt);
if (dt.min == 0)
{
Print("整點任務執行中...");
SendHourlyReport();
}
}
// 高精度計時器(毫秒)
void SetMillisecondTimer()
{
// 每 500 毫秒觸發
EventSetMillisecondTimer(500);
}
實際應用:定時心跳監控
datetime g_lastTickTime = 0;
int g_tickCount = 0;
int g_timerCount = 0;
void OnTick() { g_lastTickTime = TimeCurrent(); g_tickCount++; }
void OnTimer()
{
g_timerCount++;
// 計算距離上一個 Tick 的時間
int secondsSinceLastTick = (int)(TimeCurrent() - g_lastTickTime);
// 超過 5 分鐘沒有新 Tick → 可能斷線
if (secondsSinceLastTick > 300 && g_lastTickTime > 0)
{
Print("⚠️ 警告:超過 ", secondsSinceLastTick, " 秒沒有收到新報價!");
Alert("EA 可能斷線!距上次報價: " + IntegerToString(secondsSinceLastTick) + " 秒");
}
// 每 10 次定時器(10分鐘)輸出一次統計
if (g_timerCount % 10 == 0)
{
Comment(StringFormat(
"EA 運行狀態
"
"累計 Tick: %d
"
"定時器計數: %d
"
"距上次 Tick: %d 秒
"
"持倉數: %d",
g_tickCount, g_timerCount,
secondsSinceLastTick,
PositionsTotal()
));
}
}
OnTimer() 與 OnTick() 的選擇
| 場景 | 建議使用 |
|---|---|
| 技術指標訊號、下單邏輯 | OnTick() |
| 定時報告、心跳監控 | OnTimer() |
| 每日重置、時段過濾 | OnTimer() + 時間判斷 |
| WebRequest(Telegram 通知) | OnTimer()(避免每個 Tick 都發送) |
本文由 James Lee 撰寫。內容僅供教育目的,不構成投資建議。