GlobalVariableSetOnCondition

Define o novo valor da variável global existente, se o valor da corrente é igual ao terceiro parâmetro check_value. Se não houver nenhuma variável global, a função irá gerar um erro ERR_GLOBALVARIABLE_NOT_FOUND (4501) e voltar false.

bool  GlobalVariableSetOnCondition(
   string  name,            // Nome da variável global
   double  value,           // Novo valor para a variável, se a condição for verdadeira
   double  check_value      // Verifique condição de valor
   );

Parâmetros

name

[in]  O nome de uma variável global.

value

[in]  Novo valor.

check_value

[in]   O valor para verificar o valor atual da variável global.

Valor do Retorno

Se bem sucedida, a função retorna true, caso contrário ela retorna false. Para obter detalhes sobre o erro chamar GetLastError(). Se o valor atual da variável global é diferente de check_value, a função retorna false.

Observação

Função fornece acesso atômico a variável global, para que ele possa ser utilizado para a prestação de uma exclusão mútua na interação de vários consultores especializados trabalhando simultaneamente dentro de um terminal de cliente.

 

Exemplo:

#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
#property description "Para verificar a operabilidade da função GlobalVariableSetOnCondition"
#property description "é necessário executar este EA em vários gráficos simultaneamente."
 
#define EXP_NAME StringSubstr(**FILE**, 0, StringLen(**FILE**)-4) // nome do programa
#define MUTEX EXP_NAME+"_MUTEX" // nome da variável global do mutex
#define DELAY 5000 // quantidade de milissegundos de emulação do trabalho do EA
 
input long InpExpMagic = 0; /* Expert magic number */ // identificador do EA. Se o valor for 0, é usado o identificador do gráfico
 
union LongDouble // união para gravar e obter valores long a partir de double
  {
   long   lvalue;             // long value
   double dvalue;             // double value
  };
  
//--- variáveis globais do EA
long ExtExpMagic; // identificador do EA
ulong ExtStart; // momento de início dos "cálculos" do EA
 
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- atribuímos ao identificador do EA o identificador do gráfico caso um valor zero tenha sido definido
   ExtExpMagic=(InpExpMagic==0 ? ChartID() : InpExpMagic);
 
//--- criamos um mutex, em caso de erro retornamos erro de inicialização
   if(!MutexCreate())
      return(INIT_FAILED);
      
//--- inicialização bem-sucedida
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- se o mutex estiver capturado por este EA - liberamos o mutex
   if(MutexGetExpertID()==ExtExpMagic)
      MutexRelease();
      
//--- limpamos o que for preciso
   Comment("");
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- se não houver mutex, criamos; em caso de erro, saímos até o próximo tick
   if(!GlobalVariableCheck(MUTEX) && !MutexCreate())
      return;
      
//--- obtemos o identificador do EA gravado na variável global do terminal
   long magic=MutexGetExpertID();
 
//--- se o identificador pertence a este EA, imitamos seu trabalho
   if(magic==ExtExpMagic)
     {
 //--- se o "trabalho" do EA foi concluído, liberamos o mutex
      if(EAProgressHandler(ExtStart))
         MutexRelease();
      return;
     }
//--- o mutex está capturado por outro EA
   else
     {
 //--- se o mutex já foi liberado
      if(magic==0)
        {
 //--- ocupamos o mutex e registramos o horário de acesso ao trabalho
         if(MutexOccupy())
           {
            PrintFormat("%s: Mutex is occupied by %s",Symbol(), ExpertIDDescription());
            ExtStart=GetTickCount64();
           }
         return;
        }
 //--- o mutex ainda está ocupado por outro EA - trabalhar é proibido
      else
         return;
     }
   /*
   resultado da execução de dois EAs idênticos nos gráficos EURUSD e AUDUSD:
   EURUSD: Mutex is occupied by Expert 133829812107724569
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 end
   EURUSD: Mutex is occupied by Expert 133829812107724569
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 end
   AUDUSD: Mutex is occupied by Expert 128968168951083984
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 end
   AUDUSD: Mutex is occupied by Expert 128968168951083984
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 end
   EURUSD: Mutex is occupied by Expert 133829812107724569
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 end
   EURUSD: Mutex is occupied by Expert 133829812107724569
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 end
   AUDUSD: Mutex is occupied by Expert 128968168951083984
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 next tick
   AUDUSD: Expert 128968168951083984 end
   EURUSD: Mutex is occupied by Expert 133829812107724569
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 next tick
   EURUSD: Expert 133829812107724569 end
   
  é visível que o primeiro a ocupar o mutex é o EA onde o tick chegou primeiro
  após a conclusão do ciclo de trabalho, se novamente o tick chegou primeiro aqui,
  novamente esse mesmo EA ocupa o mutex
   */
  }
//+------------------------------------------------------------------+
//| Manipulador-emulador do trabalho do EA                           |
//+------------------------------------------------------------------+
bool EAProgressHandler(ulong start)
  {
 //--- se desde o início do trabalho do manipulador passou o tempo determinado
   if(GetTickCount64()-start>=DELAY)
     {
 //--- informamos no diário o término do trabalho do manipulador,
 //--- definimos um novo horário de início do trabalho do manipulador e retornamos true
      PrintFormat("%s: %s end", Symbol(), ExpertIDDescription());
      start=GetTickCount64();
      return(true);
     }
 //--- o tempo de trabalho do emulador de cálculos do EA ainda não terminou -
 //--- informamos no diário sobre o próximo tick
   else
     {
      PrintFormat("%s: %s next tick", Symbol(), ExpertIDDescription());
     }
//--- o tempo de trabalho ainda não terminou, retornamos false
   return(false);
  }
//+------------------------------------------------------------------+
//| Cria um mutex, define-o para o estado bloqueado                  |
//+------------------------------------------------------------------+
bool MutexCreate(void)
  {
   if(!GlobalVariableCheck(MUTEX))
     {
      LongDouble magic={};
      magic.lvalue=ExtExpMagic;
      ResetLastError();
      if(!GlobalVariableSet(MUTEX, magic.dvalue))
        {
         PrintFormat("%s: GlobalVariableSet() failed. Error %d",__FUNCTION__, GetLastError());
         return(false);
        }
     }
   return(true);
  }
//+------------------------------------------------------------------+
//| Captura o 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(MUTEX, magic.dvalue, 0))
     {
      PrintFormat("%s: GlobalVariableSetOnCondition() failed. Error %d",__FUNCTION__, GetLastError());
      return(false);
     }
   return(true);
  }
//+------------------------------------------------------------------+
//| Libera o 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(MUTEX, 0, magic.dvalue))
     {
      PrintFormat("%s: GlobalVariableSetOnCondition() failed. Error %d",__FUNCTION__, GetLastError());
      return(false);
     }
   return(true);
  }
//+------------------------------------------------------------------+
//| Retorna o valor do mutex                                         |
//+------------------------------------------------------------------+
long MutexGetExpertID(void)
  {
   LongDouble magic={};
   ResetLastError();
   if(!GlobalVariableGet(MUTEX, magic.dvalue))
     {
      PrintFormat("%s: GlobalVariableGet() failed. Error %d",__FUNCTION__, GetLastError());
      return(WRONG_VALUE);
     }
   return(magic.lvalue);
  }
//+------------------------------------------------------------------+
//| Retorna como string o identificador do EA                        |
//+------------------------------------------------------------------+
string ExpertIDDescription(void)
  {
   return("Expert "+(string)ExtExpMagic);
  }