GlobalVariableSetOnCondition

Устанавливает новое значение существующей глобальной переменной, если текущее значение переменной равно значению третьего параметра check_value. Если переменной не существует, функция сгенерирует ошибку ERR_GLOBALVARIABLE_NOT_FOUND (4501) и вернет false.

bool  GlobalVariableSetOnCondition(
   string  name,            // имя
   double  value,           // значение при выполнении условия
   double  check_value      // проверяемое условие
   );

Параметры

name

[in]  Имя глобальной переменной.

value

[in]  Новое значение.

check_value

[in]   Значение для проверки текущего значения глобальной переменной.

Возвращаемое значение

При успешном выполнении функция возвращает true, иначе false. Для получения информации об ошибке необходимо вызвать функцию GetLastError(). Если текущее значение глобальной переменной отличается от check_value, функция вернет false.

Примечание

Функция обеспечивает атомарный доступ к глобальной переменной, поэтому она может быть использована для организации мьютекса при взаимодействии нескольких одновременно работающих экспертов в пределах одного клиентского терминала.

Пример:

#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
#property description   "Для проверки работоспособности функции GlobalVariableSetOnCondition"
#property description   "необходимо запустить данного эксперта на нескольких графиках одновременно."
 
#define   EXP_NAME      StringSubstr(__FILE__0StringLen(__FILE__)-4)   // имя программы
#define   MUTEX         EXP_NAME+"_MUTEX"                                  // имя глобальной переменной мьютекса
#define   DELAY         5000                                               // количество миллисекунд эмуляции работы эксперта
 
input long  InpExpMagic =  0; /* Expert magic number  */ // идентификатор эксперта. При значении 0 используется идентификатор графика
 
union LongDouble              // объединение для записи и получения long-значений из double
  {
   long   lvalue;             // long value
   double dvalue;             // double value
  };
  
//--- глобальные переменные советника
long  ExtExpMagic;            // идентификатор эксперта
ulong ExtStart;               // момент старта "расчётов" советника
 
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- присваиваем идентификатору эксперта идентификатор графика в случае, если задано нулевое значение
   ExtExpMagic=(InpExpMagic==0 ? ChartID() : InpExpMagic);
 
//--- создаём мьютекс, при ошибке возвращаем ошибку инициализации
   if(!MutexCreate())
      return(INIT_FAILED);
      
//--- успешная инициализация
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- если мьютекс захвачен этим советником - освобождаем мьютекс
   if(MutexGetExpertID()==ExtExpMagic)
      MutexRelease();
      
//--- почистим за собой
   Comment("");
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- если мьютекса нет - создаём, при ошибке - уходим до следующего тика
   if(!GlobalVariableCheck(MUTEX) && !MutexCreate())
      return;
      
//--- получаем идентификатор эксперта, записанный в глобальной переменной терминала
   long magic=MutexGetExpertID();
 
//--- если идентификатор принадлежит этому эксперту - имитируем его работу
   if(magic==ExtExpMagic)
     {
      //--- если "работа" эксперта завершена - освобождаем мьютекс
      if(EAProgressHandler(ExtStart))
         MutexRelease();
      return;
     }
//--- мьютекс захвачен другим советником
   else
     {
      //--- если мьютекс уже освобождён
      if(magic==0)
        {
         //--- занимаем мьютекс и запоминаем время доступа к работе
         if(MutexOccupy())
           {
            PrintFormat("%s: Mutex is occupied by %s",Symbol(), ExpertIDDescription());
            ExtStart=GetTickCount64();
           }
         return;
        }
      //--- мьютекс всё ещё занят другим советником - работать запрещено
      else
         return;
     }
   /*
   результат запуска двух одинаковых советников на графиках EURUSD и 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
   
   видно, что первым мьютекс занимает советник, где тик пришёл первым
   после завершения цикла работы, если опять тик пришёл первым здесь же,
   опять этот же советник занимает мьютекс
   */
  }
//+------------------------------------------------------------------+
//| Обработчик-эмулятор работы советника                             |
//+------------------------------------------------------------------+
bool EAProgressHandler(ulong start)
  {
   //--- если с момента начала работы обработчика прошло заданное время
   if(GetTickCount64()-start>=DELAY)
     {
      //--- сообщаем в журнал об окончании работы обработчика,
      //--- устанавливаем новое время начала работы обработчика и возвращаем true
      PrintFormat("%s: %s end"Symbol(), ExpertIDDescription());
      start=GetTickCount64();
      return(true);
     }
   //--- время работы эмулятора расчётов советника ещё не завершено -
   //--- сообщаем в журнале об очередном тике
   else
     {
      PrintFormat("%s: %s next tick"Symbol(), ExpertIDDescription());
     }
//--- время работы ещё не завершилось - возвращаем false
   return(false);
  }
//+------------------------------------------------------------------+
//| Создаёт мьютекс, устанавливает в заблокированное состояние       |
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+
//| Захватывает мьютекс                                              |
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+
//| Освобождает мьютекс                                              |
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+
//| Возвращает значение мьютекса                                     |
//+------------------------------------------------------------------+
long MutexGetExpertID(void)
  {
   LongDouble magic={};
   ResetLastError();
   if(!GlobalVariableGet(MUTEXmagic.dvalue))
     {
      PrintFormat("%s: GlobalVariableGet() failed. Error %d",__FUNCTION__GetLastError());
      return(WRONG_VALUE);
     }
   return(magic.lvalue);
  }
//+------------------------------------------------------------------+
//| Возвращает в виде строки идентификатор советника                 |
//+------------------------------------------------------------------+
string ExpertIDDescription(void)
  {
   return("Expert "+(string)ExtExpMagic);
  }