MQL5 新聞過濾器:重大事件前後自動暫停 EA

📌 本文重點
實作 MQL5 新聞過濾器:透過 WebRequest 取得 Forex Factory 日曆,或手動設定重大新聞時段,讓 EA 在高影響力事件前後自動暫停交易。

為什麼需要新聞過濾器?

非農就業(NFP)、FOMC 利率決議、CPI 等高影響力數據公布時,市場可能在幾秒內移動數百點。EA 在這段時間的止損可能被穿越,或出現異常滑點。新聞過濾器幫助你在這些時段暫停交易。

方法一:手動設定新聞時間

// 定義新聞事件結構
struct NewsEvent
{
    string name;         // 事件名稱
    int    dayOfWeek;    // 星期幾(0=週日, 5=週五)
    int    hour;         // 小時(GMT)
    int    minute;       // 分鐘
    int    pauseBefore;  // 事件前幾分鐘暫停(分鐘)
    int    pauseAfter;   // 事件後幾分鐘暫停(分鐘)
};

// 設定本週重大新聞(每週更新)
NewsEvent g_newsEvents[] =
{
    {"NFP(非農就業)",      5, 12, 30, 30, 60},  // 週五 12:30 GMT
    {"FOMC 利率決議",        3, 18,  0, 60, 120}, // 週三 18:00 GMT
    {"美國CPI數據",          2, 12, 30, 30, 30},  // 週二 12:30 GMT
    {"ECB 利率決議",         4, 11, 45, 30, 60}   // 週四 11:45 GMT
};

bool IsNewsTime()
{
    MqlDateTime dt;
    TimeToStruct(TimeGMT(), dt);  // 使用 GMT 時間

    for (int i = 0; i < ArraySize(g_newsEvents); i++)
    {
        NewsEvent &ev = g_newsEvents[i];
        if (dt.day_of_week != ev.dayOfWeek) continue;

        // 計算事件時間(GMT 分鐘數)
        int eventMinutes  = ev.hour * 60 + ev.minute;
        int currentMinutes= dt.hour * 60 + dt.min;

        int diffBefore = eventMinutes - currentMinutes;
        int diffAfter  = currentMinutes - eventMinutes;

        if (diffBefore >= 0 && diffBefore <= ev.pauseBefore)
        {
            Print("新聞前暫停:", ev.name, " 還有 ", diffBefore, " 分鐘");
            return true;
        }
        if (diffAfter >= 0 && diffAfter <= ev.pauseAfter)
        {
            Print("新聞後暫停:", ev.name, " 已過 ", diffAfter, " 分鐘");
            return true;
        }
    }
    return false;
}

void OnTick()
{
    if (IsNewsTime())
    {
        Comment("⚠️ 新聞時段,交易暫停中...");
        return;
    }
    Comment("✅ 正常交易中");
    // ... 正常交易邏輯
}

方法二:週末與非交易時段過濾

input int InpTradingStartHour = 8;   // 交易開始時間(GMT)
input int InpTradingEndHour   = 20;  // 交易結束時間(GMT)
input bool InpAvoidFriday     = true; // 避開週五晚間
input bool InpAvoidMonday     = true; // 避開週一開盤

bool IsTradingSession()
{
    MqlDateTime dt;
    TimeToStruct(TimeGMT(), dt);

    // 週末不交易
    if (dt.day_of_week == 0 || dt.day_of_week == 6) return false;

    // 週一開盤前兩小時不交易
    if (InpAvoidMonday && dt.day_of_week == 1 && dt.hour < 2) return false;

    // 週五下午4點後不開新倉
    if (InpAvoidFriday && dt.day_of_week == 5 && dt.hour >= 16) return false;

    // 只在指定時段交易
    if (dt.hour < InpTradingStartHour || dt.hour >= InpTradingEndHour) return false;

    return true;
}

本文由 James Lee 撰寫。內容僅供教育目的,不構成投資建議。

Similar Posts

發佈留言

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