Заработать на ФОРЕКС
Пятница, 31.03.2017, 01:34
Всё для прибыльной торговли на FOREX!
Главная | Добавить в избранное | Сделать стартовойфорекс советники
Меню сайта
Категории раздела
Торгуем прибыльно с Price Action и VSA [27]
Учимся прибыльно торговать с помощью методики Price Action и VSA
Форекс видео уроки [14]
Форекс видео уроки
Основы Финансового Рынка - Азбука Инвестора форекс видео [41]
Форекс видео уроки для трейдеров и инвесторов - Азбука Инвестора
Лучшие брокеры
заработок в интернете форекс бесплатно Виртуальный выделенный сервер для Форекс Виртуальный выделенный сервер для Форекс Виртуальный выделенный сервер для Форекс Виртуальный выделенный сервер для Форекс заработок в интернете заработок на форекс заработок в интернете заработок в интернете заработок в интернете заработок в интернете Виртуальный выделенный сервер для Форекс
Радио Forex
Друзья сайта
Поиск
Наш опрос
Рейтинг брокеров
Всего ответов: 1917
Термины ФОРЕКС
<a href="http://instaforex.com/ru/" rel="nofollow">Форекс портал</a>

Основы языка MQL 4. Сложные вопросы простым языком

Часть1

Введение

     Это вторая статья из цикла "Основы языка MQL 4". В первой статье "Основы языка MQL 4. Первое знакомство" рассказывалось о том, что можно сделать с помощью языка MQL4, мы научились писать обычные скрипты, поняли, что такое переменная, научились работе с переменными, разобрались, что такое функция, массивы, встроенные или предопределённые массивы и переменные, циклы for и простые и сложные условия. Сейчас мы будем разбираться в более сложных и продвинутых конструкциях языка, изучим новые возможности и посмотрим, как их можно применять в ежедневной практике. Сегодня вы узнаете про новый вид циклов while, новый вид условий switch, операторы break и continue. Кроме того вы научитесь писать собственные функции и работать с многомерными массивами. На десерт я подготовил для вас разъяснения о препроцессоре.

Совет

Не вздумайте читать эту статью, полностью не разобравшись с первой. Вы только наломаете дров и все равно ничего не поймете. Эта статья основывается на старом материале, так что не нужно спешить! Также хочу успокоить вас. Сложности, с которыми вы сталкиваетесь сейчас при изучении материала, обманчивы. Придет время, когда вы даже не будете задумываться о том, как пишутся циклы, где какие условия поставить, - все будет происходить автоматически. Чем дольше вы будете работать с языком MQL4, тем легче вам будет его использовать.

 

Новый вид циклов while

Хочу отметить, что цикл for, описанный в предыдущей статье, является универсальным и может заменить другой вид циклов, с которым мы сейчас познакомимся. Но это не всегда удобно и оправданно. Иногда намного эффективнее использовать while. Скоро вы сами поймете, где какой вид цикла использовать более рационально. Давайте выполним одну задачу двумя способами: найдем суммарный объем всех баров, используя оба цикла и посмотрим в чем разница:

// используем цикл for
double sum = 0.0;
 
for(int a = 0; a < Bars; a++)
 sum += Volume[a];
 
// здесь используем while, результат будет одинаковый
double sum = 0.0;
int a = 0;
 
while(a < Bars)
 {
 sum += Volume[a];
 a++;
 }
Как видно, теперь счетчик объявляется и используется отдельно. Вообще while переводится как "пока". То есть не "до свидания", а в том смысле, что пока это условие истинно, то цикл продолжает выполняться. Посмотрите на общую форму:
while(условие выполнения цикла)
 {
 код
 }

Вот ещё более понятный пример:

while(пока я не доел яблоко) // условие
 {
 // что делать, если условие не выполнено
 укусить еще; 
 }
На самом деле цикл while отличается от for лишь отсутствием счетчика. Если он вам не нужен используйте while, хотя это не обязательно. Например, я часто использую while со счетчиком, это уже больше дело вкуса. Как и в случае с for, если тело цикла включает лишь одну инструкцию, то можно упустить фигурные скобки. Также, для общего развития вам нужно запомнить значение слова итерация. Это один из многочисленных проходов (повторений), которые выполняет цикл. То есть выполнив тело цикла один раз, тем самым была выполнена одна итерация.
 

Новый вид условий switch или переключатель

Как и в случае с циклами, нужно отметить, что switch можно заменить на комбинацию привычных вам условий if и else. Конструкция switch используется в том случае, когда вам нужно выполнить определенные действия в зависимости от значения какой-то переменной. Это похоже на обычный переключатель режимов в микроволновке. Например, представьте, что вы пишите советника и он изменяет свое поведение в зависимости от состояния рынка. Пусть за это отвечает переменная int marketState. Она может принимать следующие значения:

  • 1 - восходящий тренд
  • 2 - нисходящий тренд
  • 3 - флэт

Неважно как определяется это состояние, наша задача реализовать какой-то механизм, чтобы советник в зависимости от состояния рынка выполнял соответствующие действия. Что ж, вы умеете это делать. Самый очевидный вариант выглядит следующим образом:

if(marketState == 1)
 {
 // стратегия торговли для восходящего тренда
 }
else 
 if(marketState == 2)
 {
 // стратегия для нисходящего тренда
 }
 else 
 if(marketState == 3)
 {
 // стратегия для флета
 }
 else
 {
 // ошибка: такого состояния не предусмотрено!
 }

Тут нужно отметить несколько особенностей:

  • все условия проводятся с одной и той же переменной;
  • все условия сводятся к сравнению этой переменной с одним из значений, которые она способна принимать.

Так вот, все это относится и к структуре switch. Посмотрите на аналогичный по результату код, который использует switch:

switch(marketState)
 {
 case 1: // стратегия торговли для восходящего тренда
 break;
 case 2: // стратегия для нисходящего тренда
 break;
 case 3: // стратегия для флета
 break;
 default: // ошибка: такого состояния не предусмотрено!
 break;
 }

Обратите внимание, сначала мы указываем какую переменную будем сравнивать:

// switch - ключевое слово, marketState - 
// переменная для сравнения
switch(marketState)

а потом указываем что делать в конкретных случаях:

 

 
case 1: // case - ключевое слово; 
 // стратегия торговли // если marketState равно 1, то 
 // для восходящего тренда // выполняем этот код
 break; // ключевое слово, которое указывает 
 // на конец действий в этом случае
 
case 2: // если marketState равно 2, то
 // стратегия для // выполняем это
 // нисходящего тренда 
 break; // конец
 
case 3: // аналогично
 // стратегия для флета
 break;
 
default: // иначе, выполняем это
 // ошибка: такого 
 // состояния не 
 // предусмотрено!
 break;

В общем виде switch имеет такую форму:

switch(переменная для сравнения)
 {
 case [значение переменной]:
 // код для этого случая
 break;
 
 case [другое значение переменной]
 // код для этого случая
 break;
 
 default:
 // код для всех остальных случаев
 break;
 }

Используйте switch, если сравниваете одну переменную с несколькими значениями и каждому значению соответствует определенный блок кода. В любом другом случае используйте обычные комбинации условий if и else. Иногда нужно выполнить какой-то код при нескольких значениях переменной. То есть, например, если marketState == 1 или 2, то выполнить такой-то код. Вот как это можно сделать используя switch:

switch(marketState)
 {
 case 1: // если marketState равно 1
 case 2: // или если marketState равно 2, то
 // выполнить это
 break;
 
 default: // в любом другом случае выполнить 
 // этот код
 break;
 }

 

Операторы continue и break

С оператором break мы только что познакомились. Он предназначен для выхода из тела switch. Кроме того вы можете его использовать для выхода из цикла. Например, если при каких-то условиях цикл больше выполнять не требуется. Допустим нам нужно узнать сколько первых баров потребуется, что бы вместить объем в 1000 пунктов. Для этого можно написать такой код:

int a = 0;
double volume = 0.0;
 
while(volume < 1000.0)
 {
 volume += Volume[a]; // равносильно volume = volume + Volume[a]; 
 a++;
 }
 
// теперь переменная "a" содержит количество баров, которые 
// в сумме имеют объем не меньше 1000 пунктов

А теперь напишем аналогичный код, но будем использовать оператор break:

int a = 0;
double volume = 0.0;
 
while(a < Bars)
 {
 // если объем превышает 1000 пунктов, то
 if(volume > 1000.0) // выходим из цикла 
 break; 
 
 volume += Volume[a];
 a++;
 }

Как видно оператор break очень прост в использовании и позволяет избавиться от лишних итераций цикла. Еще один полезный оператор continue предназначен для "пропускания" ненужных итераций. Пусть нам нужно посчитать суммарный объем, но мы не должны учитывать объемы баров в момент важных новостей. Как известно, важные новости влекут за собой огромные объемы пунктов. Притворимся наивными детьми и будем считать, что объем бара в 50 пунктов и больше - это новость. Для решения этой задачки воспользуемся оператором continue:

int a = -1;
double volume = 0.0;
 
while(a < Bars)
 {
 a++;
 // если объем превышает 50 пунктов, то это должно 
 // быть новость, пропустим ее 
 if(Volume[a] > 50.0) 
 continue; 
 volume += Volume[a];
 }

Как видите, использование оператора continue довольно тривиально, но иногда это может очень помочь вам. Понятно, что этот скрипт предназначен для мелких таймфреймов.

Пишем собственные функции

Да, но зачем они нужны? Дело в том, что частенько в вашем коде вы будете находить повторы. То есть один и тот же набор инструкций вы будете использовать то здесь, то там. Что бы сэкономить ваше время и силы, вы можете вынести этот повторяющийся код в отдельную функцию. А когда нужно, просто вписать название этой функции и она сделает все за вас. Давайте посмотрим как это работает. Представьте, что вам нужно узнать цвет свечи. Всем известно, что "белой" считается свеча, которая закрылась выше открытия, "черной" - наоборот. Напишем код для определения цвета свечи:

bool color; // так как имеется всего 2 варианта 
 // (белая или черная свеча), 
 // то будем считать, что значению 
 // false соответствует черная 
 // свеча, а true - белая
 
if(Close[0] > Open[0])
 color = true; // белая свеча
 
if(Open[0] > Close[0])
 color = false; // черная свеча

Вот и все, теперь в переменной color хранится цвет последней свечи. Что бы узнать цвет какой-то другой свечи, например, предпоследней, нужно изменить индекс с 0 на 1. Но не будете же вы вставлять этот код в любом месте, где понадобиться узнать цвет свечи! А если таких мест будет несколько десятков? Именно поэтому нужно использовать функции. Давайте подумаем, как она должна работать. Подобная функция должна принимать один аргумент - индекс свечи, цвет которой нужно определить, и возвращать цвет - переменную типа bool. Представим, что функция уже написана и мы вызываем ее:

bool color; // сюда будет записан цвет нужной нам свечи
 
color = GetColor(0);

Как вы догадались, наша функция будет называться GetColor. В этом вызове мы захотели узнать цвет последней свечи, поэтому единственный аргумент равен нулю. Функция возвращает цвет свечи, поэтому мы сразу выполняем присваивание. Это очень важный момент! Внутри функции создается переменная, а потом ее значение подставляется вместо самого вызова функции. В конечном итоге вызов функции и код определения функции, тот, что мы писали выше, дадут одинаковый результат - в переменной color будет записан цвет последней свечи, но используя функции мы затрачиваем меньше усилий.

А теперь давайте неожиданно остановимся на коде пустого скрипта. Создайте новый скрипт. Дело в том, что там уже включено полное описание функции start(). Самое интересное то, что все это время вы писали скрипты в этой функции! Когда вы запускаете ваш скрипт, то терминал просто вызывает функцию start(). Рассмотрим подробнее код пустого скрипта:

int start()

Эта строка очень важна! Она включает

название функции

, то есть ключевое слово, которое вы будете писать, когда захотите вызвать эту функцию. В нашем случае это - start. Также указывается

тип возвращаемого значения

- int. Это значит, что после выполнения функции, она возвратит нам какое-то значение типа int. В скобках размещается

перечень аргументов

, но в нашем случае функция не принимает никаких параметров.

После этого в фигурных скобках следует описание самой функции, то есть тот код, который будет выполняться при вызове:

 {
 //----
 // код, который будет выполняться 
 // при вызове функции.
 //----
 return(0);
 }

Как видно, все это время мы писали код в теле функции start(). В самом конце функции находится оператор

return

, который возвращает значение функции. В нашем случае возвращается нуль.

Теперь посмотрите на общую форму написания функций:

[тип возвращаемого значения] [название функции] ([перечень аргументов])
 {
 // код функции
 return([значение, которое функция возвращает]);
 }

А теперь давайте вернемся к нашим свечам и функции GetColor. Посмотрите на код этой функции:

bool GetColor(int index)
 {
 bool color;
 if(Close[index] > Open[index])
 color = true; // белая свеча
 if(Open[index] > Close[index])
 color = false; // черная свеча
 return(color);
 }

Рассмотрим первую строку детально:

bool GetColor(int index)

Здесь имеем: bool - тип возвращаемого значения; GetColor - название функции; int - тип аргумента; index - название аргумента. Обратите внимание, что мы используем index для обращения в теле функции, но при непосредственном вызове функции это названия никогда не упоминается, например:

bool lastColor = GetColor(0);

Смотрим дальше:

{
 bool color;
 if(Close[index]>Open[index])
 color=true; // белая свеча
 if(Open[index]>Close[index])
 color=false; // черная свеча

Это тело функции - основной код, который будет выполняться при каждом вызове. Смотрим дальше:

 return(color);
}

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

bool GetColor(int index)
 {
 if(Close[index] > Open[index])
 return(true); // белая свеча
 if(Open[index] > Close[index])
 return(false); // черная свеча
 }

Как видно, использование нескольких операторов return позволило избавиться от переменной color. Кроме того в операторе return можно использовать даже логические выражения:

return(Close[index] > Open[index]);

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

Теперь давайте вернемся к списку аргументов. В нашей функции используется лишь один аргумент - int index. Если нужно использовать несколько аргументов, то перечислите их через запятую:

bool SomeСomplicatedFunction(int fistArgument, int secondArgument, 
 sting stringArgument)

Чтобы обратится к этим аргументам, используйте их имена, как и в предыдущей функции. При вызове функций с несколькими аргументами обращайте внимание на

порядок следования аргументов

: ничего не перепутайте! Если функция не должна возвращать никакого значения, то используйте ключевое слово

void

, чтобы указать это. Обратите внимание, оператор return в этом случае не используется:

void function()
 {
 // код
 }

Есть еще одна тонкость: вы можете задать значения для аргументов функций по умолчанию. Что это такое? Допустим, вы написали какую-то сложную функцию, у которой есть 5 аргументов, которые настраивают ее поведение. Но последние несколько аргументов почти всегда используются с одними и теми же значениями. Только на два десятка вызовов вам приходится применять какие-то специальные значения. Что бы не указывать каждый раз значения последних аргументов, которые почти всегда одинаковы, используются значения аргументов по умолчанию. В таком случае вы просто пропускаете последние аргументы, как будто их не существует, но на самом деле они используются, только им присваиваются значения по умолчанию. Когда же возникает тот самый специальный случай, то вы указываете все аргументы. Посмотрим как можно объявить функцию с аргументами по умолчанию:

void someFunction(int argument1, int argument2, 
 int specialArgument = 1)
 {
 // код
 }

Как видите, все очень просто: мы присваиваем нужному аргументу нужное значение и теперь его можно пропускать при вызове:

someFunction(10,20); // мы пропустили последний аргумент, но 
 // на самом деле ему присвоено значение по умолчанию
 
someFunction(10,20,1); // этот вызов полностью аналогичен предыдущему
 
someFunction(10,20,2); // а тут мы указали другое значение, обычно 
 // такое редко бывает

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

void someFunction(int argument1, int argument2, 
 int specialArgument = 1) // все верно
 
void someFunction(int argument1, int argument2 = 10, 
 int specialArgument=1) // верно
 
void someFunction(int argument1, int argument2 = 10, 
 int specialArgument) // неправильно! значения 
 // по умолчанию должны
 // быть в конце списка 
 // аргументов
 
void someFunction(int argument1 = 0, int argument2 = 10, 
 int specialArgument = 1) // можете хоть всем 
 // аргументам присвоить 
 // значения по умолчанию

 

 



Наш выбор брокеров
forex4you roboforex форекс бесплатно заработать на форекс instaforex nordfx

Копирование
VPS для Форекс
vps сервер для форекс
Заработать на ФОРЕКС
памм инвестирование
Форекс обзор
<a href="http://instaforex.com/ru/" rel="nofollow">Форекс портал</a>
Наша кнопка
Установите нашу кнопку себе на сайт

Форекс советники

Торговые сессии
Котировки Sell/Buy
vps для форекс
Журнал
FOREX MAGAZINE
Форекс рассылки
FxMail.ru
Рекомендуемые Форекс рассылки
Форма входа
Статистика
vps для форекс сервер для форекс
Онлайн всего: 2
Гостей: 2
Пользователей: 0
Календарь
«  Март 2017  »
ПнВтСрЧтПтСбВс
  12345
6789101112
13141516171819
20212223242526
2728293031
Торговля на финансовых рынках сопряжена с риском. Все материалы носят исключительно ознакомительный характер. Администрация сайта не несет ответственности за принимаемые Вами решения.
Copyright Profit © 2010 - 2017

Облако тегов: форекс для начинающих форекс для начинающих видео форекс для новичков форекс для тебя форекс для чайников форекс анализ технический анализ форекс прогноз форекс аналитика рейтинг форекс брокеров форекс видео брокеры форекс лучшие брокеры форекс надежный брокер форекс форекс брокеры отзывы самый лучший форекс брокер MQL4 Волновой форекс анализ и прогноз mql4 com язык mql4 mql4 программирование mql4 учебник Форекс аналитика от Trading Central трейдер VSA форекс вебинар бесплатные советники форекс советники форекс бесплатно vps для форекс форекс сервер советники форекс ПАММ памм счета стратегии форекс торговые стратегии форекс зaрaботaть нa форекс волновой анализ форекс волновой анализ рынка форекс волновой анализ волновой анализ рынка волновой анализ эллиотта волновой анализ элиота аналитика рынка форекс аналитика форекс аналитика форекс на каждый день форекс аналитика прогнозы trading central аналитика аналитика форекс на сегодня trading central заработок на форекс форекс советники vps лучшие советники форекс форекс советники бесплатно Форекс советник аналитика форекс прогноз ежедневная форекс аналитика форекс новости аналитика советники форекс 2014 прибыльные советники форекс советники форекс скачать скачать советник форекс советники форекс 2015 аналитика форекс евро форекс аналити лучшая аналитика форекс импульсный уровень форекс аналитика форекс евро доллар trading central отзывы прогнозы от trading central технический анализ форекс анализ рынка форекс фундаментальный анализ форекс Анализ Форекс нелинейный волновой анализ упрощенн волновой анализ эл волновой анализ eur usd теория волн технический анализ рынка прогноз доллара форекс прогноз рынка форекс форекс прогноз евро доллар аналитика форекс прогнозы прогноз форекс на сегодня аналитика рынка аналитика евро форекс аналитика форекс евро дол прогноз аналитика форекс графический анализ форекс свечной анализ на форекс Фундаментальный анализ форекс на сегодня прогноз рынка форек фундаменталь прогноз форекс 2016 форекс прогноз евро технический анали технический анализ для начинающих технический анализ трейдеров