GlobalVariableSetOnCondition

Imposta il nuovo valore della variabile globale esistente se il valore corrente è uguale al terzo parametro check_value. Se non vi è nessuna variabile globale, la funzione genererà un errore ERR_GLOBALVARIABLE_NOT_FOUND (4501) e restituisce false.

bool  GlobalVariableSetOnCondition(
   string  name,            // Nome della variabile globale
   double  value,           // Nuovo valore per la variabile se la condizione è true
   double  check_value      // Condizione di controllo valore
   );

Parametri

name

[in] Il nome di una variabile globale.

valore

[in]  New value.

check_value

[in] Il valore per controllare il valore corrente della variabile globale.

Valore restituito

In caso di successo, la funzione restituisce true, altrimenti restituisce false. Per i dettagli sull'errore chiamare GetLastError(). Se il valore corrente della variabile globale è diverso da check_value, la funzione restituisce false.

Nota

La funzione fornisce l'accesso atomico per la variabile globale, in modo che possa essere utilizzata per fornire un mutex all' interazione dei diversi Expert Advisors che lavorano simultaneamente all'interno del terminale client.

 

Esempio:

#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
#property description   "Per testare la funzionalità della funzione GlobalVariableSetOnCondition,"
#property description   "è necessario eseguire l'EA su più grafici contemporaneamente."
 
#define   EXP_NAME      StringSubstr(__FILE__0StringLen(__FILE__)-4)   // program name
#define   MUTEX         EXP_NAME+"_MUTEX"                                  // nome della variabile globale mutex
#define   DELAY         5000                                               // numero di millisecondi di emulazione EA
 
input long  InpExpMagic =  0; /* Expert magic number  */ // ID dell'EA. Se 0, viene utilizzato l'ID del grafico
 
union LongDouble              // unione per scrivere e recuperare valori long da double
  {
   long   lvalue;             // valore long
   double dvalue;             // valore double
  };
  
//--- Variabili globali dell'EA
long  ExtExpMagic;            // ID dell'EA
ulong ExtStart;               // momento in cui iniziano i "calcoli" dell'EA
 
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- assegnare l'ID del grafico all'ID dell'EA se viene specificato un valore zero
   ExtExpMagic=(InpExpMagic==0 ? ChartID() : InpExpMagic);
 
//--- creare mutex, se c'è un errore, restituire un errore di inizializzazione
   if(!MutexCreate())
      return(INIT_FAILED);
      
//--- inizializzazione avvenuta con successo
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- se mutex viene catturato dall'EA, rilasciare mutex
   if(MutexGetExpertID()==ExtExpMagic)
      MutexRelease();
      
//--- ripulire
   Comment("");
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- se non c'è mutex, crearlo; se c'è un errore, lasciare fino al tick successivo
   if(!GlobalVariableCheck(MUTEX) && !MutexCreate())
      return;
      
//--- ottenere l'ID dell'expert impostato nella variabile globale del terminale
   long magic=MutexGetExpertID();
 
//--- se l'ID appartiene all'EA, simula il suo lavoro
   if(magic==ExtExpMagic)
     {
      //--- se il "lavoro" dell'EA è completato, rilasciare mutex
      if(EAProgressHandler(ExtStart))
         MutexRelease();
      return;
     }
//--- mutex catturato da un altro EA
   else
     {
      //--- se mutex è già stato rilasciato
      if(magic==0)
        {
         //--- occupa mutex e ricorda l'ora di accesso al lavoro
         if(MutexOccupy())
           {
            PrintFormat("%s: Mutex is occupied by %s",Symbol(), ExpertIDDescription());
            ExtStart=GetTickCount64();
           }
         return;
        }
      //--- mutex ancora occupato da un altro EA - il lavoro è vietato
      else
         return;
     }
   /*
   risultato dell'esecuzione di due EA identici sui grafici EURUSD e 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
   
   possiamo vedere che il primo EA ad occupare il mutex è quello in cui il tick è arrivato per primo
   dopo il completamento del ciclo di lavoro, se il tick torna prima qui,
   lo stesso EA occupa di nuovo il mutex
   */
  }
//+------------------------------------------------------------------+
//| Emulatore del gestore delle operazioni dell'EA                   |
//+------------------------------------------------------------------+
bool EAProgressHandler(ulong start)
  {
   //--- se è trascorso il tempo specificato da quando il gestore ha iniziato a funzionare
   if(GetTickCount64()-start>=DELAY)
     {
      //--- riportare nel journal in merito al completamento del gestore,
      //--- impostare un nuovo orario di inizio per il gestore e restituire 'true
      PrintFormat("%s: %s end"Symbol(), ExpertIDDescription());
      start=GetTickCount64();
      return(true);
     }
   //--- il tempo di funzionamento dell'emulatore di calcolo dell'EA non è stato ancora completato -
   //--- riportare il prossimo tick nel journal
   else
     {
      PrintFormat("%s: %s next tick"Symbol(), ExpertIDDescription());
     }
//--- l'orario di lavoro non è ancora terminato - restituisci 'false'
   return(false);
  }
//+------------------------------------------------------------------+
//| Creare mutex, impostarlo sullo stato bloccato                    |
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+
//| Catturare 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;
   ResetLastError();
   if(!GlobalVariableSetOnCondition(MUTEXmagic.dvalue0))
     {
      PrintFormat("%s: GlobalVariableSetOnCondition() failed. Error %d",__FUNCTION__GetLastError());
      return(false);
     }
   return(true);
  }
//+------------------------------------------------------------------+
//| Rilasciare 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;
   ResetLastError();
   if(!GlobalVariableSetOnCondition(MUTEX0magic.dvalue))
     {
      PrintFormat("%s: GlobalVariableSetOnCondition() failed. Error %d",__FUNCTION__GetLastError());
      return(false);
     }
   return(true);
  }
//+------------------------------------------------------------------+
//| Restituire il valore di mutex                                    |
//+------------------------------------------------------------------+
long MutexGetExpertID(void)
  {
   LongDouble magic={};
   ResetLastError();
   if(!GlobalVariableGet(MUTEXmagic.dvalue))
     {
      PrintFormat("%s: GlobalVariableGet() failed. Error %d",__FUNCTION__GetLastError());
      return(WRONG_VALUE);
     }
   return(magic.lvalue);
  }
//+------------------------------------------------------------------+
//| Restituire ID dell'EA come stringa                               |
//+------------------------------------------------------------------+
string ExpertIDDescription(void)
  {
   return("Expert "+(string)ExtExpMagic);
  }