MQL5 定時器(EventSetTimer)與 OnTimer() 應用

📌 本文重點
學習 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 撰寫。內容僅供教育目的,不構成投資建議。

Similar Posts

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *