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**0StringLen(**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:
   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
   
  é 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(MUTEXmagic.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(MUTEXmagic.dvalue0))
     {
      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(MUTEX0magic.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(MUTEXmagic.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);
  }