home

Любой эксперт оперирует с некоторыми данными — ценами, значениями индикаторов, объемами, количеством открытых позиций и пр. Те, места, где эти данные хранятся в эксперте, называются переменными. В качестве имен переменных можно использовать цифры (0-9), латинские прописные и строчные буквы (а — z и А — Z, следует помнить, что буквы ’a’ и ’A’ — совершенно разные символы), символ подчеркивания (_). Первый символ не может быть цифрой. Также имя переменной не должно совпадать с зарезервированным словом (т.е. словом, которое имеет особый смысл в языке MetaQuotes Language 4 — но об этом позже).

Желательно в качестве имени переменной использовать такое, из которого сразу становится понятным предназначение переменной. Например, переменная, содержащая количество открытых позиций, может иметь такое имя: OpenPositionsNumber.

  • Можно создавать переменные разных типов:
  • int — целое число (от -2147483648 до 2147483647);
  • bool — логический тип (или ложь — false, или истина — true);
  • datetime — дата и время (в формате D’YYYY.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. Параметры эксперта

Рис. 1. Параметры эксперта

Если эксперт уже «прикреплен» к графику (в правом верхнем углу графика Вы видите улыбающуюся или грустную рожицу), то для изменения его параметров — значений внешних переменных — нажмите на рожице правую кнопку мыши и выберите в в появившемся контекстном меню пункт «Советники — Свойства …». Более быстрый способ — использовать горячую клавишу F7. Появится окно с параметрами эксперта (см. рис. 1), в котором Вы сможете изменить значения внешних переменных.

Глобальные переменные

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

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

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

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

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

 //---- глобальные переменные
int CurrentState;
int MyOrderTicket;

//---- определения функций
int init()
{
...
}



Начальное значение глобальной переменной может быть только константой (если не задано никакого значения, то она инициализируется нулем). Это значение присваивается глобальной переменной только один раз, до выполнения функции init().