home

GlobalVariableCheck(): проверка существования глобальной переменной

Для человека, имеющего уже опыт написания экспертов, выражение «глобальные переменные» может внести небольшую путанницу. Дело в том, что на самом деле существует два вида «глобальных переменных»:

  • переменные, которые видны из любой функции ОДНОГО эксперта (т.е. являются глобальными в пределах этого эксперта); и
  • переменные, которые являются общими для ВСЕХ экспертов.

О глобальных переменных первого типа — тех, которые являются общими для всех функций ОДНОГО эксперта, — я рассказывал ранее, в выпуске «Глобальные переменные».

Сейчас же речь пойдет именно о глобальных переменных второго типа — общих для ВСЕХ экспертов.

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

Для работы с глобальными переменными используются следующие функции:

  • GlobalVariableCheck()
  • GlobalVariableDel()
  • GlobalVariableGet()
  • GlobalVariableName()
  • GlobalVariableSet()
  • GlobalVariableSetOnCondition()
  • GlobalVariablesDeleteAll()
  • GlobalVariablesTotal()

Вначале я хотел бы рассказать о функции GlobalVariableCheck().

 

 bool GlobalVariableCheck(string name)


 

Эта функция возвращает true, если глобальная переменная с именем name существует, и false, если такой переменной нет.

В нашей функции WaitBeforeTransaction() мы храним время и дату совершения последней торговой операции в глобальной переменной «LastTradeTime».

Перед тем, как узнать время последней операции, прочитав значение этой переменной, мы проверяем, существует ли она вообще:

 

 // если глобальная переменная LastTradeTime не существует,
// то создать ее
if (!GlobalVariableCheck("LastTradeTime"))
{
... создаем переменную ...
}


 

Проверять существование глобальной переменной и создавать ее в случае отсутствия можно в двух местах: при инициализации эксперта — в функции init() — или на каждом тике — в функции start().

Несмотря на то, что на первый взгляд напрашивается осуществлять эти действия в функции init(), я бы советовал Вам делать это все-таки в функции start(). Дело в том, что если пользователь при работающем эксперте удалит глобальную переменную, а проверка на ее существование делается только при инициализации эксперта, то дальнейшее поведение такого советника сложно спрогнозировать. Скорее всего, такой советник просто перестанет торговать и начнет выдавать ошибки при обращении к удаленной глобальной переменной.

GlobalVariableSet() — установка нового значения глобальной переменной

Предположим, что ее не существует или же нам надо изменить ее значение. В этом случае надо использовать функцию GlobalVariableSet().

 

 datetime GlobalVariableSet(string name, double value)


 

Функция GlobalVariableSet() устанавливает новое значение value глобальной переменной с именем name и в случае успеха возвращает время последнего доступа к глобальной переменной. Если произошла какая-то ошибка, то функция возвращает 0. Код ошибки, как обычно, можно получить с помощью функции GetLastError().

Если глобальная переменная с именем name отсутствовала, то она создается и она принимает значение value.

Пример использования функции GlobalVariableSet() можно найти в написанной нами функции WaitBeforeTransaction():

 

 // если глобальная переменная LastTradeTime не существует,
// то создать ее
if (!GlobalVariableCheck("LastTradeTime"))
{
// Если произошла какя-то ошибка при вызове функции
// GlobalVariableCheck(), выйдем с ошибкой
if (GetLastError()!=0)
{
Print("WaitBeforeTransaction(): ошибка ",GetLastError(),
" при проверке глобальной переменной LastTradeTime");
return(-1);
}

// глобальная переменная не существует, создадим ее
if (GlobalVariableSet("LastTradeTime", 1)==0)
{
// произошла ошибка при создании глобальной переменной
Print("WaitBeforeTransaction(): ошибка ",GetLastError(),
" при создании глобальной переменной LastTradeTime");
return(-1);
}

// глобальная переменная успешно создана
Print("WaitBeforeTransaction(): глобальная переменная ",
"LastTradeTime создана");
}



 

GlobalVariableSetOnCondition() — установка нового значения глобальной переменной, если текущее ее значение равно заданному значению

К счастью, создатели языка MetaQuotes Language 4 являются профессиональными программистами и заранее могут предугадать, что может понадобиться трейдеру при написании экспертов. Я им очень благодарен, что они включили в список функций языка MetaQuotes Language 4 функцию GlobalVariableSetOnCondition().

Давайте же рассмотрим, чем так полезна эта функция.

 

 bool GlobalVariableSetOnCondition(string name, double value, 
double check_value)


 

Прежде всего эта функция проверяет, существует ли глобальная переменная с именем name. В документации по MetaQuotes Language 4 написано, что если такой глобальной переменной нет, то функция возвращает false и генерит ошибку ERR_GLOBAL_VARIABLE_NOT_FOUND (4058), которую можно получить с помощью функции GetLastError().

Однако при экспериментах с функцией GlobalVariableSetOnCondition() мне не удалось добиться того, чтобы функция вернула ошибку ERR_GLOBAL_VARIABLE_NOT_FOUND (4058). Почему-то даже в случае отсутствия глобальной переменной функция возвращает false и код ошибки ERR_NO_ERROR (т.е. 0). Вот кусок кода, который я использовал для этой цели:

 

 string name = "MyGlobalVariable";
double value = 1;
double check_value = 2;

if (GlobalVariableSetOnCondition(name, value, check_value))
{
Print("Глобальная переменная ", name, " существует.",
" Ее значение изменено с ", check_value, " на ", value);
}
else
{
int Err=0;
Err = GetLastError();
Print(Err);
switch (Err)
{
case 0: Print("Глобальная переменная ", name," изменена не была",
" т.к. ее значение не равно ", check_value); break;
case 4058: Print("Глобальной переменной ", name,
" не существует"); break;
default: Print("Неизвестная ошибка: ", Err);
}
}


 

Если это баг, то думаю, что в следующих версиях MetaTrader 4 его исправят.

Вернемся к описанию функции GlobalVariableSetOnCondition(). Если же глобальная переменная name существует, то функция не изменит ее текущего значения и вернет false, если текущее значение этой глобальной переменной не равно check_value. Если потом запросить код последней ошибки, то функция GetLastError()вернет ERR_NO_ERROR (т.е. 0), т.к. реально никакой ошибки не было.

Если же текущее значение глобальной переменной name равно значению check_value, то функция GlobalVariableSetOnCondition() присвоит этой глобальной переменной новое значение: value.