Философия MQL4

Программирование прибыли: от азов к секретам мастерства. Читайте, спрашивайте, делитесь опытом.
Бонус за сообщение 0.5$
Ответственный Модератор - Haos

Философия MQL4

Сообщение mfcoder » 01 авг 2013, 19:37

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

здесь я попробую сделать небольшое оглавление о нижеизложенном

1. Общая информация о MQL (первые две страницы)
2. Создание индикаторов
3. Использование графических объектов
3.1. Создание графических объектов
3.1.2. Вывод текста
3.1.3. Создание текстовой метки
3.1.4. Создание объекта стрелка
3.1.5. Рисование линий
3.1.5.1. Вертикальная линия
[urlhttps://investforum.ru/forum/viewtopic.php?f=8&t=99&start=10#p1179]3.1.5.2.[/url] Создание горизонтальной линии
3.1.5.3. Создание трендовой линии
3.1.5.4. Дополнительные свойства (размер/толщина, отображение в фоне, стиль отображения)
3.2. Манипуляции с графическими объектами
4. Создание скриптов
5. Создание советников
Аватар пользователя
mfcoder
 
Сообщений: 1531
Зарегистрирован: 29 июл 2013, 11:55
Средств на руках: 26.85 Доллар
Группа: Базовая
Благодарил (а): 78 раз.
Поблагодарили: 423 раз.

Re: Философия MQL4

Сообщение mfcoder » 01 авг 2013, 20:03

1. Общая информация о MQL

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

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

Скрипты - это программный компонент, который вызывается одноразово, скрипт может выполнять практически любые действия, которые можно переложить в код

Советники - это программный компонент, который работает в интерфейсном потоке и выполняет заложенные в нем торговые или иные действия .

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

Использование индикаторов, то использование их на одном графике почти не ограничено (на самом деле оно есть, точно не помню сколько), что касается советников и скриптов, то больше одного каждого из них использовать никак не получится..
Аватар пользователя
mfcoder
 
Сообщений: 1531
Зарегистрирован: 29 июл 2013, 11:55
Средств на руках: 26.85 Доллар
Группа: Базовая
Благодарил (а): 78 раз.
Поблагодарили: 423 раз.

Re: Философия MQL4

Сообщение mfcoder » 01 авг 2013, 20:40

Стандартный интерфейс mql-программы описан тремя системными функциями:
init() - данная функция вызывается при старте программы и предназначена в общем случае для инициализации стартового состояния программы

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

start() - вызывается после функции init() и является стартовой точкой для начала исполнения программы

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

Функция deinit() вызывается при удалении программы с графика, и, аналогично функции init() при манипуляции с графиком или компиляции кода

Функция start() автоматически вызывается после функции init() по приходу нового тика

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

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

Для скриптов и советников функция init() необязательна, хотя часто в скриптах используют вызов действий уже в init(), это делается для ускорения вызова действия, чтобы не ожидать прихода нового тика. Следует учитывать для скриптов, что если весь вызов действий перенесен в функцию init(), то на всякий случай нужно иметь пустую функцию start(), т.к. в некоторых случая без нее скрипты не компилируются. Под пустой функцией я имею в виду функцию без тела, т.е. без каких либо действий, вида
Код: выделить все
int start() {}
Аватар пользователя
mfcoder
 
Сообщений: 1531
Зарегистрирован: 29 июл 2013, 11:55
Средств на руках: 26.85 Доллар
Группа: Базовая
Благодарил (а): 78 раз.
Поблагодарили: 423 раз.

Re: Философия MQL4

Сообщение mfcoder » 01 авг 2013, 23:14

Структуру любой программы можно описать примерно такой конструкцией

[специфичные для программы определения]
[импорты внешнего код]
[импорты функций внешних библиотек]
[внешние переменные]
[глобальные переменные]
[функции]


Опишем содержательно что подразумевается в вышеперечисленных пунктах.

[специфичные для программы определения] - у каждой программы возможны специфичные определения, которые задаются специальным идентификатором #property. Есть необязательные определения, как например, copyright или link, которые описывают разработчика и его интернет ресурс, в коде они выглядят так
Код: выделить все
#property copyright "Copyright © 2009-2012, mfcoder"
#property link      "mfcode@mfcoder.ru"


такие декларации не влияют на работоспособность/функциональность кода

Для индикаторов, например, актуальны такие параметры:
indicator_chart_window - выводить индикатор в окно графика
indicator_separate_window - выводить индикатор в отдельное окно
indicator_buffers - количество буферов для расчета индикатора
indicator_colorN - цвет для вывода линии N, где N от 1 до 8
и т.п. все это можно посмотреть в справке

Для скриптов используются
show_confirm - выводить окно подтверждения перед запуском скрипта
show_inputs - выводить окно со свойствами перед запуском скрипта и запретить вывод окна подтверждения

[импорты внешнего код] - это подключение внешнего файла с кодом, выглядит в коде так
#include <order.mqh>

декларация #include говорит компилятору о том, что нужно взять файл order.mqh из каталога include, который расположен в каталоге experts вашего терминала и добавить весь код этого файла к коду вашей программы

Для чего нужны такие include ресурсы ? Разумеется по мере изучения языка и написания кода программ так или иначе создаются какие-то полезные функции, которые можно использовать в последствии, так вот Include файлы как раз и наполняются нашими наработками, чтобы потом в "два клика" написать какой-то специфический скрипт.

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

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

Что такое mql-библиотека ? В отличие от include файла, который представляет собой исходный код, библиотека это скомпилированный код.

Как получается библиотека? Собственно, берется исходный код, например, имеющийся include-файл копируется в каталог libraries, который находится в каталоге experts вашего терминала, затем открываете этот файл в метаедиторе и в начало кода файла добавляете декларацию #property library - эта декларация говорит компилятору, что при компиляции не нужно пропускать неиспользуемые функции, т.е. все функции что есть в файле буду скомпилированы, таком образом будет получен ex4-файл - файл библиотеки.

Чтобы иметь возможность использовать какую-либо функцию из библиотеки в коде программы нужно произвести импорт необходимых функций, например, так
Код: выделить все
#import "stdlib.ex4" //<-- здесь указывается имя файла скомпилированной библиотеки
   string ErrorDescription(int error_code);
   int    RGB(int red_value, int green_value, int blue_value);
#import


Что такое DLL - это библиотеки динамической компоновки, собственно, это могут как самописные так и системные библиотеки Windows, которые также можно подключать для реализации решений, которые нельзя осуществить с помощью штатных средств mql, например прочитать содержимое сайта или подключиться в базе данных и т.п.
Импорт функций DLL выглядит так
Код: выделить все
#import "user32.dll"
  int      GetActiveWindow();
#import


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

[внешние переменные] - такие переменные в коде объявлены со спецификатором extern
Для чего нужны такие переменные, как правило этот тип переменных используется в качестве параметров программ, которые можно задавать при старте программы через специальное окно свойств, стоит уточнить, что у индикаторов и советников данные параметры доступны через окно свойств при их наличии, а чтобы они были доступны у скрипта, то необходимо в начале кода скрипта сделать объявление
Код: выделить все
#property show_inputs


иначе окно свойств не будет выводиться и скрипт будет автоматический выполняться, т.е. внешние переменные по сути будут иметь свойство глобальных переменных в коде программы

Например, в коде, внешние переменные выглядят так
Код: выделить все
extern int drawBars = 100;
extern int period = 24;
extern bool showSkipVolumePeriod = false;


а в окне свойств, так
params.png


[глобальные переменные] - это переменные, которые объявлены вне функций, как правило их пишут в начале кода, чтобы не потерять, но в принципе их можно писать между любыми функциями, но так не рекомендуется из-за нечитабельности, данный вид переменных доступен в любом месте кода, т.е. в любой функции, впрочем также как и внешние переменные.
Код: выделить все
double value    = 0;
int period       = 13;
color col      = Red;


[функции] - это блоки кода выделенные особым образом и выполняющие заданный набор действий
Функции различаются по возвращаемым значениям, т.е. функция может возвращать значение заданного типа, а может ничего не возвращать, а лишь выполнять внутри себя какие-то действия..

Примеры функций с возвращаемыми значениями

Код: выделить все
int getValue(){ //Функция возвращает целочисленное значение
    return(1);
}

//Функция возвращает значение  с плавающей точкой - дробное значение,
// в данном случае произведение двух чисел, которые передаются в функцию в качестве параметров a и b
double getValue(double a, double b){
    return(a*b);
}

//Функция ничего не возвращает, производит вывод сообщения в журнал
void print(string s ){
    Print(s);
}


и так примерный шаблон программы
[специфичные для программы определения]
[импорты внешнего код]
[импорты функций внешних библиотек]
[внешние переменные]
[глобальные переменные]
[функции]


выглядит так
Код: выделить все
//[специфичные для программы определения]
#property copyright "Copyright © 2009-2012, mfcoder"
#property link      "mfcode@mfcoder.ru"

//[импорты внешнего код]
#include <order.mqh>

//[импорты функций внешних библиотек]
// импорт mql-библиотек
#import "stdlib.ex4" //<-- здесь указывается имя файла скомпилированной библиотеки
string ErrorDescription(int error_code);
int    RGB(int red_value, int green_value, int blue_value);
#import

// импорт DLL-библиотек
#import "user32.dll"
int      GetActiveWindow();
#import

//[внешние переменные]
extern int drawBars = 100;
extern int period = 24;
extern bool showSkipVolumePeriod = false;

[глобальные переменные]
double value    = 0;
int period      = 13;
color col       = Red;

//[функции]
int init() {
    print("init");
}

int deinit() {
    print("deinit");
}

int start(){
    print("start");
}

void print(string s){
    Print(s);
}
Аватар пользователя
mfcoder
 
Сообщений: 1531
Зарегистрирован: 29 июл 2013, 11:55
Средств на руках: 26.85 Доллар
Группа: Базовая
Благодарил (а): 78 раз.
Поблагодарили: 423 раз.

Re: Философия MQL4

Сообщение mfcoder » 02 авг 2013, 18:58

Продолжим тему.. надеюсь меня простят за своевольную в некоторых случаях терминологию, и также рассчитываю на то, что выше изложенное более или менее понятно..

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

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

[*] целые (int) - числа в диапазоне -2147483648 до 2147483647

[*] логические (bool) - принимают значения true или false

[*]литералы (char) - одиночный символ заключенный в одинарные кавычки, например, 'a', внутреннее представление данного типа это число в диапазоне от 0 до 255

[*]строки (string) - последовательность символов заключенная в кавычки, например, "привет"

[*]с плавающей точкой (double) - иначе говоря дробные числа, например, 1.5

[*]цвет (color) - цвет может задаваться различными способами:
// в виде литералов
C'128,128,128' // серый
C'0x00,0x00,0xFF' // синий
//в виде названий цветов
Red // красный
Yellow // желтый
Black // черный
// в виде целочисленного представления
0xFFFFFF // белый
16777215 // белый
0x008000 // зеленый
32768 // зеленый

[*]дата и время (datetime) - этот тип также может быть представлен в разных видах, внутреннее представление этого типа это число - количество секунд отсчитанное от 0:00 1 января 1970 года
//в виде литералов
D'2004.01.01 00:00' // Новый Год
D'1980.07.19 12:30:27'
D'19.07.1980 12:30:27'
D'19.07.1980 12' //равнозначно D'1980.07.19 12:00:00'
D'01.01.2004' //равнозначно D'01.01.2004 00:00:00'
D'12:30:27' //равнозначно D'[дата компиляции] 12:30:27'
D'' //равнозначно D'[дата компиляции] 00:00:00'
//в виде числа
1213124132 //равнозначно 2008.06.10 18:55:32

разнообразие представление двух последних типов данных сделано для удобства, т.к. цвет/датаВремя может рассчитываться математически и тогда его удобно в виде числа задавать, через интерфейс, конечно, же удобнее задавать, когда цвета представлены в виде названий, а время в виде формата 'ГГГГ.ММ.ДД чч:мм:сс'
Аватар пользователя
mfcoder
 
Сообщений: 1531
Зарегистрирован: 29 июл 2013, 11:55
Средств на руках: 26.85 Доллар
Группа: Базовая
Благодарил (а): 78 раз.
Поблагодарили: 423 раз.

Re: Философия MQL4

Сообщение mfcoder » 04 авг 2013, 00:56

Использование переменных.

В программировании имеются два часто используемых понятия это объявление переменной и ее инициализация.
Что такое объявление переменной?
Это декларация переменной в форме [идентификатор имяПеременной;], где символ ";" (точка с запятой) означает оператор завершения выражения
Код: выделить все
//примеры объявлений переменных
int i;
bool b;
string s;
double d;
color col;
datetime date;


Что такое инициализация?
Это присвоение переменной первоначального значения. В вышеприведенном примере переменным значения не присваиваются, однако при компиляции программы компилятор автоматически всем переменным присвоит начальные значения, такое присвоение значений компилятором имеет название присвоение значений по умолчанию.
Соответственно, всем переменным будут присвоены следующие значения
Код: выделить все
//примеры инициализации переменных
i = 0;
b = false;
s = "";
d = 0.0;
col = CRL_NONE; // отсутствие цвета, т.е. это цвет фона окна с графиком
date = 0; //соответствует, 01.01.1970 0:00


Далее поговорим об основных манипуляциях с переменными.
1. выражения - это изменения значений переменных (инициализации, арифметические операции и т.п.), запись выражений заканчивается оператором ";"
например,
Код: выделить все
a = 1;
b = (a + 1) / 3;

2. арифметические операции
тут все просто,
Код: выделить все
x = x + y; // увеличение числа на y или такой вариант записи x += x;
x = x - y; // уменьшение числа на y или такой вариант записи x -= x;
x = x * y; // увеличение числа в y раз или такой вариант записи x *= x;
x = x / y; // уменьшение числа в y раз или такой вариант записи x /= x;


для деления стоит уточнить такой момент, что если производится деление целых чисел (тип int), то производится округление до целых чисел путем отбрасывания дробной части, например,
Код: выделить все
int a = 18;
int b = 10;
int c = 3;
double e = a / b * c;


Возникает вопрос каким будет результат ?
Если посчитать, то вроде как должно получиться 5.4, но с учетом того, что переменные имеют тип int, то результат будет 3. Чтобы математика была "правильной" нужно использовать тип double, по крайней мере один из участников деления должен иметь тип double. Суть в том, что когда числа делятся будучи int типом получается 1.8 и после округления имеем 1, а далее понятен результат.

Бывает, что программа так устроена, что типы нельзя поменять, т.е. значения в данном случае переменных a, b и c возвращаются какими-то функциями и их переделка проблематична. В таком случае можно сделать ход конем и добавить лишний множитель, который позволит выполнить правильный расчет
Код: выделить все
double e = [b]1.0[/b] * a / b * c;


кроме четырех основных операций есть еще получение остатка от деления для этого используют оператор %, а выглядит это так
Код: выделить все
a = 5 % 2; // имеем результат 1

данная операция производится только над целыми числами (int)

инкрементация и декрементация, т.е. увеличение/уменьшение значения на единицу
Код: выделить все
i++;// эквивалентно i = i + 1;
i--;// эквивалентно i = i - 1;


3. Операции отношения
Код: выделить все
Истина, если a равно b                       a == b;
Истина, если a не равно b                    a != b;
Истина, если a меньше b                      a < b;
Истина, если a больше b                      a > b;
Истина, если a меньше или равно b            a <= b;
Истина, если a больше или равно b            a >= b;


4. Логические операции
логическое отрицание (!) применимо только к булевым переменным
Код: выделить все
bool a = true;
bool b = !a; // false


логическое или (||) возвращает истину если хотя бы одно из условий истина, в противном случае возвращает ложь
Код: выделить все
int a = 4;
bool b = false;
if (a > 5 || !b){
   Print("истина");
}


логическая операция и (&&) возвращает истину только в случае, если все условия в выражении истина
Код: выделить все
int a = 4;
bool b = false;
if (a >= 3 && !b){
   Print("истина");
}


Ну и пару слов о переменных используемых в качестве параметров функции и видимости переменных в коде.
Как уже писалось ранее внешние (extern) и глобальные (те, что объявляются вне функций) переменные доступны из любого места в программе.

Возможные казусы программирования:
Имена переменных глобальной в внутренней (по отношению к функции) одинаковы к чему это может привести ?
Код: выделить все
int period = 10; // глобальная переменная

int start(){
   int a = get();
   Print(a);
}
int get(){
   int period = 0; // локальная переменная
   return(period * 3);
}


Зачастую при больших объемах кода ненарочно внутри функций создаются одноименные глобальным переменные.
Хотя по смыслу подразумевалось использование именно глобальных, что приводит к возможным ошибкам. Или например, такое чаще бывает, когда пишешь сначала тестовую функцию, а потом некоторые внутренние параметры функции выносишь в глобальные переменные и случайно забываешь удалить локальные. И вроде рассчитываешь что должны использоваться уже глобальные и смотришь на результат, а он совсем не тот, хотя ошибки явной нет.

Более интересен другой пример
Код: выделить все
int period = 10; // глобальная переменная

int start(){
   int a = get(period);//тут передается значение 10
   Print(a);//возвращено значение 30
   Ptint(period);//  <---------------------- а здесь все равно 10 ?!
}
int get(int period){//пришло 10
   period *= 3;//увеличили
   return(period);//вернули 30
}


Нередко бывает такая конструкция, что в функцию передается параметр (глобальная переменная), а в самой функции имя параметра совпадает с именем глобальной переменной и тут возникают логические казусы, т.к. разработчик ожидает, что переменная должна измениться и при принте переменной period в функции start() имеет не изменившееся значение. И такая ситуация зачастую становится непонятной в силу того, что в разных языках такие вещи обрабатываются по разному.

В данном случае в функции get() входной параметр - int period, является локальной переменной для самой функции, и поэтому чтобы мы не делали с ней внутри функции, то все это и останется внутри нее. А правильнее говорить, что параметр в функцию передается по значению, что означает, что в функцию передается копия исходного значения, что в свою очередь подразумевает, что эта копия хранится в другой "ячейке" памяти нежели оригинал, и естественно, ее изменение не может никак влиять на оригинал, с которого эта копия взята.

На тот случай, если нужно чтобы в место вызова, в данном случае это функция start(), возвращалось измененное значение передаваемого в функцию параметра, то значение в функцию нужно передавать по ссылке, что означает передачу оригинальной ссылки на "ячейку" памяти, т.е. все изменения внутри функции будут сохранены. Чтобы передавать значение по ссылке нужно в объявлении переменной period в функции get() добавить символ амперсанта.

Код: выделить все
int get(int[b]&[/b] period){
   period *= 3;
   return(period);
}


Понятие необязательных переменных.
В функциях могут быть необязательные параметры, которые можно не передавать. Например, для работы с ценами очень часто (почти всегда) следут использовать нормализацию цен. О чем тут речь? Цена любого инструмента имеет фиксированное число знаков после запятой, и если мы каким-либо образом вычисляли цену, а иногда даже беря текущую цену, получали лишние знаки, то такую цену - ненормализованную, т.е. не приведенную к правильному значению знаков после зяпятой нельзя использовать для торговых операций, т.к. бeдет выдана ошибка.

Так вот, для нормализации значений есть функция NormalizeDouble(), которая имеет два параметра - значение, которое нужно нормализовать и количество знаков, до которых нужно произвести нормализацию. На основе этой функции можно слделать свою функцию специально для нормализации цен.
Код: выделить все
double N(double value, int digits=Digits){
return(NormalizeDouble(value, digits));
}


Обратите внимание на то, как задан второй параметр int digits=Digits что означает эта запись ?
Во-первых Digits - это системная константа, которая выдает количество значков после запятой для текущего инструмента, т.е. тот инструмент, на котором исполняется код во-вторых, запись int digits=Digits, говорит о том, что этот параметр необязателен, что это значит ?
Это значит, что можно вызывать эту функцию как со вторым параметром, так и без него, при этом если функция вызывается без параметра, то внутри функции переменная digits инициализируется значением по умолчанию, которое равно Digits.

Возьмем для примера инструмент EURUSD на "четырехначной" платформе у него четыре знака после зяпятой, таким образом имеем
Код: выделить все
double price = 1.33333333333333;
double n = N(price, 8); // нормализуем до восьми знаков после запятой, т.е. имеем 1.33333333
double n = N(price);    // нормализуем до Digits знаков после запятой, т.е. до 4-х знаков, имеем 1.3333
Аватар пользователя
mfcoder
 
Сообщений: 1531
Зарегистрирован: 29 июл 2013, 11:55
Средств на руках: 26.85 Доллар
Группа: Базовая
Благодарил (а): 78 раз.
Поблагодарили: 423 раз.

Re: Философия MQL4

Сообщение mfcoder » 04 авг 2013, 13:07

В дополнение об использовании необязательных параметров следует кое-что еще добавить.
1. у функции все параметры могут быть необязятельными (впрочем функция может быть и вообще без параметров)
2. если у функции есть обязательные параметры, то необязательные всегда должны следовать за обязательными параметрами, иначе будет ошибка при компиляции кода.
3. если в функции имеется несколько необязательных параметров вы не можете использовать необязательные параметры в произвольном порядке, что я здесь имею в виду, т.е. вы не можете использовать, например, только второй необязательный параметр без использования первого, третий без использования двух предыдущих и т.д.
Например, у нас есть функция с несколькими необязательными параметрами

Код: выделить все
double func(double v1, double v2=0, int v3=0, string v4=""){
// что-то делаем
}


мы можем вызвать эту функцию несколькими способами и эти способы заявисят от числа передаваемых парамтеров, т.е.
Код: выделить все
a = func(1, 3, 4,"hello");// используя все параметры
a = func(1, 3, 4); // и далее используя все меньше и меньше необязательных парамтеров
a = func(1, 3,);
a = func(1);


Таким образом, мы не можем явно пропускать какие-то параметры, хотя некоторые языки такое позволяют и тогда вызов функции может выглядеть примерно так
Код: выделить все
a = func(1, , ,"hello");// т.е. пропущены 1 и 2-ой необязательные параметры


но в mql нет таких возможностей.
Аватар пользователя
mfcoder
 
Сообщений: 1531
Зарегистрирован: 29 июл 2013, 11:55
Средств на руках: 26.85 Доллар
Группа: Базовая
Благодарил (а): 78 раз.
Поблагодарили: 423 раз.

Re: Философия MQL4

Сообщение mfcoder » 11 авг 2013, 18:36

Продолжим познавать азы языка mql4..

На этом этапе мы поговорим об понятии оператора.
Что есть оператор - перефразируя учебник (коротко и просто) это заданный способ преобразования информации.
Какие бывают операторы, их не много, но все они постоянно используются. Это оператор присваивания, то бишь знак равно (=), суть его проста присвоить переменное некое значение. Как вы, надеюсь, помните присвоение значения переменной оканчивается символом точка с запятой (;) - это разделитель между простыми операторами. Присвоение это простой оператор, но имеются и составные операторы, к ним относятся if, for, while, switch. Разберем для чего они предназначены.

Условный оператор if-else, работает он так, если выражение истина, то выполняется оператор1, иначе оператор2
if( выражение истина)
оператор1
else
оператор2

например,
Код: выделить все
if (a > 0)
  Print("больше ноля");
else
  if (a < 0 )
    Print("меньше ноля");
  else
    Print("ноль");


Отступим на шаг в сторону, глядя на запись в такой форме можно не сразу понять что вообще должно произойти, т.к. сочетания if и else условий дают запутанную картину, иногда некоторые умельцы все это дело могут загнать вообще в одну строку и тогда читабельность кода сводится к нулю. Для того чтобы код был читаемым его разбивают на блоки с помощью парных символов - фигурные скобки ({}), т.е. имеем следующее

Код: выделить все
if (a == 1){
  Print("один");
} else {
  if (a == 2 ){
    Print("два");
  } else {
    Print("что-то еще");
  }
}


таким образом, получаем более читабельный код
например, данный фрагмент можно преобразовать и использовать с помощью оператора switch(), суть оператора это переключатель, т.е. имея на входе параметр, по его значению выполнять определенное действие
Код: выделить все
switch(a){
  case 1:
    Print("один");
    break;
  case 2:
    Print("два");
    break;
  default:
    Print("что-то еще");
}


В данной конструкции используется оператор break - его предназначение это прерывание действий и выход из составного оператора (switch, for или while).
Стоит заметить, что если в case 1, удалить оператор break, то при значении а = 1, произойдет выполнение операторов в case 1 и case 2, т.е. раз нет выхода, произойдет переход к нижеследующему case и так далее, если в них нет break-операторов выхода из оператора switch.
Аватар пользователя
mfcoder
 
Сообщений: 1531
Зарегистрирован: 29 июл 2013, 11:55
Средств на руках: 26.85 Доллар
Группа: Базовая
Благодарил (а): 78 раз.
Поблагодарили: 423 раз.

Re: Философия MQL4

Сообщение mfcoder » 11 авг 2013, 19:08

Операторы цикла for и while.
В целом они позволяют обрабатывать информацию в цикле, но имеют разные параметры.
Например, выполняем цикл, пока счетчик не достиг 10
Код: выделить все
int count = 0;
while(count <= 10){
  Print(count);
  count++;// увеличиваем счетчик на единицу
}


используя цикл for это выглядело бы так
Код: выделить все
for( int count = 0; count <= 10; count++){
  Print(count);
}


как можете видеть for имеет более сложную структуру параметров - операторов, которые разделены точкой с запятой: до первой точки с запятой идет инициализация, т.е. здесь может быть более чем один параметр, которые должны быть разделены запятой, т.е. int count = 0, count2 = 0, count3 = 0;
Далее вторым оператором идет условие выполнения цикла в данном случаем - count <= 10, т.е. пока значение переменной count меньше или равно 10 цикл будет выполняться. Третьим параметром идет дополнительное выражение count++, которое увеличивает счетчик на единицу, в данной конструкции увеличение можно было бы внести внутрь цикла и не указывать третий оператор. В принципе все три оператора (выражения) не являются обязательными и вышеприведенный цикл for можно сделать более похожим к циклу while в данной конкретной функциональности так
Код: выделить все
int count = 0;
for( ;count <= 10; ){ // первый и третий операторы пусты
  Print(count);
  count++;
}


Также стоит упомянуть об операторе continue, который часто используется цикличных конструкциях, оператор предназначен для пропуска нижеследующего за ним кода и перехода к последующей итерации выполнения кода, что было понятнее приведу пример кода, который выводит четные числа
Код: выделить все
for(int count = 0; count <= 10; count++){
  if (count % 2 != 0){ // % - остаток от деления числа на 2, для всех четных это ноль
    continue; // пропускаем нечетные числа
  }
  Print(count);
}
Аватар пользователя
mfcoder
 
Сообщений: 1531
Зарегистрирован: 29 июл 2013, 11:55
Средств на руках: 26.85 Доллар
Группа: Базовая
Благодарил (а): 78 раз.
Поблагодарили: 423 раз.

Re: Философия MQL4

Сообщение mfcoder » 25 авг 2013, 19:57

здесь я коснусь немного о понятии массивов..

массив это контейнер, состоящий из одного или нескольких элементов одного типа, каждый из которого имеет свой индекс (т.е. это подобно строке ячеек в Excel, кто понимает о чем речь), т.е. запись string ar[20];
означает что мы имеем массив элементов строк, в котором количество ячеек/элементов равно 20, стоит заметить что элементы массива начинаются с 0 (это принято в большинстве языков программирования), обращение к элементам массива производится по их индексам, т.е. ar[0], ar[1] - получить значение 0, 1-го элемента и т.д.

массивы могут быть одномерными и многомерными, т.е.
int a[5]; // одномерный массив с 5-ю элементами
int b[2][5]; // двумерный массив с 10-ю элементами, условно говоря это таблица, где 2 строки по 5 элементов
int c[3][2][5]; // трехмерный массив с тридцатью элементами, условно такую конструкцию можно представить как кубик (параллелепипед) со сторонами 3, 2 и 5 ячеек, если удобнее представлять в таблицах, то это 3 таблицы 2 на 5

в mql максимум возможно 4 размерности, как представить для себя модель с 4-мя измерениями придумайте сами, я редко пользуюсь-то и двумя, бывает тремя, но ни разу четырьмя..
Аватар пользователя
mfcoder
 
Сообщений: 1531
Зарегистрирован: 29 июл 2013, 11:55
Средств на руках: 26.85 Доллар
Группа: Базовая
Благодарил (а): 78 раз.
Поблагодарили: 423 раз.


Вернуться в MQL – теория и практика

Кто сейчас на форуме?

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 64

Права доступа к форуму

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения