Запись и чтение глобальной переменной

Для записи и чтения глобальных переменных MQL5 API предоставляет 2 функции: GlobalVariableSet и GlobalVariableGet (в двух вариантах).

datetime GlobalVariableSet(const string name, double value)

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

При успешном выполнении функция возвращает время модификации переменной (текущее локальное время компьютера). В случае ошибки получим 0.

double GlobalVariableGet(const string name)

bool GlobalVariableGet(const string name, double &value)

Функция возвращает значение глобальной переменной по имени name. Результат вызова первого варианта функции содержит непосредственно значение переменной (в случае успеха) или 0 (в случае ошибки). Поскольку переменная может содержать значение 0 (что совпадает с индикацией ошибки), данный вариант требует анализировать внутренний код ошибки _LastError, если получен ноль, чтобы отличить штатное исполнение от нештатного. В частности, если делается попытка прочитать несуществующую переменную, генерируется внутренняя ошибка 4501 (GLOBALVARIABLE_NOT_FOUND).

Данный вариант функции удобно применять в алгоритмах, где получение нуля является подходящим аналогом инициализации по умолчанию для несуществовавшей ранее переменной (см. пример ниже). Если же отсутствие переменной нужно обработать особым образом (в частности, вычислить какое-то другое стартовое значение), следует предварительно проверить переменную на существование с помощью функции GlobalVariableCheck и в зависимости от её результата выполнять разные ветки кода. Или же можно воспользоваться вторым вариантом.

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

В тестовом скрипте GlobalsRunCount.mq5 используем глобальную переменную для подсчета количества раз, которое он запускался. В качестве имени переменной выступает имя исходного файла.

const string gv = __FILE__;

Напомним, встроенный макрос __FILE__ (см. раздел Предопределенные константы) раскрывается компилятором в название компилируемого файла, то есть в данном случае "GlobalsRunCount.mq5".

В функции OnStart попытаемся прочитать данную глобальную переменную и сохраним полученный результат в локальную переменную count. Если глобальной переменной еще не было, получим 0, что нас устраивает (начинаем подсчет с нуля).

Перед сохранением значения в count необходимо делать приведение к (int), поскольку функция GlobalVariableGet возвращает double, и без приведения компилятор выдает предупреждение о потенциальной потере данных (он не в курсе, что мы планируем хранить исключительно целые числа).

void OnStart()
{
   int count = (int)PRTF(GlobalVariableGet(gv));
   count++;
   PRTF(GlobalVariableSet(gvcount));
   Print("This script run count: "count);
}

Затем мы увеличиваем счетчик на 1 и записываем его обратно в глобальную переменную с помощью GlobalVariableSet. Если запустить скрипт несколько раз, получим примерно следующие записи в журнале (метки времени у вас будут отличаться):

GlobalVariableGet(gv)=0.0 / GLOBALVARIABLE_NOT_FOUND(4501)
GlobalVariableSet(gv,count)=2021.08.29 16:04:40 / ok
This script run count: 1
GlobalVariableGet(gv)=1.0 / ok
GlobalVariableSet(gv,count)=2021.08.29 16:05:00 / ok
This script run count: 2
GlobalVariableGet(gv)=2.0 / ok
GlobalVariableSet(gv,count)=2021.08.29 16:05:21 / ok
This script run count: 3

Важно отметить, что при первом запуске мы получили значение 0, и был взведен внутренний признак ошибки 4501. Все последующие вызовы уже выполняются без проблем, так как переменная существует (её можно увидеть в окне "Глобальные переменные" терминала). Желающие могут закрыть терминал, запустить его вновь и выполнить скрипт еще раз: счетчик продолжит увеличиваться с прошлого значения.