MQL5 Telegram 通知:WebRequest 串接機器人推送交易訊息

📌 本文重點
學習使用 MQL5 的 WebRequest() 函數,透過 Telegram Bot API 即時推送交易通知到你的手機,包括開倉、平倉、警報訊息。

前置準備:建立 Telegram Bot

  1. 在 Telegram 搜尋 @BotFather
  2. 發送 /newbot,依指示設定 Bot 名稱
  3. 取得 Bot Token(格式:123456789:ABCdef...
  4. 與你的 Bot 對話,然後訪問 https://api.telegram.org/bot[TOKEN]/getUpdates 取得你的 Chat ID

MT5 設定:允許 WebRequest

在 MT5 中:「工具」→「選項」→「Expert Advisors」→ 勾選「允許 WebRequest 到以下 URL」→ 加入 https://api.telegram.org

MQL5 實作

input string InpBotToken = "YOUR_BOT_TOKEN";  // Telegram Bot Token
input string InpChatID   = "YOUR_CHAT_ID";    // 你的 Chat ID

// 發送 Telegram 訊息
bool SendTelegram(string message)
{
    string url = StringFormat("https://api.telegram.org/bot%s/sendMessage", InpBotToken);

    // URL 編碼訊息(替換特殊字元)
    StringReplace(message, "&", "%26");
    StringReplace(message, "+", "%2B");
    StringReplace(message, "#", "%23");

    string body = StringFormat("chat_id=%s&text=%s&parse_mode=HTML", InpChatID, message);

    char   postData[];   StringToCharArray(body, postData, 0, StringLen(body));
    char   result[];
    string responseHeaders;

    int res = WebRequest(
        "POST",
        url,
        "Content-Type: application/x-www-form-urlencoded
",
        5000,        // 超時 5 秒
        postData,
        result,
        responseHeaders
    );

    if (res == 200)
    {
        Print("Telegram 訊息發送成功");
        return true;
    }
    else
    {
        Print("Telegram 發送失敗!HTTP 狀態: ", res, " 錯誤: ", GetLastError());
        return false;
    }
}

// 格式化並發送開倉通知
void NotifyOpen(string symbol, string direction, double lots, double price, double sl, double tp)
{
    string msg = StringFormat(
        "🟢 <b>開倉通知</b>
"
        "品種: %s | 方向: %s
"
        "手數: %.2f | 價格: %s
"
        "止損: %s | 止盈: %s
"
        "帳戶: $%.2f
"
        "時間: %s",
        symbol, direction,
        lots, DoubleToString(price, (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS)),
        DoubleToString(sl, (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS)),
        DoubleToString(tp, (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS)),
        AccountInfoDouble(ACCOUNT_EQUITY),
        TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES)
    );
    SendTelegram(msg);
}

// 發送平倉通知
void NotifyClose(string symbol, double profit, double lots)
{
    string emoji = profit >= 0 ? "💰" : "🔴";
    string msg = StringFormat(
        "%s <b>平倉通知</b>
"
        "品種: %s | 手數: %.2f
"
        "盈虧: %+.2f USD
"
        "帳戶餘額: $%.2f",
        emoji, symbol, lots, profit,
        AccountInfoDouble(ACCOUNT_BALANCE)
    );
    SendTelegram(msg);
}

// 每日報告
void SendDailyReport()
{
    static datetime lastReport = 0;
    MqlDateTime dt;
    TimeToStruct(TimeCurrent(), dt);

    // 每天 20:00 GMT 發送日報
    if (dt.hour == 20 && dt.min == 0 && TimeCurrent() - lastReport > 3600)
    {
        lastReport = TimeCurrent();
        double balance  = AccountInfoDouble(ACCOUNT_BALANCE);
        double equity   = AccountInfoDouble(ACCOUNT_EQUITY);
        double margin   = AccountInfoDouble(ACCOUNT_MARGIN_LEVEL);
        int    positions= PositionsTotal();

        string msg = StringFormat(
            "📊 <b>每日交易報告</b>
"
            "餘額: $%.2f | 淨值: $%.2f
"
            "保證金水平: %.1f%%
"
            "目前持倉: %d",
            balance, equity, margin, positions
        );
        SendTelegram(msg);
    }
}

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

Similar Posts

發佈留言

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