اتصال متاتریدر به تلگرام: ارسال اعلان از اکسپرت با WebRequest
پاسخ کوتاه: برای اتصال متاتریدر به تلگرام یک ربات تلگرام با BotFather بسازید، توکن و شناسه چت (chat_id) را بردارید، نشانی https://api.telegram.org را در تنظیمات متاتریدر مجاز کنید و در اکسپرت با تابع WebRequest متد sendMessage را صدا بزنید. WebRequest در اندیکاتور و Strategy Tester کار نمیکند و تا رسیدن پاسخ، اکسپرت را نگه میدارد؛ پس فقط برای رویدادهای مهم پیام بفرستید.
اعلان تلگرام از اکسپرت به چه کاری میآید؟
رباتی که روی VPS یا کامپیوتر خانه کار میکند، بیشتر وقتها جلوی چشم شما نیست. اعلان تلگرام همان چیزهایی را که در زبانههای Experts و Journal متاتریدر ثبت میشود، به گوشیتان میرساند. کاربردهای رایج:
- باز و بسته شدن معامله: نماد، حجم، قیمت و نتیجه معامله.
- هشدار ریسک: وقتی افت سرمایه (Drawdown) از حدی که تعیین کردهاید گذشت یا ربات به سقف ضرر روزانه رسید.
- خطاهای اجرایی: رد شدن سفارش، قطع ارتباط با سرور بروکر یا خاموش شدن Auto Trading.
- گزارش دورهای: مثلاً هر روز در ساعتی مشخص، موجودی، Equity و تعداد معاملههای باز.
اعلان، خودِ معامله را بهتر نمیکند؛ فقط زودتر خبردارتان میکند. اگر ربات بیدلیل معامله باز نمیکند، اول دلیلهای باز نشدن معامله در ربات را بررسی کنید و اگر Auto Trading مدام خاموش میشود، حل مشکل Auto Trading Off را.
پیشنیاز: ربات تلگرام، توکن و chat_id
ساخت ربات با BotFather
- در تلگرام حساب
@BotFatherرا باز کنید و دستور/newbotرا بفرستید. - یک نام نمایشی و یک نام کاربری که به
botختم شود انتخاب کنید. - BotFather یک توکن میدهد، رشتهای شبیه
123456789:AA.... این توکن رمز ربات شماست و جایی منتشرش نکنید.
پیدا کردن chat_id
ربات فقط به چتی پیام میدهد که شناسهاش را داشته باشد و قبلاً با آن در تماس بوده باشد:
- چت خصوصی: به ربات خودتان پیام
/startبدهید، سپس نشانیhttps://api.telegram.org/bot<TOKEN>/getUpdatesرا در مرورگر باز کنید و به جای<TOKEN>توکن خودتان را بگذارید. عددی که بعد از"chat":{"id":آمده، شناسه چت شماست. - گروه: ربات را به گروه اضافه کنید و در گروه دستوری مثل
/startبفرستید. شناسه گروه در همان getUpdates عددی منفی است. - کانال: ربات را مدیر (Admin) کانال کنید. برای کانال عمومی میتوانید به جای عدد، نام کاربری کانال را با @ بدهید، مثل
@channelusername.
مجاز کردن نشانی تلگرام در متاتریدر
متاتریدر به هیچ اکسپرتی اجازه نمیدهد به هر نشانی اینترنتی درخواست بفرستد. از منوی Tools ← Options، در زبانه Expert Advisors گزینه Allow WebRequest for listed URL را تیک بزنید و https://api.telegram.org را به فهرست اضافه کنید. اگر این کار انجام نشود، WebRequest مقدار -1 برمیگرداند و پیامی نمیرسد. این تنظیم برای هر نصب متاتریدر جداست و روی VPS هم باید دوباره انجام شود.
کد ارسال پیام در MQL5
تابع زیر پیام را به شکل JSON و با رمزگذاری UTF-8 میفرستد، پس متن فارسی هم درست میرسد:
input string InpBotToken = ""; // token from @BotFather
input string InpChatId = ""; // numeric chat id or @channelusername
string JsonEscape(string s)
{
StringReplace(s, "\\", "\\\\");
StringReplace(s, "\"", "\\\"");
StringReplace(s, "\r", "\\r");
StringReplace(s, "\n", "\\n");
StringReplace(s, "\t", "\\t");
return s;
}
bool SendTelegram(const string text)
{
if(InpBotToken == "" || InpChatId == "")
return false;
if(MQLInfoInteger(MQL_TESTER)) // WebRequest does not run in the Strategy Tester
return true;
string url = "https://api.telegram.org/bot" + InpBotToken + "/sendMessage";
string body = "{\"chat_id\":\"" + JsonEscape(InpChatId) + "\",\"text\":\"" + JsonEscape(text) + "\"}";
char data[], result[];
int len = StringToCharArray(body, data, 0, WHOLE_ARRAY, CP_UTF8);
ArrayResize(data, len - 1); // drop the terminating zero
string result_headers;
ResetLastError();
int code = WebRequest("POST", url, "Content-Type: application/json\r\n", 5000, data, result, result_headers);
if(code != 200)
{
PrintFormat("Telegram failed: HTTP %d, error %d, %s", code, GetLastError(),
CharArrayToString(result, 0, WHOLE_ARRAY, CP_UTF8));
return false;
}
return true;
}
چند نکته درباره همین کد:
CP_UTF8باعث میشود حروف فارسی درست تبدیل شوند. بدون آن، متن فارسی خراب به تلگرام میرسد.StringToCharArrayصفر انتهای رشته را هم در آرایه میگذارد.ArrayResize(data, len - 1)آن را حذف میکند تا بدنه درخواست فقط همان JSON باشد.- عدد
5000مهلت انتظار به میلیثانیه است. WebRequest همزمان (synchronous) است: تا پاسخ نرسد یا مهلت تمام نشود، اکسپرت کار دیگری نمیکند. - اگر ارسال شکست بخورد، کد HTTP، کد خطا و پاسخ تلگرام در زبانه Experts ثبت میشود. خواندن این کدها را در آموزش Error Handling در MT5 توضیح دادهایم.
کِی پیام بفرستیم؟ اعلان باز و بسته شدن معامله
بهترین جا برای اعلان معامله در MQL5 رویداد OnTradeTransaction است. این رویداد فقط وقتی اجرا میشود که در حساب اتفاقی بیفتد، پس برخلاف OnTick با هر تیک قیمت صدا زده نمیشود:
input long InpMagic = 20251025; // only this EA's trades
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
if(trans.type != TRADE_TRANSACTION_DEAL_ADD || !HistoryDealSelect(trans.deal))
return;
if(HistoryDealGetInteger(trans.deal, DEAL_MAGIC) != InpMagic)
return;
string symbol = HistoryDealGetString(trans.deal, DEAL_SYMBOL);
int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
double volume = HistoryDealGetDouble(trans.deal, DEAL_VOLUME);
double price = HistoryDealGetDouble(trans.deal, DEAL_PRICE);
long entry = HistoryDealGetInteger(trans.deal, DEAL_ENTRY);
if(entry == DEAL_ENTRY_IN)
SendTelegram(StringFormat("Opened %s %.2f lot at %s", symbol, volume, DoubleToString(price, digits)));
else if(entry == DEAL_ENTRY_OUT)
SendTelegram(StringFormat("Closed %s %.2f lot, profit %.2f", symbol, volume,
HistoryDealGetDouble(trans.deal, DEAL_PROFIT)));
}
فیلتر Magic Number باعث میشود معاملههای دستی یا اکسپرتهای دیگرِ همان حساب اعلان نفرستند؛ اگر با این شماره آشنا نیستید، تنظیم Magic Number در ربات معاملهگر را ببینید. DEAL_PROFIT سود یا زیان ناخالص است و کمیسیون و سواپ جدا ثبت میشوند (DEAL_COMMISSION و DEAL_SWAP).
برای گزارش روزانه یا هشدار افت سرمایه، به جای OnTick از OnTimer استفاده کنید تا وضعیت حساب مثلاً هر پنج دقیقه یک بار بررسی شود. فرق این دو رویداد را در تفاوت OnTick و OnTimer در ربات معاملهگر نوشتهایم.
نکتههایی که اعلان را قابل اعتماد نگه میدارد
- کم و بهجا بفرستید. تلگرام توصیه میکند در یک چت بیش از یک پیام در ثانیه فرستاده نشود و در گروه سقف ۲۰ پیام در دقیقه است. اکسپرتی که با هر تیک پیام بدهد، هم خودش کند میشود و هم به خطای 429 میخورد.
- توکن را داخل کد ننویسید. هر کس توکن را داشته باشد، از طرف ربات شما پیام میفرستد. توکن را پارامتر ورودی بگذارید، فایل اکسپرتی را که توکن داخلش است به کسی ندهید و اگر توکن لو رفت، با دستور
/revokeدر BotFather توکن تازه بگیرید. - اندیکاتور نمیتواند پیام بدهد. WebRequest در اندیکاتور مجاز نیست و خطای 4014 در MQL5 (و 4060 در MQL4) میدهد. اگر هشدار از اندیکاتور میآید، ارسال را به اکسپرت یا اسکریپت بسپارید.
- در بکتست پیامی نمیآید. WebRequest در Strategy Tester اجرا نمیشود. برای آزمودن اعلانها، اکسپرت را روی حساب دمو اجرا کنید؛ کار با تستر را در آموزش استفاده از Strategy Tester در متاتریدر ببینید.
- دسترسی شبکه را در نظر بگیرید. تلگرام در ایران فیلتر است. اگر متاتریدر روی کامپیوتر یا سروری داخل ایران اجرا شود، درخواست به
api.telegram.orgمعمولاً به جایی نمیرسد و فقط خطا ثبت میشود. برای همین اعلان تلگرام بیشتر روی سرور مجازی خارج از ایران به کار میرود؛ راهاندازی ربات روی VPS و مزایا و معایب VPS برای ربات را ببینید.
در MQL4 چه فرقی دارد؟
WebRequest در MQL4 هم با همین دو شکل وجود دارد و همان مجوز نشانی در Tools ← Options لازم است، پس تابع SendTelegram تقریباً بدون تغییر کار میکند. فرق اصلی در تشخیص معامله است: MQL4 رویداد OnTradeTransaction ندارد و باید در OnTick یا OnTimer تعداد سفارشهای باز و تاریخچه را با دفعه قبل مقایسه کنید. تفاوتهای دیگر دو زبان را در تفاوت MQL4 و MQL5 در ساخت Expert Advisor مرور کردهایم.
جایگزین سادهتر: اعلان داخلی متاتریدر
اگر فقط میخواهید روی گوشی خودتان خبردار شوید، تابع SendNotification پیام را به اپ موبایل متاتریدر میفرستد. لازم نیست نشانیای را مجاز کنید؛ کافی است MetaQuotes ID اپ موبایل را در زبانه Notifications تنظیمات متاتریدر وارد کنید. در عوض محدودتر است:
| ویژگی | تلگرام با WebRequest | SendNotification |
|---|---|---|
| گیرنده | چت خصوصی، گروه یا کانال، برای چند نفر | اپ موبایل متاتریدر با MetaQuotes ID |
| طول پیام | تا ۴۰۹۶ نویسه | تا ۲۵۵ نویسه |
| سقف ارسال | حدود یک پیام در ثانیه در هر چت؛ ۲۰ پیام در دقیقه در گروه | ۲ پیام در ثانیه و ۱۰ پیام در دقیقه |
| تنظیم لازم | ساخت ربات، توکن، chat_id و مجوز نشانی | وارد کردن MetaQuotes ID |
| در Strategy Tester | کار نمیکند | کار نمیکند |
خطاهای رایج و راه رفع
| نشانه | علت محتمل | راه رفع |
|---|---|---|
WebRequest مقدار -1 برمیگرداند |
نشانی در فهرست مجاز نیست، تابع از اندیکاتور صدا زده شده یا اینترنت به تلگرام وصل نمیشود | https://api.telegram.org را در Options اضافه کنید و کد GetLastError را در زبانه Experts ببینید |
| خطای 400 با پیام chat not found | chat_id اشتباه است یا هنوز به ربات پیام ندادهاید | به ربات /start بدهید و chat_id را دوباره از getUpdates بخوانید |
| خطای 401 | توکن اشتباه است یا باطل شده | توکن را دوباره از BotFather کپی کنید |
| خطای 403 | ربات را بلاک کردهاید، از گروه حذف شده یا در کانال مدیر نیست | ربات را از بلاک درآورید یا دوباره به گروه یا کانال (با دسترسی مدیر) اضافه کنید |
| خطای 429 | تعداد پیامها از سقف تلگرام گذشته | ارسال را به رویدادهای مهم محدود کنید و پیامهای نزدیک به هم را یکی کنید |
| متن فارسی خراب میرسد | رشته بدون CP_UTF8 به آرایه تبدیل شده |
در StringToCharArray و CharArrayToString از CP_UTF8 استفاده کنید |
جمعبندی
اتصال متاتریدر به تلگرام سه بخش دارد: ربات و chat_id در تلگرام، مجوز نشانی در متاتریدر و چند خط WebRequest در اکسپرت. چیزی که اعلان را مفید نگه میدارد، انتخاب درست رویدادهاست: باز و بسته شدن معامله، عبور از سقف افت سرمایه و خطاهای اجرایی، نه هر تیک قیمت. پیش از اجرای واقعی، اکسپرت را روی حساب دمو امتحان کنید تا مطمئن شوید پیامها میرسند و ربات کند نمیشود.
منبعها: مستند رسمی WebRequest و SendNotification در MQL5، WebRequest در MQL4، Telegram Bot API و پرسشهای متداول رباتهای تلگرام.
اگر اکسپرتی با اعلان تلگرام، هشدار افت سرمایه یا گزارش روزانه میخواهید، درخواستتان را در صفحه برنامهنویسی اکسپرت MQL ثبت کنید. برای ساخت ربات کامل از صفر هم سفارش ربات متاتریدر را ببینید.
دیدگاهها