⚡
MT5 Signal Receiver

📖 Tài Liệu Tích Hợp Webhook Bot MT5 (MQL5)

Dành cho team lập trình Bot MetaTrader 5 để gửi tín hiệu mở lệnh, đóng lệnh và cảnh báo sang hệ thống.

1 Thông Tin Kết Nối Webhook
Webhook URL (POST)
https://mt5-receiver.newgen.com.vn/webhook
Content-Type Header
application/json
Auth Header
x-api-key: <API_KEY_CỦA_BẠN>
2 Bước Bắt Buộc Trên MT5 Terminal
⚠️ QUAN TRỌNG: Mặc định MT5 chặn toàn bộ kết nối ra Internet. Nếu không thêm domain vào whitelist, bot sẽ bị chặn và báo lỗi Error 4060.
  1. Mở MT5 Terminal -> Nhấn Ctrl + O (hoặc vào menu Tools -> Options).
  2. Chuyển sang tab Expert Advisors.
  3. Tích chọn vào ô: Allow WebRequest for listed URL.
  4. Bấm đúp vào dòng Add new URL... và dán chính xác URL sau:
    https://mt5-receiver.newgen.com.vn
    (Lưu ý: Không thêm /webhook ở bước whitelist này, chỉ nhập tên miền).
  5. Nhấn OK để lưu lại.
3 Thư Viện Helper MQL5 (WebhookSender.mqh)
Tải file .mqh

Copy đoạn class sau dán vào đầu bot của bạn hoặc lưu vào thư mục MQL5/Include/WebhookSender.mqh:

MQL5 Header - WebhookSender.mqh
//+------------------------------------------------------------------+
//| Class CWebhookSender: Gửi tín hiệu từ MT5 sang Server qua Webhook|
//+------------------------------------------------------------------+
class CWebhookSender
{
private:
   string   m_url;
   string   m_api_key;
   int      m_timeout;

public:
   CWebhookSender(void)
   {
      m_url     = "https://mt5-receiver.newgen.com.vn/webhook";
      m_api_key = "";
      m_timeout = 3000;
   }

   void Init(string url, string api_key, int timeout_ms = 3000)
   {
      m_url     = url;
      m_api_key = api_key;
      m_timeout = timeout_ms;
   }

   // Gửi chuỗi JSON bất kỳ
   bool SendJson(string json_body)
   {
      char post_data[];
      char result_data[];
      string result_headers;
      string response_text;

      int data_size = StringToCharArray(json_body, post_data, 0, WHOLE_ARRAY, CP_UTF8);
      if(data_size > 0 && post_data[data_size - 1] == 0)
         ArrayResize(post_data, data_size - 1);

      string headers = "Content-Type: application/json\r\n" +
                       "x-api-key: " + m_api_key + "\r\n";

      ResetLastError();
      int status = WebRequest("POST", m_url, headers, m_timeout, post_data, result_data, result_headers);

      if(status == -1)
      {
         int err = GetLastError();
         Print("[Webhook ERROR] Code: ", err, " - Kiểm tra MT5 Options whitelist URL: ", m_url);
         return false;
      }

      response_text = CharArrayToString(result_data, 0, WHOLE_ARRAY, CP_UTF8);
      if(status >= 200 && status < 300)
      {
         Print("[Webhook OK] ", response_text);
         return true;
      }

      Print("[Webhook Failed] HTTP ", status, " - ", response_text);
      return false;
   }

   // Gửi sự kiện giao dịch (Mở/Đóng lệnh)
   bool SendSignal(string event_type, string symbol, string order_type, double volume,
                   double price, double sl = 0.0, double tp = 0.0, double profit = 0.0,
                   ulong ticket = 0, long magic = 0, string comment = "")
   {
      string json = "{" +
         "\"event\":\"" + event_type + "\"," +
         "\"symbol\":\"" + symbol + "\"," +
         "\"type\":\"" + order_type + "\"," +
         "\"volume\":" + DoubleToString(volume, 2) + "," +
         "\"price\":" + DoubleToString(price, 5) + "," +
         "\"sl\":" + DoubleToString(sl, 5) + "," +
         "\"tp\":" + DoubleToString(tp, 5) + "," +
         "\"profit\":" + DoubleToString(profit, 2) + "," +
         "\"ticket\":" + IntegerToString(ticket) + "," +
         "\"magic\":" + IntegerToString(magic) + "," +
         "\"comment\":\"" + comment + "\"," +
         "\"time\":\"" + TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS) + "\"" +
      "}";
      return SendJson(json);
   }

   // Gửi tin nhắn text cảnh báo/thông báo
   bool SendAlert(string message, string symbol = "")
   {
      string json = "{" +
         "\"event\":\"ALERT\"," +
         "\"symbol\":\"" + symbol + "\"," +
         "\"message\":\"" + message + "\"," +
         "\"time\":\"" + TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS) + "\"" +
      "}";
      return SendJson(json);
   }
};
4 Ví Dụ Tích Hợp Vào Bot EA (Code Mẫu Đầy Đủ)

Ví dụ bắt sự kiện tự động khi bot mở lệnh hoặc đóng lệnh bằng hàm OnTradeTransaction():

MQL5 Expert Advisor - ExampleEA.mq5
// Khai báo cấu hình ở đầu file bot
input string InpWebhookUrl = "https://mt5-receiver.newgen.com.vn/webhook";
input string InpApiKey     = "secret-mt5-key-bot-01"; // Điền API Key được cấp
input long   InpMagic      = 123456;                  // Magic number của Bot

CWebhookSender g_webhook;

int OnInit()
{
   // Khởi tạo webhook
   g_webhook.Init(InpWebhookUrl, InpApiKey);

   // Gửi alert test kiểm tra kết nối khi khởi động
   g_webhook.SendAlert("Bot started on Account: " + IntegerToString(AccountInfoInteger(ACCOUNT_LOGIN)), _Symbol);
   return(INIT_SUCCEEDED);
}

// Hàm bắt sự kiện giao dịch tự động của MT5
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
{
   if(trans.type == TRADE_TRANSACTION_DEAL_ADD)
   {
      ulong dealTicket = trans.deal;
      if(dealTicket > 0 && HistoryDealSelect(dealTicket))
      {
         long dealMagic = HistoryDealGetInteger(dealTicket, DEAL_MAGIC);
         if(InpMagic == 0 || dealMagic == InpMagic)
         {
            ENUM_DEAL_ENTRY dealEntry = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(dealTicket, DEAL_ENTRY);
            ENUM_DEAL_TYPE  dealType  = (ENUM_DEAL_TYPE)HistoryDealGetInteger(dealTicket, DEAL_TYPE);
            
            string symbol     = HistoryDealGetString(dealTicket, DEAL_SYMBOL);
            double volume     = HistoryDealGetDouble(dealTicket, DEAL_VOLUME);
            double price      = HistoryDealGetDouble(dealTicket, DEAL_PRICE);
            double profit     = HistoryDealGetDouble(dealTicket, DEAL_PROFIT);
            string comment    = HistoryDealGetString(dealTicket, DEAL_COMMENT);
            ulong  positionId = HistoryDealGetInteger(dealTicket, DEAL_POSITION_ID);
            string typeStr    = (dealType == DEAL_TYPE_BUY) ? "BUY" : "SELL";

            // 1. KHI MỞ LỆNH THÀNH CÔNG
            if(dealEntry == DEAL_ENTRY_IN)
            {
               double sl = 0.0, tp = 0.0;
               if(PositionSelectByTicket(positionId))
               {
                  sl = PositionGetDouble(POSITION_SL);
                  tp = PositionGetDouble(POSITION_TP);
               }

               g_webhook.SendSignal("ORDER_OPEN", symbol, typeStr, volume, price, sl, tp, 0.0, positionId, dealMagic, comment);
            }
            // 2. KHI ĐÓNG LỆNH (CHỐT LỜI / CẮT LỖ / ĐÓNG TAY)
            else if(dealEntry == DEAL_ENTRY_OUT || dealEntry == DEAL_ENTRY_OUT_BY)
            {
               g_webhook.SendSignal("ORDER_CLOSE", symbol, typeStr, volume, price, 0.0, 0.0, profit, positionId, dealMagic, comment);
            }
         }
      }
   }
}
5 Định Dạng Dữ Liệu JSON (Payload Spec)
JSON Schema Example
{
  "event": "ORDER_OPEN",         // "ORDER_OPEN" | "ORDER_CLOSE" | "ALERT" | "SIGNAL"
  "symbol": "XAUUSD",            // Cặp tiền
  "type": "BUY",                 // "BUY" | "SELL"
  "volume": 0.1,                 // Khối lượng lot
  "price": 2745.50,              // Giá khớp lệnh
  "sl": 2735.00,                 // Cắt lỗ (Stop Loss)
  "tp": 2765.00,                 // Chốt lời (Take Profit)
  "profit": 0.0,                 // Lợi nhuận (khi đóng lệnh)
  "ticket": 12345678,            // Ticket / Position ID
  "magic": 123456,               // Magic number của EA
  "comment": "Trend Strategy",   // Ghi chú lệnh
  "time": "2026-10-31 22:00:00"  // Thời gian
}

* Server hỗ trợ dynamic schema, bạn có thể truyền thêm bất kỳ trường nào khác vào JSON, server đều ghi nhận nguyên bản vào database.

6 Bảng Mã Lỗi Thường Gặp Trên MT5
Mã Lỗi Nguyên Nhân Cách Khắc Phục
Error 4060 Chưa whitelist URL trong MT5 Nhấn Ctrl + O -> Tab Expert Advisors -> Bật Allow WebRequest và thêm https://mt5-receiver.newgen.com.vn.
HTTP 401 / 403 Sai hoặc thiếu API Key Kiểm tra biến InpApiKey truyền vào hàm g_webhook.Init(...) có khớp với key được cấp không.
Error 5203 Timeout kết nối (> 3000ms) Kiểm tra đường truyền mạng hoặc tăng timeout_ms trong hàm Init(...) lên 5000ms.
Error 4014 Chạy nhầm trong Indicator Hàm WebRequest() của MT5 chỉ hoạt động trong Expert Advisor (EA), không chạy được trong Indicator.
Đã copy code vào clipboard!