Любой эксперт оперирует с некоторыми данными — ценами, значениями индикаторов, объемами, количеством открытых позиций и пр. Те, места, где эти данные хранятся в эксперте, называются переменными. В качестве имен переменных можно использовать цифры (0-9), латинские прописные и строчные буквы (а — z и А — Z, следует помнить, что буквы a и A — совершенно разные символы), символ подчеркивания (_). Первый символ не может быть цифрой. Также имя переменной не должно совпадать с зарезервированным словом (т.е. словом, которое имеет особый смысл в языке MetaQuotes Language 4 — но об этом позже).
Желательно в качестве имени переменной использовать такое, из которого сразу становится понятным предназначение переменной. Например, переменная, содержащая количество открытых позиций, может иметь такое имя: OpenPositionsNumber.
- Можно создавать переменные разных типов:
- int — целое число (от -2147483648 до 2147483647);
- bool — логический тип (или ложь — false, или истина — true);
- datetime — дата и время (в формате DYYYY.MM.DD HH:MM:SS);
- color — цвет (о формате я расскажу в следующих выпусках);
- double — вещественное число (-1.7 × 10-308 до 1.7 × 10308, точность — 15 значащих цифр);
- string — заключенная в двойные кавычки строка (например, «это строка»).
Перед использованием переменной ее надо объявить. Это можно сделать несколькими способами:
тип имя;
или
тип имя = начальное_значение;
Примеры объявлений переменных:
int Count;
datetime InitialDate = D'2006.07.12 00:00';
string ip_address = "127.0.0.1";
В дальнейшем для того, чтобы обратиться к значению переменной, надо будет просто указать ее имя:
i = 5 + Count;
Иногда требуется сохранить не одно значение, а определенное количество взаимосвязанных значений. Например, значение индикатора на текущем баре, на предыдущем баре, , N-баров назад. Для таких целей существуют массивы. Массив — это индексированная совокупность однотипных данных.
Предположим, что у нас в эксперте есть такое описание массива Prices:
double Prices[50];
Это означает, что массив-переменная Prices предоставляет доступ к 50 элементам типа double. Для доступа к i-му элементу надо указать Prices[i]. Нумерация элементов начинается с нуля и заканчивается 49-м элементов (в нашем случае).
Если Вы попробуете обратиться к элементу вне этого диапазона, то будет зафиксирована ошибка ERR_ARRAY_INDEX_OUT_OF_RANGE (4002), которую можно получить при помощи функции GetLastError().
В случае необходимости можно использовать не только одномерные массивы (у которых только один индекс), но и многомерные массивы.
Пример описания двухмерного массива, состоящего из шести массивов, каждый из которых состоит из 50 элементов:
int mas[6] [50];
При описании массива можно в фигурных скобках задать начальные значения для каждого элемента:
int a[4][4] = { 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4 };
Начальные значения элементов массивов могут быть только константами. Если Вы в фигурных скобках при инициализации массива указали меньшее количество начальных значений, чем размерность массива, то недостающие элементы инициализируются нулями.
Локальные и статические переменные
- Единственным нераскрытом моментом остались области видимости переменных. Дело в том, что переменные бывают нескольких типов:
- локальные переменные,
- статические переменные,
- глобальные переменные,
- внешние переменные,
- параметры функций.
Локальные переменные
Если переменная объявлена в пределах какой-нибудь функции, то она является локальной переменной и видна только в пределах этой функции. За пределами этой функции к этой переменной обращаться нельзя.
Инициализация (присвоение начального значения) локальной переменной происходит каждый раз при вызове функции. Присваиваемое начальное значение может быть как константой, так и выражением.
Пример объявления и инициализации локальной переменной:
int CalcFactorial(int n)
{
int i = 0;
...
}
Cтатические переменные
Статические переменные объявляются директивой static. Они инициализируются только один раз — при первом вызове функции и сохраняют свое значение даже после выхода из функции. В следующий раз при новом вызове функции статические переменные будут иметь то же значение, которое они имели перед выходом из функции в послений раз.
Статические переменные объявляются в пределах описания функции и поэтому доступны для использования только в пределах той функции, в которой они объявлены.
Пример объявления статической переменной:
int GetOpenPositionsNumber()
{
static int Count = 0;
...
}
Внешние переменные
Мы уже сталкивались с внешними переменными, когда описывали параметры эксперта MAPeriod и LotsNumber в коде нашего первого эксперта.
Внешние переменные описываются с помощью зарезервированного слова extern:
extern int MAPeriod=13;
extern double LotsNumber=1.0;
Внешние переменные не могут быть массивами.
Внешние переменные — это параметры эксперта, которые можно изменять.
«Прикрепите» эксперт к графику. Для этого нажмите правую кнопку мыши на названии эксперта в окне «Навигатор» и в появившемся контекстном меню выберите «Присоединить к графику». Появится окно свойств эксперта. Во вкладке «Входные параметры» Вы можете изменить значения внешних переменных, описанных в эксперте (см. рис. 1).
Рис. 1. Параметры эксперта
Если эксперт уже «прикреплен» к графику (в правом верхнем углу графика Вы видите улыбающуюся или грустную рожицу), то для изменения его параметров — значений внешних переменных — нажмите на рожице правую кнопку мыши и выберите в в появившемся контекстном меню пункт «Советники — Свойства ». Более быстрый способ — использовать горячую клавишу F7. Появится окно с параметрами эксперта (см. рис. 1), в котором Вы сможете изменить значения внешних переменных.
Глобальные переменные
Для человека, имеющего уже опыт написания экспертов, выражение «глобальные переменные» может внести небольшую путанницу. Дело в том, что на самом деле существует два вида «глобальных переменных»:
- переменные, которые видны из любой функции ОДНОГО эксперта (т.е. являются глобальными в пределах этого эксперта); и
- переменные, которые являются общими для ВСЕХ экспертов.
В этом выпуске речь пойдет именно о глобальных переменных первого типа — тех, которые являются общими для всех функций ОДНОГО эксперта.
Второй же тип глобальных переменных я рассмотрю в следующих выпусках, когда буду рассказывать о функциях, с помощью которых к таким переменным получают доступ, — GlobalVariable ().
Если Вы хотите, чтобы к значению переменной можно было бы обращаться из разных функций одного эксперта, сделайте ее глобальной переменной, т.е. определите ее на том же уровне, что и функции:
//---- глобальные переменные
int CurrentState;
int MyOrderTicket;
//---- определения функций
int init()
{
...
}
Начальное значение глобальной переменной может быть только константой (если не задано никакого значения, то она инициализируется нулем). Это значение присваивается глобальной переменной только один раз, до выполнения функции init().