GlobalVariableSetOnCondition

Met une nouvelle valeur de la variable globale existante si la valeur courante est égal à la valeur du troisième paramètre check_value. Si la variable n'existe pas, la fonction générera l'erreur ERR_GLOBALVARIABLE_NOT_FOUND (4501) et rendra false.

bool  GlobalVariableSetOnCondition(
   string  name,            // nom
   double  value,           // valeur à l'exécution de la condition
   double  check_value      // condition vérifiée
   );

Paramètres

name

[in] Le nom de la variable globale.

value

[in]  Une nouvelle valeur.

check_value

[in]   La valeur pour la vérification de la valeur courante de la variable globale.

La valeur rendue

A l'exécution réussi la fonction rend true, autrement rend false. Pour recevoir l'information sur l'erreur, il est nécessaire d'appeler la fonction GetLastError(). Si la valeur courante de la variable globale se distingue de  check_value, la fonction rendra false.

Note

La fonction assure l'accès atomique à la variable globale, c'est pourquoi elle peut être utilisée pour l'organisation du mutex à la coopération de quelques experts travaillant simultanément dans la limite d'un terminal de client.

 

Exemple :

#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
#property description   "Pour tester le fonctionnement de la fonction GlobalVariableSetOnCondition,"
#property description   "il est nécessaire d'exécuter l'EA sur plusieurs graphiques simultanément."
 
#define   EXP_NAME      StringSubstr(__FILE__0StringLen(__FILE__)-4)   // program name
#define   MUTEX         EXP_NAME+"_MUTEX"                                  // nom de la variable globale mutex
#define   DELAY         5000                                               // nombre de millisecondes d'émulation de l'EA
 
input long  InpExpMagic =  0; /* Expert magic number  */ // Id de l'EA. Si 0, l'id du graphique est utilisé
 
union LongDouble              // union pour écrire et récupérer des valeurs longues à partir de double
  {
   long   lvalue;             // valeur de type long
   double dvalue;             // valeur de type double
  };
  
//--- variables globales de l'EA
long  ExtExpMagic;            // Id de l'EA
ulong ExtStart;               // moment du démarrage des calculs de l'EA
 
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- attribue l'ID du graphique à l'ID de l'EA si une valeur nulle est spécifiée
   ExtExpMagic=(InpExpMagic==0 ? ChartID() : InpExpMagic);
 
//--- crée un mutex, s'il y a une erreur, renvoie une erreur d'initialisation
   if(!MutexCreate())
      return(INIT_FAILED);
      
//--- initialisation réussie
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- si le mutex est capturé par l'EA, relâche le mutex
   if(MutexGetExpertID()==ExtExpMagic)
      MutexRelease();
      
//--- nettoyage
   Comment("");
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//-- crée le mutex s'il n'existe pas. S'il y a une erreur, on passe au tick suivant
   if(!GlobalVariableCheck(MUTEX) && !MutexCreate())
      return;
      
//--- récupère l'ID d'expert défini dans la variable globale du terminal
   long magic=MutexGetExpertID();
 
//--- si l'ID appartient à l'EA, simule son travail
   if(magic==ExtExpMagic)
     {
      //--- si le "travail" EA est terminé, libére le mutex
      if(EAProgressHandler(ExtStart))
         MutexRelease();
      return;
     }
//--- mutex capturé par un autre EA
   else
     {
      //--- si le mutex est déjà relâché
      if(magic==0)
        {
         //--- occupe le mutex et mémorise l'heure d'accès au travail
         if(MutexOccupy())
           {
            PrintFormat("%s: Mutex is occupied by %s",Symbol(), ExpertIDDescription());
            ExtStart=GetTickCount64();
           }
         return;
        }
      //--- mutex toujours occupé par un autre EA - travaux interdits
      else
         return;
     }
   /*
 résultat de l'exécution de deux EA identiques sur les graphiques EURUSD et AUDUSD :
   EURUSDMutex is occupied by Expert 133829812107724569
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 end
   EURUSDMutex is occupied by Expert 133829812107724569
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 end
   AUDUSDMutex is occupied by Expert 128968168951083984
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 end
   AUDUSDMutex is occupied by Expert 128968168951083984
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 end
   EURUSDMutex is occupied by Expert 133829812107724569
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 end
   EURUSDMutex is occupied by Expert 133829812107724569
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 end
   AUDUSDMutex is occupied by Expert 128968168951083984
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 next tick
   AUDUSDExpert 128968168951083984 end
   EURUSDMutex is occupied by Expert 133829812107724569
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 next tick
   EURUSDExpert 133829812107724569 end
   
  nous pouvons voir que le premier EA à occuper le mutex est celui dans lequel le tick est arrivé en premier
  après l'achèvement du cycle de travail, si le tick est revenu en premier ici,
  le même EA occupe à nouveau le mutex
   */
  }
//+------------------------------------------------------------------+
//| Émulateur de gestionnaire d'opérations de l'EA                   |
//+------------------------------------------------------------------+
bool EAProgressHandler(ulong start)
  {
   //--- si l'heure spécifiée s'est écoulée depuis que le handler a commencé à travailler
   if(GetTickCount64()-start>=DELAY)
     {
      //--- rapporte au journal l'achèvement du handler,
      //--- définit une nouvelle heure de début pour le handler et renvoie 'true'
      PrintFormat("%s: %s end"Symbol(), ExpertIDDescription());
      start=GetTickCount64();
      return(true);
     }
   //--- le temps de fonctionnement de l'émulateur de calcul de l'EA n'est pas encore terminé -
   //--- rapporte le prochain tick dans le journal
   else
     {
      PrintFormat("%s: %s next tick"Symbol(), ExpertIDDescription());
     }
//--- le temps de travail n'est pas encore terminé - renvoie 'false'
   return(false);
  }
//+------------------------------------------------------------------+
//| Crée un mutex et le définit sur l'état verrouillé                |
//+------------------------------------------------------------------+
bool MutexCreate(void)
  {
   if(!GlobalVariableCheck(MUTEX))
     {
      LongDouble magic={};
      magic.lvalue=ExtExpMagic;
      ResetLastError();
      if(!GlobalVariableSet(MUTEXmagic.dvalue))
        {
         PrintFormat("%s: GlobalVariableSet() failed. Error %d",__FUNCTION__GetLastError());
         return(false);
        }
     }
   return(true);
  }
//+------------------------------------------------------------------+
//| Capture le mutex                                                |
//+------------------------------------------------------------------+
bool MutexOccupy(void)
  {
   if(!GlobalVariableCheck(MUTEX))
     {
      PrintFormat("%s: Error! Mutex is missing. First create it with MutexCreate()",__FUNCTION__);
      return(false);
     }
   LongDouble magic={};
   magic.lvalue=ExtExpMagic;
s   ResetLastError();
   if(!GlobalVariableSetOnCondition(MUTEXmagic.dvalue0))
     {
      PrintFormat("%s: GlobalVariableSetOnCondition() failed. Error %d",__FUNCTION__GetLastError());
      return(false);
     }
   return(true);
  }
//+------------------------------------------------------------------+
//| Relâche le mutex                                                 |
//+------------------------------------------------------------------+
bool MutexRelease(void)
  {
   if(!GlobalVariableCheck(MUTEX))
     {
      PrintFormat("%s: Error! Mutex is missing. First create it with MutexCreate()",__FUNCTION__);
      return(false);
     }
   LongDouble magic={};
   magic.lvalue=ExtExpMagic;
s   ResetLastError();
   if(!GlobalVariableSetOnCondition(MUTEX0magic.dvalue))
     {
      PrintFormat("%s: GlobalVariableSetOnCondition() failed. Error %d",__FUNCTION__GetLastError());
      return(false);
     }
   return(true);
  }
//+------------------------------------------------------------------+
//| Retourne la valeur du mutex                                      |
//+------------------------------------------------------------------+
long MutexGetExpertID(void)
  {
   LongDouble magic={};
s   ResetLastError();
   if(!GlobalVariableGet(MUTEXmagic.dvalue))
     {
      PrintFormat("%s: GlobalVariableGet() failed. Error %d",__FUNCTION__GetLastError());
      return(WRONG_VALUE);
     }
   return(magic.lvalue);
  }
//+------------------------------------------------------------------+
//| Renvoie l'identifiant de l'EA sous forme de chaîne               |
//+------------------------------------------------------------------+
string ExpertIDDescription(void)
  {
   return("Expert "+(string)ExtExpMagic);
  }