Содержание
Введение
Одной из распространенных задач при автоматизации трейдинга является отправка торговых сигналов или уведомлений в Telegram. Однако многие программисты сталкиваются с серьезным ограничением: в индикаторах MetaTrader 4 и 5 запрещено использовать функцию WebRequest(), без которой невозможно напрямую взаимодействовать с внешними API, включая Telegram Bot API.
В этой статье я расскажу об элегантном решении этой проблемы без использования сторонних DLL, основанном на механизме кастомных событий терминала MetaTrader.
Проблема и ограничения
При разработке индикаторов для MT4/MT5 разработчики сталкиваются с рядом ограничений безопасности:
- В индикаторах запрещено использовать функцию
WebRequest() - Нельзя напрямую подключать внешние DLL для обхода этого ограничения (это небезопасно и есть ограничения)
- Индикаторы и DLL работают в одном потоке , поэтому введены ограничения на DLL, чтобы не завис терминал.
Решение: Механизм кастомных событий
MetaTrader предоставляет механизм пользовательских событий CHARTEVENT_CUSTOM, который позволяет обмениваться данными между разными элементами платформы — индикаторами, советниками и скриптами.
Суть решения:
- Индикатор генерирует кастомное событие с необходимыми данными
- Советник (эксперт), установленный на любом графике, перехватывает это событие
- Советник использует WebRequest для отправки сообщения в Telegram Bot API
Шаг 1: Реализация отправки событий из индикатора
Для отправки сигналов из индикатора в советник нам понадобится универсальная функция SendEvent():
//+------------------------------------------------------------------+
//| Отправка кастомного события всем открытым графикам |
//+------------------------------------------------------------------+
#define MSG_TELEGRAM_TEXT CHARTEVENT_CUSTOM+2
void SendEvent(ushort broadcastEventID, long lparam, double dparam, string sparam)
{
// CHARTEVENT_CUSTOM начинается с 1000, поэтому вычитаем это значение
// Максимальный ID события может быть 65534
ushort eventID = (ushort)(broadcastEventID - CHARTEVENT_CUSTOM);
long currChart = ChartFirst();
int i = 0;
const int CHARTS_MAX = 100; // Максимальное количество графиков для обработки
while(i < CHARTS_MAX)
{
EventChartCustom(currChart, eventID, lparam, dparam, sparam);
currChart = ChartNext(currChart);
if(currChart == 0)
break;
i++;
}
} Эта функция отправляет кастомное событие всем открытым в терминале графикам. Теперь в коде индикатора при необходимости отправить сообщение в Telegram достаточно вызвать:
// Пример отправки сигнала в Telegram из индикатора
SendEvent(MSG_TELEGRAM_TEXT, ChatID, 0.0, "Обнаружен сигнал на покупку по паре EURUSD H1"); Шаг 2: Создание советника-посредника TelegramBridge
Советник будет принимать кастомные события и отправлять сообщения в Telegram. Полный код советника:
//+------------------------------------------------------------------+
//| TelegramBridge.mq5 |
//+------------------------------------------------------------------+
#property copyright "Copyright (c) 2007 - 2025, Trading Shop"
#property link "https://trading-shop.ru"
#property version "1.000"
#property description "Посредник для отправки сообщений из индикаторов в Telegram"
input string InpToken = ""; // Token Bot, format: XXXXXXXXXX:HHHHHHHHHHHHHHH
input long InpUserID = 0; // User ID по умолчанию
// Определяем идентификатор события для Telegram сообщений
#define MSG_TELEGRAM_TEXT CHARTEVENT_CUSTOM+2
#include <TelegramAPI\\Telegram.mqh>
CTelegramAPI bot;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Проверяем наличие токена
if(InpToken == "" || StringLen(InpToken) < 10)
{
Alert("TelegramBridge: Необходимо указать токен бота в настройках!");
return(INIT_FAILED);
}
// Проверяем наличие ID пользователя
if(InpUserID == 0)
{
Alert("TelegramBridge: Необходимо указать User ID в настройках!");
return(INIT_FAILED);
}
// Инициализация Telegram бота
bot.OnInit(InpToken);
Print("TelegramBridge успешно инициализирован. Готов принимать сообщения.");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Очистка ресурсов при необходимости
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// В данном случае не требуется обработка тиков
}
//+------------------------------------------------------------------+
//| Обработчик событий |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, // идентификатор события
const long& lparam, // параметр события типа long
const double& dparam, // параметр события типа double
const string& sparam) // параметр события типа string
{
// Проверяем, является ли событие сообщением для Telegram
if(id == MSG_TELEGRAM_TEXT)
{
// Если в lparam указан конкретный ChatID (не 0), используем его
// Иначе используем ID по умолчанию из настроек
long chatID = (lparam > 0) ? lparam : InpUserID;
// Отправляем сообщение в Telegram
int result = bot.sendMessage(chatID, sparam);
if(result == 0) {
Print("Сообщение успешно отправлено в Telegram: ", sparam);
} else {
Print("Ошибка отправки в Telegram (код ", result, "): ", GetLastError());
}
}
}
//+------------------------------------------------------------------+ 
Шаг 3: Библиотека Telegram API
Для взаимодействия с Telegram Bot API используется библиотека TelegramAPI.mqh, код которой приведен в начале статьи. Эта библиотека реализует все необходимые функции для отправки сообщений и медиафайлов в Telegram.
Шаг 4: Настройка Telegram бота
- Создайте бота в Telegram через BotFather
- Скопируйте токен бота (формата XXXXXXXXX:YYYYYYYYYYYYYYYYYYYYY)
- Узнайте ваш User ID:
- В Telegram найдите и запустите бота @userinfobot
- Он автоматически сообщит ваш ID
- Альтернативный варианты: Web telegram для каналов и групп и MacOS, где в настройках включается отображать ID.
- Установите советник на любой график в терминале MT4/MT5
- В настройках советника укажите токен бота и ваш User ID
Преимущества данного подхода
- Безопасность: Не используются сторонние DLL, что исключает риски безопасности
- Простота интеграции: Для отправки сообщения из индикатора достаточно вызвать одну функцию
- Гибкость: Можно настроить несколько советников для разных целей или чатов, код открытый.
- Надежность: Механизм кастомных событий является встроенным в MetaTrader и работает стабильно
- Универсальность: Решение работает как в MT4, так и в MT5 без изменения кода.
Заключение
Предложенный подход позволяет обойти ограничения платформы MetaTrader на использование WebRequest в индикаторах, предоставляя разработчикам возможность отправлять торговые сигналы и уведомления в Telegram без компромиссов с безопасностью.
Ключевой элемент решения — механизм кастомных событий, который создает мост между индикаторами и советниками, позволяя последним выполнять «запрещенные» операции от имени первых.
Эта техника может быть расширена не только для отправки сообщений в Telegram, но и для других задач, требующих взаимодействия с внешними ресурсами или выполнения действий, запрещенных в индикаторах.