Variables globales MQL5 : partager des données entre plusieurs EAs
Découvrez comment synchroniser vos Experts Advisors en utilisant les variables globales MQL5. Une méthode robuste pour partager des données en temps réel entre plusieurs EAs sur le même compte MetaTrader 5.
1. Introduction : pourquoi partager des données entre EAs en MQL5 ?
Lorsque vous développez un système de trading automatisé complexe, il arrive souvent que plusieurs Experts Advisors (EAs) doivent collaborer sur un même compte MetaTrader 5. Par exemple, vous pourriez avoir un EA principal qui analyse le marché et envoie des signaux à des sous-EAs responsables de l’exécution des ordres sur différents instruments. Sans un mécanisme de partage de données, chaque EA fonctionnerait en silo, ignorant les actions des autres, ce qui peut entraîner des conflits de positions, des doublons de trades ou une gestion désynchronisée des risques.
Les variables globales MQL5 offrent une solution élégante et performante pour résoudre ce problème. Elles permettent de stocker des valeurs dans la mémoire partagée du terminal MetaTrader 5, accessibles par n’importe quel EA, script ou indicateur s’exécutant sur le même compte. Contrairement aux fichiers ou aux bases de données, les variables globales sont instantanées et ne nécessitent pas de lecture/écriture disque, garantissant une latence minimale. Dans cet article, nous allons explorer en profondeur comment maîtriser les variables globales MQL5 partager données entre plusieurs EAs, avec des exemples concrets et des bonnes pratiques.
2. Comprendre les variables globales MQL5 : définition et portée
Les variables globales MQL5 sont des paires clé-valeur stockées dans la mémoire du terminal MetaTrader 5. Elles sont persistantes tant que le terminal est ouvert et peuvent être lues et écrites par n’importe quel programme MQL5 (EA, script, indicateur) s’exécutant sur le même compte de trading. Leur portée est donc globale au niveau du terminal, mais limitée au compte courant.
Voici les principales caractéristiques :
- Persistance : Elles survivent à la fermeture d’un EA, mais sont effacées lorsque le terminal MetaTrader 5 est fermé.
- Accès concurrent : Plusieurs EAs peuvent lire et écrire simultanément, mais il faut gérer les collisions potentielles.
- Types supportés : Uniquement des valeurs numériques (double, int, datetime, color). Les chaînes de caractères ne sont pas directement supportées, mais peuvent être encodées via des fonctions de conversion.
- Nombre maximum : MetaTrader 5 autorise jusqu’à 1024 variables globales par compte.
Pour travailler avec ces variables, MQL5 fournit un ensemble de fonctions dédiées : GlobalVariableSet(), GlobalVariableGet(), GlobalVariableDel(), GlobalVariableCheck(), GlobalVariableName() et GlobalVariablesTotal(). Ces fonctions sont la clé pour implémenter un partage de données efficace.
3. Étape 1 : Écrire et lire des variables globales entre EAs
Le mécanisme de base pour partager des données repose sur deux actions : écrire une valeur dans une variable globale depuis un EA, et la lire depuis un autre EA. Prenons un exemple concret : un EA principal (Master EA) calcule un indicateur personnalisé et souhaite transmettre sa valeur à un EA esclave (Slave EA) qui exécutera un trade.
Exemple de code dans le Master EA (écriture) :
//+------------------------------------------------------------------+
//| Master EA : écriture d'une variable globale |
//+------------------------------------------------------------------+
void OnTick()
{
double customIndicatorValue = iCustom(_Symbol, PERIOD_CURRENT, "MyIndicator", 0, 0);
string varName = "MasterSignal_" + _Symbol; // Nom unique pour éviter les conflits
if(GlobalVariableSet(varName, customIndicatorValue))
{
Print("Valeur écrite : ", customIndicatorValue);
}
else
{
Print("Erreur d'écriture : ", GetLastError());
}
}
Exemple de code dans le Slave EA (lecture) :
//+------------------------------------------------------------------+
//| Slave EA : lecture de la variable globale |
//+------------------------------------------------------------------+
void OnTick()
{
string varName = "MasterSignal_" + _Symbol;
if(GlobalVariableCheck(varName))
{
double value = GlobalVariableGet(varName);
Print("Valeur lue depuis Master : ", value);
// Logique de trading basée sur cette valeur
}
else
{
Print("Variable non trouvée");
}
}
Ce schéma simple illustre le principe fondamental : l’EA maître écrit une variable avec un nom unique (incluant le symbole pour éviter les collisions), et l’EA esclave la lit à chaque tick. Cependant, dans un environnement multi-EA, il est crucial d’utiliser des noms de variables cohérents et bien structurés, par exemple en incluant le symbole, le timeframe et un identifiant d’EA.
4. Étape 2 : Synchronisation et gestion des conflits
Lorsque plusieurs EAs écrivent et lisent simultanément sur les mêmes variables globales, des conflits peuvent survenir. Par exemple, deux EAs pourraient écraser mutuellement leurs données, ou lire une valeur qui n’est plus à jour. Pour éviter cela, il faut implémenter des mécanismes de synchronisation.
Stratégie de nommage unique : La première ligne de défense est d’utiliser des noms de variables très spécifiques. Par exemple : "EA_TradeSignal_" + Symbol() + "_" + TimeframeToString(Period()). Cela garantit que chaque EA a son propre espace de noms.
Utilisation de verrous (locks) : MQL5 ne fournit pas de mutex natifs, mais on peut simuler un verrou en utilisant une variable globale dédiée. L’idée est de créer une variable “lock” que chaque EA doit acquérir avant d’écrire ou de lire une donnée critique.
//+------------------------------------------------------------------+
//| Fonction de verrouillage simple |
//+------------------------------------------------------------------+
bool AcquireLock(string lockName, int timeout=100)
{
datetime startTime = TimeCurrent();
while(GlobalVariableSet(lockName, 1.0) == false)
{
if(TimeCurrent() - startTime > timeout)
{
Print("Timeout sur le verrou : ", lockName);
return false;
}
Sleep(10); // Attendre avant de réessayer
}
return true;
}
void ReleaseLock(string lockName)
{
GlobalVariableDel(lockName);
}
Gestion des timeouts : Si un EA plante ou met trop de temps à libérer un verrou, les autres EAs peuvent rester bloqués. Il est donc essentiel d’implémenter un timeout (comme dans l’exemple ci-dessus) et de gérer les cas d’échec. Une alternative plus robuste consiste à utiliser des horodatages dans les variables globales pour détecter les données obsolètes.
5. Étape 3 : Cas d’usage avancés et bonnes pratiques
Au-delà du simple partage de signaux, les variables globales MQL5 permettent des architectures de trading sophistiquées. Voici quelques cas d’usage avancés :
- Gestion centralisée des risques : Un EA Risk Manager surveille l’exposition globale du compte. Chaque EA de trading écrit sa position courante (volume, symbole, sens) dans des variables globales. Le Risk Manager lit ces données et peut émettre des ordres de réduction si l’exposition dépasse un seuil.
- Coordination de plusieurs stratégies : Vous pouvez avoir un EA qui analyse le sentiment de marché (via des indicateurs) et écrit un score global. D’autres EAs lisent ce score et adaptent leurs paramètres (filtrage des signaux, taille des lots).
- File d’attente d’ordres : Un EA ordonnanceur gère une file d’attente de trades. Chaque EA de trading écrit une demande dans une variable globale avec un timestamp. L’ordonnanceur lit ces demandes, les traite une par une, et met à jour le statut.
Bonnes pratiques à retenir :
- Utilisez des noms de variables explicites et structurés (ex: “EA_MyEA_Signal_BTCUSD_M5”).
- Nettoyez les variables globales qui ne sont plus nécessaires avec
GlobalVariableDel()pour éviter de saturer la limite de 1024. - Ajoutez des mécanismes de heartbeat : chaque EA peut écrire son timestamp de dernière activité. Si un EA ne met pas à jour son heartbeat pendant un certain temps, les autres peuvent considérer qu’il est inactif.
- Testez votre système en environnement démo avec plusieurs EAs simultanés pour valider la synchronisation.
StringToInteger() pour convertir une chaîne en entier, et IntegerToString() pour la reconvertir. Attention toutefois à la perte de données si la chaîne est trop longue. Une autre méthode consiste à concaténer des variables globales numériques pour représenter les caractères ASCII, mais cela reste complexe. Privilégiez les solutions basées sur des fichiers CSV ou une base de données légère si vous devez échanger des données textuelles complexes.
6. Étape 4 : Dépannage et débogage des variables globales
Même avec une bonne conception, des problèmes peuvent survenir. Voici les erreurs les plus fréquentes et comment les résoudre :
- Erreur 5000 (ERR_GLOBAL_VARIABLE_NOT_FOUND) : La variable que vous essayez de lire n’existe pas. Vérifiez le nom exact et assurez-vous que l’EA qui écrit a bien été exécuté. Utilisez
GlobalVariableCheck()avant de lire. - Erreur 5001 (ERR_GLOBAL_VARIABLE_EXISTS) : Vous essayez de créer une variable qui existe déjà. Si vous souhaitez la mettre à jour, utilisez simplement
GlobalVariableSet()(qui écrase). Pour une création conditionnelle, vérifiez d’abord avecGlobalVariableCheck(). - Erreur 5002 (ERR_GLOBAL_VARIABLE_LIMIT) : Vous avez atteint la limite de 1024 variables globales. Utilisez
GlobalVariablesTotal()pour surveiller le nombre de variables, et supprimez régulièrement celles qui ne sont plus utiles. - Conflits de noms : Deux EAs différents peuvent accidentellement utiliser le même nom de variable. Adoptez une convention de nommage stricte (ex: “Auteur_NomEA_TypeDonnee_Symbole”).
Pour déboguer efficacement, vous pouvez utiliser le MetaEditor et afficher toutes les variables globales avec un script dédié :
//+------------------------------------------------------------------+
//| Script : Afficher toutes les variables globales |
//+------------------------------------------------------------------+
void OnStart()
{
int total = GlobalVariablesTotal();
Print("Nombre de variables globales : ", total);
for(int i = 0; i < total; i++)
{
string name = GlobalVariableName(i);
double value = GlobalVariableGet(name);
Print("Variable ", i, " : ", name, " = ", value);
}
}
Ce script est très utile pendant la phase de développement pour visualiser l’état de toutes les variables globales en temps réel.
Besoin d’un EA sur-mesure ? Demander un devis gratuit
Questions fréquentes
Quelle est la différence entre les variables globales MQL5 et les variables globales MQL4 ?
En MQL4, les variables globales sont également disponibles mais avec des limitations : le nombre maximum est de 64 (contre 1024 en MQL5), et les fonctions sont légèrement différentes (GlobalVariableSet() existe dans les deux, mais MQL5 offre des fonctions supplémentaires comme GlobalVariableCheck() et GlobalVariableName()). De plus, MQL5 gère mieux la concurrence d’accès grâce à son système de threading plus robuste. Si vous migrez de MQL4 vers MQL5, vous devrez adapter vos noms de variables et revoir votre logique de synchronisation pour profiter des capacités étendues de MQL5.
Les variables globales MQL5 survivent-elles à un redémarrage du terminal MetaTrader 5 ?
Non, les variables globales MQL5 sont stockées dans la mémoire vive (RAM) du terminal MetaTrader 5. Elles sont automatiquement effacées lorsque le terminal est fermé ou redémarré. Si vous avez besoin de persistance entre les sessions, vous devez sauvegarder vos données dans un fichier (par exemple au format CSV ou INI) ou dans une base de données. Vous pouvez utiliser les fonctions de gestion de fichiers MQL5 comme FileOpen(), FileWrite() et FileRead() pour cela. Une autre option est d’utiliser le stockage cloud via une API REST, mais cela nécessite des compétences en programmation réseau.
Puis-je partager des structures de données complexes (tableaux, matrices) via les variables globales MQL5 ?
Les variables globales MQL5 ne supportent que les types numériques simples (double, int, datetime, color). Pour partager des structures complexes comme des tableaux, vous devez les sérialiser. Une méthode courante consiste à convertir chaque élément du tableau en une variable globale distincte, en utilisant un nom de variable qui inclut un index (ex: “MyArray_0”, “MyArray_1”, etc.). Vous pouvez également coder les valeurs dans une seule variable en utilisant des opérations mathématiques (par exemple, combiner deux entiers en un seul double via des multiplications et divisions). Pour des données très volumineuses, il est préférable d’utiliser des fichiers partagés ou une base de données SQLite via des appels système.