- •Внешние переменные
- •Глобальные переменные
- •Формальные параметры функций
- •Операции отношения
- •Логическая операция и (&&)
- •Побитовые операции
- •Объединение арифметических и побитовых операций с операцией присваивания
- •Формат оператора цикла while:
- •Формат оператора цикла for:
- •Оператор досрочного завершения цикла break
- •Формат оператора switch:
- •Формат функции OrderSelect():
- •IsStopped(): как проверить, что эксперт был остановлен
- •Выдерживаем паузу между торговыми операциями
- •Index - индекс элемента
- •Реализация трейлинг стопа в эксперте
- •Функция iAlligator() - Аллигатор Билла Вильямса (Alligator)
- •IGator() - определение периодов сна и бодроствования Аллигатора с помощью Gator Oscillator
- •Функция iGator()
- •IFractals(): фракталы б.Вильямса - первое измерение рынка
- •IAo(): Волшебный Осциллятор Билла Вильямса (Awesome Oscillator - ao) - второе измерение рынка
- •Сигналы Волшебного осциллятора (Awesome Oscillator)
Формальные параметры функций
Как я уже говорил в выпуске "Создание собственных функций" функцию можно описать следующим образом:
тип имя ( формальные параметры ) { действия }
Формальные параметры функции - это значения, которые передаются в функцию. Они указываются через через запятую в круглых скобках после имени функции. Для каждого параметра указывается тип (любой из стандартных: массивы, int, bool, datetime, double, color, string).
В функцию не может быть передано более 64 параметров.
Областью видимости формальных параметров функции является сама функция, т.е. доступ к их значениям может быть получен только в пределах этой функции.
В описании функции параметрам можно присваивать значения по умолчанию. При этом следует иметь в виду, что все параметры, следующие за первым параметром со значением по умолчанию, должны также иметь значения по умолчанию:
int GetSomethingUseful ( int a, int b = 0, bool f = true, double r = 5.9) { ... }
В этом случае все или часть параметро по умолчанию можно упускать при вызове функции, а вместо них автоматически будут подставлены значения по умолчанию:
Вызов GetSomethingUseful(3, 5, false) будет эквивалентен вызову GetSomethingUseful(3, 5, false, 5.9).
Вызов GetSomethingUseful(3, 5) будет эквивалентен вызову GetSomethingUseful(3, 5, true, 5.9).
Вызов GetSomethingUseful(3) будет эквивалентен вызову GetSomethingUseful(3, 0, true, 5.9).
При этом следует помнить, что если мы пропускаем какой-то параметр, имеющий значение по умолчанию, то и все последующие параметры также должны не указываться.
Если мы импортируем функцию из другого модуля, то такие параметры таких функций не могут иметь значения по умолчанию.
Все, что я рассказал выше, касалось передачи параметров в функцию по значению. Чтобы все стало ясно, давайте рассмотрим небольшой пример:
void MyFirstFunction () { int a = 10; MySecondFunction ( a ); } void MySecondFunction ( int b ) { b = b + 1; Print ( b ); }
В этом примере мы вызываем MySecondFunction, передавая в качестве параметра значение переменной "a" (в нашем случае - 10). Таким образом, при вызове MySecondFunction переменной "b" - формальному параметры функции - будет присвоено значение 10, которое будет следующей строчкой увеличено на единицу и выведено в лог. Однако при этом значение переменной a в MyFirstFunction не изменится и останется равным 10.
Существует и другой способ передачи параметров в функцию - по ссылке (используя после описания типа знак амперсенда - &). Рассмотрим новый пример:
void MyFirstFunction () { int a = 10; MySecondFunction ( a ); } void MySecondFunction ( int& b ) { b = b + 1; Print ( b ); }
В этом примере мы вызываем MySecondFunction, передавая в качестве параметра ссылка на переменную "a". Таким образом, в функции MySecondFunction всегда, когда будет идти обращение к переменной b, реально будет идти обращение к переменной a. Т.е. следующей строчкой значение переменной "a" будет увеличено на единицу и выведено в лог. После завершения функции MySecondFunction переменная "а" будет равна 11.
В качестве параметров по ссылке можно передавать как переменные стандартных типов (но только в пределах одного модуля), так и массивы (как в пределах одного модуля, так и в другие модули).
Мы изучили константы и переменные. Однако для того, чтобы что-то сделать с данными или совершить операции по торговому счету, требуется нечто большее - нужно отдать команду. В языке программирования такие команды называются операторами. В следующем выпуске я расскажу о составном операторе.
Составной оператор
В выпуске "Использование констант в эксперте" мы научились описывать константы и разобрались, что же в коде нашего первого эксперта означают следующие строчки:
#define STATE_SQUARE 0 #define STATE_LONG 1 #define STATE_SHORT 2
В выпуске Внешние переменные мы научились задавать параметры эксперта, и нам стали понятны следующие строчки:
extern int MAPeriod = 13; extern double LotsNumber = 1.0;
Кроме локальных и статических переменных мы рассмотрели и глобальные (на уровне одного модуля) переменные, в результате приоткрылась завеса над еще двумя строчками нашего эксперта:
int CurrentState; int MyOrderTicket;
Теперь рассмотрим более подробно, что же в нашем эксперте делает функция init().
int init() { //---- if (iMA(NULL, 0, MAPeriod, 0, MODE_EMA, PRICE_CLOSE, 0) > Close[0]) CurrentState = STATE_SHORT; else CurrentState = STATE_LONG; MyOrderTicket = 0; //---- return(0); }
Как мы знаем из выпуска "Функции init(), start() и deinit()" эта функция запускается в следующих случаях:
после присоединения советника к графику;
после старта MetaTrader 4 и подгрузки исторических данных;
после смены инструмента или периода графика;
после перекомпиляции программы в редакторе MetaEditor;
после изменения настроек эксперта;
после смены торгового счета.
Если отбросить комментарии, которые начинаюся с двойного флэша (//), то мы увидим, что эта функция состоит из нескольких команд (назовем их операторами), разделенных точкой запятой (;). Когда нам нужно объединить несколько операторов в один связный блок (например, в функцию), мы используем конструкцию, которая называется составной оператор. Иными словами мы эти операторы заключаем в фигурные скобки { и }. После закрывающей фигурной скобки { не должно стоять точки с запятой.
Пример составного оператора:
if (b==3) { b = b + 1; Print (b); }
В следующем выпуске я расскажу об операторе присваивания.
Оператор присваивания. Арифметические операции
В предыдущем выпуске я рассказал о составном операторе. В этом выпуске я расскажу об операторе присваивания.
Формат оператора присваивания:
переменная = выражение;
В качестве левой части оператора присваивания может выступать также элемент массива. Вначале вычисляется выражение, которое потом присваивается переменной.
Пример оператора присваивания:
b = b + 1;
Допустим, что перед выполнением этого оператора переменная "b" была равна 7. Тогда вначале вычисляется выражение в правой части ( 7+1 = 8 ), а затем значение этого выражение (8) присваивается переменной "b".
В выражении может использоваться несколько типов операций. Рассмотрим самый простой тип - арифметические операции:
Операция |
Пример |
Сложение двух аргументов |
j + k |
Вычитание второго аргумента из первого |
j - k |
Умножение аргументов |
j * k |
Получить частное от деления первого аргумента на второй |
j / k |
Получить остаток от деления первого аргумента на второй |
j % k |
Изменить знак аргумента |
-k |
Вне выражений (в виде отдельного оператора) можно применять операции:
Увеличение аргумента на единицу: j++
Уменьшение аргумента на единицу: j--
Пример:
j++; // верное выражение
k = (j++) + 3; // неверное выражение
В следующем выпуске я расскажу об операциях отношения.
Операции отношения
Как мы уже знаем, один из стандартных типов переменных в языке MetaQuotes Language 4 - тип bool. Переменная типа bool может принимать только два значения: ИСТИНА (true) и ЛОЖЬ (false). Значение ЛОЖЬ представляется в виде нулевого значения, а ИСТИНА - ненулевого.
Значение операции отношения или логической операции будет иметь тип bool.
