Copier signaux Telegram en MQL5 : code complet et bonnes pratiques

⏱ 7 min de lecture
Mis à jour le 14 mai 2026

Introduction : automatiser la copie de signaux Telegram avec MQL5

Les groupes Telegram de signaux de trading pullulent. Certains promettent des rendements mirobolants, d’autres sont de simples pompes à frais. Pourtant, pour un trader algorithmique, la question n’est pas de savoir si ces signaux sont bons ou mauvais, mais comment les intégrer dans un système automatisé fiable. Ce tutoriel vous montre comment écrire un Expert Advisor (EA) en MQL5 qui se connecte à un canal Telegram via l’API Bot, parse des messages formatés (ex : BUY EURUSD @ 1.0850 SL 1.0820 TP 1.0900), et ouvre des positions avec un money management paramétrable. Nous aborderons les pièges courants : latence, signaux contradictoires, et la réalité des signaux payants.

Prérequis techniques

Avant de coder, vous devez disposer :

  • D’un compte MetaTrader 5 avec un terminal compatible WebRequest (Windows, VPS).
  • D’un bot Telegram créé via @BotFather. Notez le token (ex : 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11).
  • De l’ID du canal ou du chat Telegram (vous pouvez utiliser @getidsbot pour le récupérer).
  • D’une autorisation WebRequest dans MetaTrader : Outils > Options > Expert Advisors > Autoriser les requêtes WebRequest pour les URL suivantes : ajoutez https://api.telegram.org.

Architecture de l’EA

Notre EA fonctionne en trois étapes :

  1. Polling : interroger l’API Telegram pour récupérer les nouveaux messages.
  2. Parsing : extraire les informations du signal (action, symbole, prix, SL, TP).
  3. Exécution : ouvrir un ordre avec gestion des risques (lot size basé sur le risque en % du capital).

Le code complet ci-dessous est commenté et prêt à être compilé dans MetaEditor.

Code complet de l’EA

//+------------------------------------------------------------------+
//|                                          TelegramSignalCopier.mq5 |
//|                                    Copyright 2025, MQL-Experts.com |
//+------------------------------------------------------------------+
#property copyright "MQL-Experts.com"
#property version   "1.00"
#property description "Copie automatique des signaux Telegram"

#include <Trade/Trade.mqh>
#include <Json.mqh> // Inclure la bibliothèque JSON (disponible sur MQL5 Market)

input string   TelegramToken = "";          // Token du bot Telegram
input string   TelegramChatID = "";         // ID du chat/canal
input double   RiskPercent = 1.0;            // Risque en % du capital par trade
input double   FixedLotSize = 0.0;           // Taille de lot fixe (0 = utiliser RiskPercent)
input int      MagicNumber = 202503;         // Magic number de l'EA
input int      UpdateInterval = 2000;        // Intervalle de polling (ms)

CTrade         Trade;
string         LastMessageID = "";

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   Trade.SetExpertMagicNumber(MagicNumber);
   if(TelegramToken == "" || TelegramChatID == "")
     {
      Print("Erreur : Token ou ChatID manquant.");
      return(INIT_PARAMETERS_INCORRECT);
     }
   EventSetMillisecondTimer(UpdateInterval);
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   string messages = GetTelegramMessages();
   if(messages == "") return;
   
   string result[];
   if(JsonParse(messages, result) == false) return;
   
   // Parcourir les messages (simplifié : on prend le dernier)
   string lastMsg = GetLastMessage(messages);
   if(lastMsg == LastMessageID) return;
   LastMessageID = lastMsg;
   
   string signal = ExtractSignal(messages);
   if(signal == "") return;
   
   ProcessSignal(signal);
  }

//+------------------------------------------------------------------+
//| Récupère les messages via WebRequest                             |
//+------------------------------------------------------------------+
string GetTelegramMessages()
  {
   string url = "https://api.telegram.org/bot" + TelegramToken + "/getUpdates";
   char post[];
   char result[];
   string headers;
   
   int res = WebRequest("GET", url, "", 5000, post, result, headers);
   if(res == -1)
     {
      Print("Erreur WebRequest : ", GetLastError());
      return "";
     }
   return CharArrayToString(result);
  }

//+------------------------------------------------------------------+
//| Extrait le dernier message texte                                 |
//+------------------------------------------------------------------+
string ExtractSignal(string json)
  {
   // Regex pour trouver le texte du message
   // Exemple simplifié : on cherche "text":"..."
   int start = StringFind(json, "\"text\":\"");
   if(start == -1) return "";
   start += 8;
   int end = StringFind(json, "\"", start);
   if(end == -1) return "";
   return StringSubstr(json, start, end - start);
  }

//+------------------------------------------------------------------+
//| Parse et exécute le signal                                       |
//+------------------------------------------------------------------+
void ProcessSignal(string signal)
  {
   // Format attendu : BUY EURUSD @ 1.0850 SL 1.0820 TP 1.0900
   string pattern = "(BUY|SELL)\\s+([A-Z]{6})\\s+@\\s+([0-9.]+)\\s+SL\\s+([0-9.]+)\\s+TP\\s+([0-9.]+)";
   string matches[];
   
   if(RegexMatch(signal, pattern, matches) == false)
     {
      Print("Format de signal invalide : ", signal);
      return;
     }
   
   string action = matches[1];
   string symbol = matches[2];
   double price = StringToDouble(matches[3]);
   double sl = StringToDouble(matches[4]);
   double tp = StringToDouble(matches[5]);
   
   // Vérifier que le symbole existe
   if(SymbolSelect(symbol, true) == false)
     {
      Print("Symbole inconnu : ", symbol);
      return;
     }
   
   // Calcul du lot
   double lot = CalculateLotSize(symbol, price, sl, RiskPercent);
   if(lot < SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN))
     {
      Print("Lot trop petit pour ", symbol);
      return;
     }
   
   // Ouvrir l'ordre
   int type = (action == "BUY") ? ORDER_TYPE_BUY : ORDER_TYPE_SELL;
   Trade.PositionOpen(symbol, type, lot, price, sl, tp, "Signal Telegram");
   
   if(Trade.ResultRetcode() != TRADE_RETCODE_DONE)
      Print("Erreur trade : ", Trade.ResultRetcode());
  }

//+------------------------------------------------------------------+
//| Calcule la taille de lot basée sur le risque                     |
//+------------------------------------------------------------------+
double CalculateLotSize(string symbol, double entry, double sl, double riskPercent)
  {
   if(FixedLotSize > 0) return FixedLotSize;
   
   double balance = AccountInfoDouble(ACCOUNT_BALANCE);
   double riskAmount = balance * riskPercent / 100.0;
   double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE);
   double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
   double slPoints = MathAbs(entry - sl) / tickSize;
   double lotStep = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
   
   double lot = riskAmount / (slPoints * tickValue);
   lot = MathFloor(lot / lotStep) * lotStep;
   
   double minLot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
   double maxLot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);
   
   return MathMax(minLot, MathMin(lot, maxLot));
  }
//+------------------------------------------------------------------+

Explication détaillée du code

1. Polling Telegram avec WebRequest

La fonction GetTelegramMessages() envoie une requête GET à l’API Telegram. Le paramètre getUpdates retourne les messages non lus. Pour éviter de traiter plusieurs fois le même message, nous stockons l’ID du dernier message traité dans LastMessageID. Notez que l’API Telegram a une limite de 20 messages par requête ; pour un usage intensif, implémentez un offset.

2. Parsing avec regex

Le pattern regex (BUY|SELL)\s+([A-Z]{6})\s+@\s+([0-9.]+)\s+SL\s+([0-9.]+)\s+TP\s+([0-9.]+) capture :

  • Groupe 1 : action (BUY/SELL)
  • Groupe 2 : symbole (6 caractères, ex : EURUSD)
  • Groupe 3 : prix d’entrée
  • Groupe 4 : stop loss
  • Groupe 5 : take profit

Si le format diffère (ex : EURUSD BUY 1.0850), adaptez le pattern. La fonction RegexMatch nécessite la bibliothèque Regex.mqh incluse dans MQL5 standard.

3. Money management

La fonction CalculateLotSize utilise le risque en pourcentage du capital. Elle calcule la distance en points entre l’entrée et le SL, multiplie par la valeur du tick, et déduit le lot correspondant. Si FixedLotSize est défini, ce calcul est ignoré. Cette approche évite le sur-risque sur des paires volatiles.

Anti-patterns à éviter

Problème Solution
Latence de message : Telegram n’est pas un flux temps réel. Un signal peut arriver avec 1 à 5 secondes de retard. Ne pas utiliser pour du scalping. Préférer des signaux sur timeframe M15 ou plus.
Signaux contradictoires : un même canal peut envoyer BUY puis SELL sur le même symbole en 2 minutes. Ajouter un délai minimum entre deux trades (ex : 5 minutes) via une variable timestamp.
Symbole non trouvé : le signal mentionne XAUUSD mais votre broker utilise GOLD. Implémenter une table de correspondance (mapping) dans les inputs.
Ordres rejetés : prix d’entrée trop éloigné du marché (slippage). Utiliser ORDER_TYPE_BUY_LIMIT ou un décalage max en pips.
Dépendance à une bibliothèque externe : le code ci-dessus utilise Json.mqh. Vous pouvez remplacer par un parsing manuel si vous préférez zéro dépendance.

Test et déploiement

Avant de lancer l’EA sur un compte réel :

  1. Testez sur un compte démo avec un petit lot fixe.
  2. Vérifiez que le bot Telegram a les droits d’envoyer des messages dans le canal (il doit être administrateur).
  3. Surveillez les logs : Print() vous indiquera les messages parsés et les erreurs éventuelles.
  4. Utilisez un VPS pour garantir une connexion 24/7. Nous recommandons Site officiel pour un hébergement stable à bas coût.

Disclaimer sur les signaux payants

La majorité des canaux Telegram de signaux payants sont des arnaques ou des stratégies à espérance mathématique négative. Les signaux gratuits sont souvent des leurres pour vendre des abonnements. Même avec un code parfait, vous ne ferez pas de l’or avec des signaux médiocres. Ce tutoriel est un outil technique, pas une recommandation d’achat. Testez toujours sur démo, et ne risquez jamais plus que ce que vous pouvez perdre.

FAQ

Puis-je utiliser ce code avec MetaTrader 4 ?

Non, ce code est spécifique à MQL5. MT4 utilise MQL4 qui ne supporte pas WebRequest de la même manière, ni les mêmes fonctions de trading. Une adaptation serait nécessaire.

Comment gérer plusieurs canaux Telegram ?

Vous pouvez appeler l’API avec un offset différent pour chaque canal, ou utiliser un seul bot qui écoute plusieurs chats. Dans ce cas, filtrez par chat.id dans le JSON reçu.

Que faire si le signal contient des commentaires ou des emojis ?

Le regex ignore tout ce qui ne correspond pas au pattern. Si le signal est noyé dans du texte, vous pouvez d’abord extraire la partie pertinente avec une expression plus large, ou demander à l’émetteur de standardiser le format.

L’EA plante avec l’erreur 401 (WebRequest) ?

Vérifiez que vous avez bien ajouté https://api.telegram.org dans la liste blanche des URL autorisées (Outils > Options > Expert Advisors). Redémarrez le terminal après modification.

Oui, tant que vous respectez les conditions d’utilisation de Telegram et de votre broker. Attention toutefois aux signaux qui pourraient constituer une manipulation de marché (pump and dump). En cas de doute, consultez un avocat.

Conclusion

Ce tutoriel vous a fourni un EA MQL5 fonctionnel pour copier des signaux Telegram. Le code est une base solide, mais chaque canal a ses spécificités : adaptez le regex, le money management et les contrôles d’erreur à votre contexte. N’oubliez pas que l’automatisation ne remplace pas une stratégie rentable. Si vous cherchez à approfondir, explorez la gestion des ordres en attente ou l’ajout d’un système de scoring des signaux. Bon code et bons trades.

Recevez nos meilleurs conseils

1 email par semaine, désinscription en 1 clic. Pas de spam, jamais.