Советник FOREX: от идеи до результата — Страница 6 — Тирметод

Операторы MQL4: продолжение

Один оператор может занимать одну или более строк. Два или большее количество операторов могут быть расположены на одной строке. Операторы, управляющие порядком выполнения, такие как if, if-else или for, могут быть вложены друг в друга.

Оператор цикла for

Оператор for состоит из трёх выражений и выполняемого оператора:

for(выражение1; выражение2; выражение3)
   оператор;

Выражение1 описывает инициализацию цикла. Выражение2 — проверка условия завершения цикла. Если оно истинно, то выполняется оператор тела цикла for. Всё повторяется, пока выражение2 не станет ложным. Если оно ложно, цикл заканчивается и управление передаётся следующему оператору. ВыражениеЗ вычисляется после каждой итерации.

Пользовательские функции

Наступил момент, когда мы будем создавать свои пользовательские функции, на основе функций MQL, конечно.

На примере вы убедитесь, что операторы, такие как if, if-else или for, просто необходимы, впрочем, как и другие, которые мы уже применяли, и те, которые, ещё будем применять.

Функция определения тренда

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

Оператор return может возвращать простые типы, простые структуры, указатели объектов. При помощи оператора return нельзя возвращать любые массивы, объекты классов, переменные типа сложных структур.

В нашем примере, см. выше, строка 60 содержит заголовок функции, где:

  • bool – тип возвращаемого значения;
  • TrendUp – имя функции;
  • () – список параметров, по умолчанию аргументы отсутствуют.

Составной оператор {}, см. строки 61 и 68, является телом функции, содержит инструкции, или операторы-выражения, заканчивающиеся точкой с запятой (;), с «предписаниями», а именно:

В данном примере, см. выше строки 60-68, функция будет возвращать значение true постоянно, сколько бы мы её ни вызывали.

– Функция, какой сейчас тренд?

– Наверх!

Добавим инструкцию проверки: «Если цена открытия больше цены закрытия на предпоследнем баре…»

Предпоследний бар имеет индекс 1. См. картинку выше.

iOpen() возвращает значение цены открытия бара с указанными параметрами, см. пример выше с аргументами (внутри круглых скобок):

  • NULL – предопределённая константная переменная – означает текущий символ;
  • PERIOD_D1 – предопределённая константная переменная – означает дневной период графика;
  • 1 – индекс получаемого значения из таймсерии – второй справа, или предпоследний, бар.

iClose() возвращает значение цены закрытия бара с указанными параметрами, см. пример выше с аргументами (внутри круглых скобок):

  • NULL – предопределённая константная переменная – означает текущий символ;
  • PERIOD_D1 – предопределённая константная переменная – означает дневной период графика;
  • 1 – индекс получаемого значения из таймсерии – второй справа, или предпоследний, бар.

Вопрос: «Почему делаем проверку именно предпоследнего бара?»

Ответ: «Потому что, открывая сделку на первом тике нового(последнего) бара, мы определяем тренд по предыдущему бару, уже предпоследнему?»

Вопрос: «Почему мы не делаем проверку: является ли цена открытия меньше цены закрытия?»

Ответ: «Зачем? Проверка условия – цена открытия больше цены закрытия – методом исключения определяет, что текущий бар НЕ медвежий, и означает, что менять значение переменной trend_up НЕ нужно».

Вопрос: «А что, если цена открытия будет равна цене закрытия?..»

Ответ: «Тогда… функция вернёт значение по умолчанию, то есть trend_up=true, хотя это НЕ является истиной в прямом смысле».

Хороший тон – задавать вопросы!

Теперь мы улучшим функцию дополнительными условиями, см. ниже, надеюсь, вы уже научились улавливать логику оператора if-else. Пожалуй, новой для вас будет операция отношения (==).

Итак, если условное выражение в строке 65 истинно, то выполняется оператор в строке 66, причем строки 67-71 программа игнорирует и переходит к исполнению оператора в строке 73. Иначе, если условное выражение в строке 65 ложно, строка 66 игнорируется, и программа переходит к условию в строке 67, после проверки которой – два варианта развития событий: если выражение ложно – программа переходит к строке 73, иначе, переходит к проверке условия в строке 69, которое, если является истинным, то меняет значение переменной trend_up на false, иначе (опять) ничего не происходит и программа, перейдя к оператору return, выдаст значение trend_up по умолчанию, то есть true.

Вот, всё это называется вложенностью  операторов.

Вопрос: «А что, если цена открытия будет равна цене закрытия на предпоследнем… и пред-предпоследнем баре?»

Ответ: «Бля… поэтому надо было сразу использовать оператор цикла for!»

Сперва мы объявим новую переменную, см. строку 64 ниже.

Новая инструкция, см. строку 64 выше, предписывает целому типу (int) переменной с идентификатором i_bar присвоить (=) значение, возвращаемое функцией iBars(), с аргументами (внутри круглых скобок):

  • NULL – предопределённая константная переменная, означающая текущий символ;
  • PERIOD_D1 – предопределённая константная переменная, означающая дневной период графика.

Повторим ещё раз, предназначение функции iBars() – возвращать количество баров в истории по соответствующему символу и периоду.

Оператор цикла for, см. строку 66 выше, содержит 3 выражения:

  1. Выражение1 (int i=1;) описывает инициализацию цикла.
  2. Выражение2 (i<i_bar;) – проверка условия завершения цикла. Если оно истинно, то выполняется оператор тела цикла for, то есть составной оператор {}, см. строки 67-74. Всё повторяется, пока выражение2 не станет ложным, то есть пока ни переберёт все бары в истории. Если оно ложно, цикл заканчивается и управление передаётся следующему оператору.
  3. Выражение3 (i++) вычисляется после каждой итерации. То есть, изначально переменная i равна 1, потом 2 (i = i+1 = 1+1), потом 3 (i = i+1 = 2+1)  и т.д.

Тело оператора цикла for содержит инструкцию, см. строки 68-73 выше, означающую:

Таким образом, наш поиск заключается в определении первого бара, начиная с предпоследнего, который НЕ соответствует «доджи», бару с одинаковыми значениями цены открытия и закрытия. То есть, исключаем, такую вероятность. Нам не требуется перебирать все бары. Используя оператор завершения (break), мы выходим из цикла заранее, или заблаговременно.

Теперь добавим основную инструкцию: «Если цена открытия больше цены закрытия…», см. строки 70-71.

Voilà! Функция определения тренда готова.

Приглядитесь, тело функции разграничено на части:

  • вход (в рот), строки 63-64;
  • переваривание (в желудке), строки 66-74;
  • выход (через…), строка  76.

Однако, в дальнейшем создавать пользовательские функции будет проще…

{Продолжение следует}