Видеоуроки по программированию на MQL5

 

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

Благодаря структурированным обучающим видеоматериалам по MQL5, его освоение теперь становится проще и доступнее.

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

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

  • Практические примеры на практике
    Одно из ключевых преимуществ обучающих материалов по программированию на MQL5 - это акцент на практических примерах на практике. Вместо того чтобы просто представлять теоретические концепции, эти уроки часто предоставляют фрагменты кода и реальные сценарии для демонстрации того, как работает MQL5 на практике. Учащиеся могут следовать за примерами, реализовывать код и видеть немедленные результаты. Такой опытный подход укрепляет понимание, поскольку учащиеся получают первоначальный опыт написания кода на MQL5 и видят его работу в MetaTrader 5.

  • Учеба с акцентом на приложениях
    Обучающие материалы по программированию на MQL5 часто ориентированы на разработку конкретных торговых инструментов, таких как советники (EAs), настраиваемые индикаторы и скрипты. Сосредоточившись на практическом применении, учащиеся могут понять, как MQL5 может быть прямо использован для улучшения торговых стратегий и принятия решений. Такой учебный подход, ориентированный на приложения, позволяет трейдерам решать свои уникальные задачи и разрабатывать инструменты на заказ, соответствующие их торговым предпочтениям.

  • Обширный охват функций MQL5
    Лучшие учебные материалы по программированию на MQL5 стремятся охватить широкий спектр функций и возможностей MQL5. Эти уроки обычно изучают такие темы, как объектно-ориентированное программирование (OOP), выполнение торговых операций, работа с техническими индикаторами, интеграция внешних библиотек и многое другое. Благодаря всеобъемлющему подходу учащиеся получают представление о разнообразных возможностях MQL5 и развивают полное понимание его потенциала для применения в алгоритмической торговле.

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

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

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

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

Документация по MQL5: Технические индикаторы
Документация по MQL5: Технические индикаторы
  • www.mql5.com
Технические индикаторы - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 

MQL5 для чайников - Урок 1: Редактор кода, События, устройство mql5 программ


MQL5 для чайников - Урок 1: Редактор кода, События, устройство mql5 программ

Приветствую вас, друзья! Эта серия уроков предназначена для новичков, которые никогда не пытались учиться программировать, а также для тех, кто уже имеет опыт в программировании, особенно на языке С или MQL4. Эти уроки будут довольно простыми, так как MQL5 - объектно-ориентированный язык программирования, в котором можно оперировать различными сложными типами данных, такими как классы. Он сильно похож на C++, но в MQL5 по сравнению со старой четвертой версией присутствует больше обработчиков событий и событий в целом, что позволяет писать более сложные алгоритмы.

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

MQL5 - узкоспециализированный язык, который нацелен на написание торговых стратегий, индикаторов и скриптов для торговли. Код пишется в специальном редакторе MetaEditor. Попав в этот редактор, можно создавать и редактировать исходный код различных программ, таких как индикаторы, скрипты и советники. В редакторе можно компилировать уже написанный код, запускать отладку и обращаться к встроенной помощи.

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

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

Чтобы использовать программу, её необходимо скомпилировать. Для этого можно нажать кнопку F7 или кнопку "Компилировать" на панели редактора кода. При компиляции отображается информация об использованных библиотеках и возможные ошибки. После успешной компиляции программа появляется во вкладке "Советники" или соответствующей категории в окне навигатора, и её можно применить на графике.

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

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

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

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

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

У нас есть несколько типов таймеров, которые могут запускать наш таймер. Это может быть EventSetTimer() и EventSetMillisecondTimer(). Таймер может генерировать события раз в секунду или миллисекунду соответственно.

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

У нас также есть функция EventKillTimer(), которая уничтожает созданный таймер в терминале.

Следующий тип события, который может генерировать таймер, это OnTrade(). Этот метод вызывается при наступлении события trade, которое предназначено для обработки изменений в списках ордеров, позиций и сделок. Он вызывается только для экспертов в индикаторах и скриптах. Если добавить этот метод в другие функции, он будет проигнорирован.

Также есть метод OnTradeTransaction(), который вызывается при наступлении события trade transaction. Этот метод предназначен для обработки результатов выполнения торгового запроса. Когда торговый сервер возвращает результат выполнения запроса, запускается метод trade transaction.

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

Еще один метод - OnChartEvent(). Он вызывается в экспертах и индикаторах для обработки изменений на графике, вызванных действиями пользователя или программой MQL5.

Метод OnTester() вызывается в экспертах при наступлении события tester. Он используется для выполнения необходимых действий при окончании тестирования советника. Например, сохранение статистики тестирования или вывод дополнительных расчетов по статистике торговли.

Метод OnTesterPass() вызывается во время оптимизации советника. Он используется для обработки нового фрейма оптимизации, то есть запуска новой итерации оптимизации советника.

У нас остался последний метод OnTesterDeinit(). Он используется в тестировщике для запуска при окончании полной оптимизации советника. Давайте пройдемся по порядку работы. Когда мы добавляем советника на график и нажимаем кнопку "ОК", происходят события инициализации, а затем запускается следующий метод. Каждый раз, когда приходит новый тег, например, при изменении цены или удалении советника с графика, вызывается соответствующий метод.

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

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

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

Если мы выбираем оптимизацию, то перед каждым новым проходом вызывается метод в оптимизаторе, а при завершении вызывается метод после завершения оптимизации.

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

Есть также метод OnBookEvent(), связанный со стаканом цен, который вызывается при изменении объемов или цен ордеров.

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

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

Содержание

00:00 Введение

01:57 Редактор кода MetaEditor

06:39 Настройки MetaEditor

08:51 Отладка

10:44 Шапка программы mql5

11:26 События mql5

13:25 Функция OnInit

17:07 Функция OnDeinit

20:56 Комментарии

23:40 Функция OnTick

24:46 Функция OnTimer

26:58 Функция OnTrade

27:58 Функция OnTradeTransaction

29:21 Функция OnBookEvent

30:11 Функция OnChartEvent

30:32 Функция OnTester

31:00 Функция OnTesterInit

31:10 Функция OnTesterPass

31:28 Функция OnTesterDeinit

31:38 Порядок возникновения событий

36:48 Функция OnCalculate

37:00 Функция OnStart

37:54 Заключение

 

MQL5 для чайников - Урок 2: Типы переменных


MQL5 для чайников - Урок 2: Типы переменных

Приветствую вас, друзья, на втором уроке по языку MQL5! Сегодня речь пойдет о переменных. Вообще, переменные являются основой всех языков программирования. Независимо от алгоритма, который вы придумали, способа его реализации или языка программирования, используемого вами, все сводится к работе с переменными.

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

Давайте создадим переменную следующим образом:

char value_char;

Что говорит нам эта запись? Прежде всего, она обозначает конец оператора. Оператор может содержать одну или несколько операций. В данном случае у нас одна операция - объявление переменной типа "char" с именем "value_char".

Имена переменных в MQL5 могут состоять из латинских букв (в верхнем или нижнем регистре), цифр и знаков подчеркивания. Они не могут содержать служебные символы, такие как "=", ".", ":" и другие. Также имя переменной не может начинаться с цифры.

MQL5 унаследовал от C++ строгую типизацию переменных. При объявлении переменной под нее сразу выделяется определенный объем памяти, который зависит от типа данных, которые будут храниться в этой переменной. После задания типа переменной нельзя присвоить данные другого типа.

Теперь давайте рассмотрим доступные типы переменных в MQL5. На данный момент в языке есть числовые типы данных. Более подробную информацию можно найти в документации MQL5 в разделе "Основы языка" -> "Типы данных". В настоящее время у нас есть четыре типа целочисленных чисел: "char" (занимает один байт памяти, диапазон значений от -128 до 127), "short" (занимает два байта памяти, диапазон значений от -32,768 до 32,767), "int" (занимает четыре байта памяти, диапазон значений от -2,147,483,648 до 2,147,483,647) и "long" (занимает восемь байт памяти, диапазон значений от -9,223,372,036,854,775,808 до 9,223,372,036,854,775,807).

Кроме того, у нас есть тип "unsigned", который используется для беззнаковых значений. Например, для типа "unsigned char" минимальное значение равно 0, а максимальное значение равно 255. Этот тип удобно использовать для переменных, которые не могут быть отрицательными, например, для подсчета количества ордеров и позиций на торговом счете.

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

Если ваши алгоритмы выполняются не на вашем компьютере с несколькими гигабайтами оперативной памяти, а на некотором дешевом VPN-сервисе с всего двумя гигабайтами доступной памяти, где большая часть этих двух гигабайт занята операционной системой, а для терминала остается очень мало места, то чаще всего используются типы bool, float и double в MQL5.

Тип bool имеет только два значения: false (ложь) и true (истина). Он часто используется для хранения логических состояний, например, для флагов переключателей или проверки условий.

Типы float и double используются для хранения чисел с плавающей точкой. Тип float занимает 4 байта памяти и имеет максимальную точность до 24 знаков после запятой. Тип double занимает 8 байтов памяти и имеет максимальную точность до 53 знаков после запятой. Обычно тип double применяется чаще всего для работы с рыночными котировками, объемами сделок, значениями прибыли и убытков на счете и т.д.

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

В MQL5 также существует возможность комментирования кода. Комментарии могут быть однострочными, начинающимися с символа "//", или многострочными, заключенными между "/*" и "*/". Комментарии полезны для пояснения кода и его документирования.

Давайте мы всё вернём обратно. В принципе, вот по шагам возврат. Это из комбинации клавиш контр+z. Соответственно, я могу двигаться назад.

Следующий тип переменных - тип enum. Ну, это специальный собственный тип, который представляет из себя перечисления или именованные перечисления. Объявляется он не сложнее, чем другие переменные. Как видите, в данном случае записи говорят о том, что в перечислении 'вылю' содержится три пронумерованных члена, и к ним можно обратиться как по имени, так и по порядковым номерам.

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

Следующий тип данных - тип datetime. Этот тип данных содержит в себе дату и время, которые хранятся в виде количества секунд, прошедших с 0 часов 0 минут 1 января 1970 года. Для работы с этим типом данных, как с типом 'string', также предусмотрено множество различных функций. Ему также будет посвящен отдельный урок. При помощи переменных типа 'datetime', например, можно определять момент открытия нового бара или задавать время торговли или время перерыва в торговле.

Ну, и следующий тип данных - тип color. Собственно, тип 'color' содержит в себе описание цвета. Присваивать ему значения можно тремя разными способами. Для именованных цветов это можно сделать специальными заданными ключевыми словами. Например, цвет синий можно задать ключевым словом 'Blue'. В данном примере также можно присвоить переменной значение в виде трех десятичных чисел или писать цвет одним шестнадцатеричным числом. Но это далеко не всегда удобно, и мы здесь пишем советники для заработка денег, а не занимаемся дизайном.

Тип 'color' имеет смысл только для удобства представления и ввода параметров, задаваемых извне. Именно для этого они и были придуманы. В документации MQL5 вы можете найти название всех предопределенных веб-цветов, а также пользовательские типы переменных, такие как классы и структуры.

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

int a = 1, b = 2, c = 3;

Таким образом, переменные a, b и c будут равны 1, 2 и 3 соответственно.

Также можно присваивать переменной одного типа значение другого типа. Например:

int a = 10; string b = "Value: " + IntegerToString(a);

В данном случае происходит неявное приведение типов, и компилятор сам преобразует значение типа int в строку.

Теперь давайте сделаем наоборот. Давайте сделаем так, чтобы у нас был тип char, и тут мы увидим сообщение от компилятора о возможной потере данных из-за конвертации из типа float в тип char. В данном случае мы фактически лишаемся дробной части числа.

Давайте посмотрим, что у нас лежит в переменной d после компиляции и запуска нашего скрипта. Мы видим, что у нас переменная d лежит 0. Давайте исправим это и присвоим ей значение 5, например. Пусть будет 5.25, и запустим снова. Мы видим, что у нас в переменной d лежит 5, то есть мы лишились напрочь нашей дробной части. При этом у нас нет никакой ошибки, только предупреждения.

Теперь мы можем, если нам действительно нужно выполнить такую операцию, явно преобразовать наше значение типа float в тип char. В данном случае ошибка в компиляторе исчезнет, но при этом переменная d также будет иметь значение 5, то есть она отбросит дробную часть.

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

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

Например, если я задам какую-нибудь глобальную переменную global типа double здесь и помещу ее в метод Print() внутри функции. Давайте запустим наш скрипт, и мы увидим, что переменная global действительно равна 0.3. Переменная global у нас доступна только внутри этой функции.

Если мы создадим другую функцию, например, и попытаемся использовать там переменную global, то компилятор не даст нам скомпилировать наш код. При этом глобальная переменная доступна в любом участке кода.

Также я хотел бы затронуть тип input в нашем уроке. Модификатор input обычно указывается перед типом данных в начале. Значение переменной с модификатором input уже нельзя изменять внутри программы. Эти переменные доступны внутри программы только для чтения.

Тем не менее, значение input переменных может изменять пользователь при запуске программы. Например, в данном случае мы можем изменить значение переменной w при запуске эксперта через окно входных параметров. Для демонстрации, давайте найдем наш эксперт и поместим сюда input double w. Теперь при запуске эксперта в окне входных параметров мы увидим наш внешний параметр, который мы можем изменить.

Давайте для демонстрации установим значение 0.5. Жмем "OK" и видим, что наше значение отобразилось как 0.5.

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

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

Содержание

00:00 Введение. Именование переменных

03:30 Целые типы переменных char, short, int, long

05:14 Беззнаковые целые типы переменных uchar, ushort, uint, ulong

08:06 Целый тип bool

08:30 Переменные типа float и double

10:10 Строковые типы переменных

13:57 Строчные и блочные комментарии

15:30 Перечисления

16:24 Тип данных для хранения времени

17:06 Тип данных для хранения цветов

18:38 Пользовательские типы данных

19:18 Объявление типов переменных

24:02 Области видимости переменных

25:12 Модификатор Input

28:21 Заключение

 

MQL5 программирование: Операции и выражения


MQL5 программирование: Операции и выражения

Всем привет! Мы продолжаем изучать язык программирования MQL5, и сегодня мы познакомимся с операциями и выражениями. Давайте немного очистим то, что осталось после прошлого урока.

Итак, у нас есть три вспомогательные переменные. Самая основная и часто встречающаяся операция - операция присваивания. Она выглядит следующим образом: a = 10. В данном случае переменной a присваивается значение 10. После этого выражения значение переменной a становится равным значению переменной b, то есть числу 12. Давайте проверим это, выведем значение a с помощью Print, и убедимся, что у нас получилось число 12.

int a = 10; int b = 12; a = b; Print("a =", a);

Мы видим, что наша переменная a действительно стала равной 12.

Еще одна операция - это увеличение значения переменной. В данном случае мы увеличиваем значение переменной a на значение переменной b. Это можно записать как a += b. Если мы применим эту операцию к нашему примеру, у нас должно получиться число 22. Давайте проверим это на практике.

int a = 10;
int b = 12;
a += b;
Print("a =", a);

Как видим, у нас действительно получилось число 22.

Также у нас есть операция уменьшения значения переменной. В данном случае мы уменьшаем значение переменной a на значение переменной b, что можно записать как a -= b. Воспользуемся этой операцией и установим a равным 12, а b равным 10. Тогда результатом должно быть число 2.

int a = 12; int b = 10; a -= b; Print("a =", a);

Результат действительно равен 2.

Следующая операция - умножение значения переменной a на значение переменной b. В нашем примере a = 12, b = 10, поэтому результатом должно быть число 120.

int a = 12;
int b = 10;
a *= b;
Print("a =", a);

Результат действительно равен 120.

Также мы можем использовать операцию деления, записываемую как a /= b. В нашем примере результатом будет число 1.2.

double a = 12.0; double b = 10.0; a /= b; Print("a =", a); 

Результат действительно равен 1.2.

Еще одна операция, которую стоит упомянуть, - это получение остатка от деления (%). В нашем примере a = 10, b = 12. Давайте посмотрим, что у нас получится. Результатом будет число 10.

int a = 10;
int b = 12;
a %= b;
Print("a =", a);

Как видим, результат действительно равен 10.

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

Также есть побитовые операции, такие как побитовое И (&), побитовое ИЛИ (|) и побитовое исключающее ИЛИ (^). Они применяются к двоичным представлениям переменных a и b. Обычно побитовые операции используются только с целыми числами. В каждом выражении может быть только одна операция присваивания, то есть нельзя записать что-то вроде a = b = c.

Далее у нас есть операции отношения, которые также называются булевыми операциями. В языке MQL5 и во многих других языках логическое значение "ложь" представлено нулем, а значение "истина" - любым ненулевым значением. Мы можем использовать операции отношения для сравнения значений переменных. Например, если мы хотим проверить, равны ли a и b, мы можем записать a == b. В данном случае это будет истинное выражение, так как у нас a = b. Если мы хотим проверить, что a не равно b, мы можем записать a != b. В данном случае это тоже будет истинное выражение.

int a = 10; int b = 12; Print(a == b); // false Print(a != b); // true

Мы видим, что результаты сравнений соответствуют ожидаемым значениям.

Также у нас есть операции "меньше" (<), "больше" (>), "больше или равно" (>=) и "меньше или равно" (<=). Например, если мы хотим проверить, что a меньше b, мы можем записать a < b. В данном случае результат будет true.

Важно помнить, что при сравнении вещественных чисел не рекомендуется использовать операции "равно" (==) или "не равно" (!=) напрямую, так как они могут привести к ошибкам из-за погрешностей округления. Для корректного сравнения вещественных чисел рекомендуется использовать нормализованную разницу между значениями с нулевым значением.

Еще один тип операций - это арифметические операции. В языке MQL5 они работают аналогично операциям в школьной математике. Например, если мы хотим вычислить сумму двух переменных a, b и c, мы можем записать a = b + c. В данном случае переменная a будет содержать сумму значений b и c, то есть 12.3.

Также у нас есть операция вычитания (-), операция изменения знака (-a), операция умножения (*) и операция деления (/). Например, если мы хотим вычислить результат деления b на c, мы можем записать b / c. В данном случае результатом будет число 4.

Операцию получения остатка от деления мы уже рассмотрели ранее.

Еще две интересные операции - это операция увеличения переменной на единицу (++) и операция уменьшения переменной на единицу (--). Например, вместо записи a = a + 1 мы можем записать a++, и в результате переменная a станет равной 11.

Давайте проверим, правильно ли мы помним, что у нас есть кот, который исполняет программу слева направо. В данном случае функция Print вывела исходные значения, не успев прибавить единицу к нашей переменной A. Таким образом, в данном случае A будет равна 11, то есть с порядком исполнения кода нужно быть аккуратнее.

Теперь давайте рассмотрим операцию с двумя минусами после переменной. Эта операция вычитает единицу из переменной. В данном случае мы получим число 9.

Кроме того, мы можем записать эту операцию таким образом, что значения переменной не имеют значения, где мы ставим плюс и минус: B--. В данном случае эта запись не будет распознана компилятором. Когда плюс или минус стоят перед переменной, это не проблема. Последние две операции, плюс плюс и минус минус, не могут применяться в выражениях. Мы не можем написать что-то вроде B++ или C--. Такое выражение будет работать некорректно.

Теперь давайте рассмотрим логические операции. Для демонстрации создадим четыре переменные типа bool: B1 = True, B2 = False, B3 = True и B4 = False.

Первая операция, которую рассмотрим, это операция "не". В данном случае мы проверяем, равна ли переменная B1 значению переменной B1. Естественно, она равна, поэтому получим False.

То есть операция логического "не" означает, что если наши две переменные равны, мы получаем True; если они не равны, мы получаем False.

Давайте заменим B1 на B2 справа, и мы получим другой результат выполнения этой логической операции. В данном случае мы получим True, так как B1 действительно не равно B2.

Следующая логическая операция - "или". В данном случае мы создадим еще одну переменную, например, переменную X, и не будем ее инициализировать никакими значениями. X будет равно B1 или B2. B1 у нас True, B2 у нас False, поэтому мы получаем True. Логика этой операции такая: если хотя бы одна из наших переменных равна True, то и X у нас будет True. Если ни одна из этих переменных не равна True, то и X у нас будет False.

Давайте посмотрим на примере B2 и B4. У нас получается False, поэтому X также будет равно False.

Еще у нас есть логическая операция "и", то есть если B4 и B2 не равны True, то и X не будет равно True. В данном случае у нас получается False, поэтому X также будет False.

Мы также можем записывать более сложные операции, например: B1 и B3 или B2 или B4. В этом случае у нас также будет True.

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

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

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

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

 

MQL5 программирование: Операторы


MQL5 программирование: Операторы

Приветствую вас, друзья! Сегодня у нас четвертый по счету урок по языку программирования MQL5. Сегодня мы будем обсуждать операторы, которые являются основными элементами программы и контролируют способ и порядок обработки объектов.

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

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

Операторы, которые мы рассмотрим сегодня, включают операторы условия if и switch, а также циклы while и for. Они могут быть вложены друг в друга, создавая более сложные структуры.

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

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

Также у нас есть операторы вызова функций и оператор возврата. Оператор вызова функции состоит из имени функции с аргументами и заканчивается точкой с запятой. Оператор возврата прекращает выполнение текущей функции и возвращает результат вычисления выражения вызывающей программе.

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

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

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

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

 

MQL5 программирование: Математические функции и циклы


MQL5 программирование: Математические функции и циклы

Приветствую вас, друзья, на пятом уроке по языку MQL5! Сегодня мы поговорим о математических функциях. Дело в том, что написание любого советника не обходится без каких-то математических вычислений. Помимо простых операций типа умножения, деления, суммирования или вычитания, также часто приходится округлять числа, возводить их в степень, сравнивать и выполнять другие подобные операции.

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

Первая функция, о которой мы поговорим, называется "MathRound". Эта функция возвращает значение, округленное до ближайшего целого числа. Например, если у нас есть число 2.32, то при использовании функции MathRound мы получим число 2. Давайте проверим это:

double test = 2.32;
int roundedValue = MathRound(test);
Print("Результат округления: ", roundedValue);

Вывод: "Результат округления: 2"

Следующая функция называется "MathCeil". Этот метод округляет число до ближайшего целого числа сверху. Например, если у нас есть число 2.32, то при использовании функции MathCeil мы получим число 3. Давайте проверим:

double test = 2.32;
int roundedValue = MathCeil(test);
Print("Результат округления: ", roundedValue);

Вывод: "Результат округления: 3"

Следующий метод - "MathFloor". Он также округляет число до целого числа, но при этом у нас будет ближайшее число снизу. Давайте посмотрим на примере:

double test = 2.32; int roundedValue = MathFloor(test); Print("Результат округления: ", roundedValue);

Вывод: "Результат округления: 2"

А что делать, если мы хотим округлить число до определенного разряда, например, до двух знаков после запятой? К сожалению, в языке MQL5 нет встроенной функции для этого, но мы можем использовать MathRound, но при этом умножить число на 100 и разделить уже результат выполнения функции на 100. Таким образом, мы округлим число до двух знаков после запятой. Давайте посмотрим на примере:

double test = 2.3256;
double roundedValue = MathRound(test * 100) / 100;
Print("Результат округления: ", roundedValue);

Вывод: "Результат округления: 2.33"

Теперь представим такую гипотетическую ситуацию: нам нужно выбрать из двух чисел (например, переменные test1 и test2) наибольшее число и использовать его дальше в коде нашего советника. Для этого мы можем использовать функцию "MathMax". Она принимает два числа и возвращает максимальное из них. Давайте проверим:

double test1 = 2.5; double test2 = 3.8; double maxValue = MathMax(test1, test2); Print("Максимальное значение: ", maxValue);

Вывод: "Максимальное значение: 3.8"

Аналогично, для поиска минимального числа существует функция "MathMin". Она принимает два числа и возвращает минимальное из них. Давайте посмотрим на пример:

double test1 = 2.5;
double test2 = 3.8;
double minValue = MathMin(test1, test2);
Print("Минимальное значение: ", minValue);

Вывод: "Минимальное значение: 2.5"

Довольно удобный метод - "MathMod". Эта функция возвращает вещественный остаток от деления двух чисел. Например, если мы разделим 5 на 2, то получим остаток 1. Давайте посмотрим на пример:

double result = MathMod(5, 2); Print("Остаток от деления: ", result);

Вывод: "Остаток от деления: 1"

Есть еще две функции, которые часто используются для исследований в области управления капиталом и тому подобного. Это функции "MathRand" и "MathSrand".

Функция "MathRand" возвращает случайное целое число в заданном диапазоне. Например, чтобы получить случайное число от 0 до 32767, мы можем использовать:

int randomNumber = MathRand();
Print("Случайное число: ", randomNumber);

Вывод: "Случайное число: <рандомное число>"

Каждый раз при обращении к функции "MathRand" будет возвращаться новое случайное число.

Если мы хотим получать всегда одну и ту же последовательность случайных чисел, мы можем использовать функцию "MathSrand" и передавать ей какое-то одно определенное число. Например:

MathSrand(4); int randomNumber = MathRand(); Print("Случайное число: ", randomNumber);

Вывод: "Случайное число: 51"

Таким образом, результаты генератора случайных чисел будут всегда одинаковыми при использовании той же самой последовательности. Это может быть полезно в определенных ситуациях. Если вам не нужно такое поведение, просто не используйте функцию "MathSrand" перед вызовом "MathRand"

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

Следующие методы используются гораздо реже. Например, один из них - "MarkX". Этот метод возвращает значение числа e в степени d. В данном случае степень равна 4, поэтому результатом будет 54.59 и так далее.

Еще один метод - "MoreFlag", возвращает натуральный логарифм. Также есть специальный метод, который возвращает логарифм числа по основанию 10.

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

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

Теперь давайте перейдем к циклам. Один из наиболее часто используемых циклов - это цикл "for". Он записывается следующим образом:

for(int i = 1; i < 10; i++){
    Print("Значение i: ", i);
}

В данном примере цикл будет выполняться 9 раз, так как переменная "i" увеличивается на каждой итерации от 1 до 9.

Еще один оператор цикла - "while". Он записывается следующим образом:

int i = 1; while(i < 10){ Print("Значение i: ", i); i++; }

В данном случае цикл будет выполняться, пока значение переменной "i" будет меньше 10. Код внутри цикла будет выполняться, и после каждой итерации значение "i" будет увеличиваться на 1.

В циклах также можно использовать операторы "break" и "continue". Оператор "break" прерывает выполнение цикла и переходит к следующей инструкции после цикла. Оператор "continue" прерывает текущую итерацию цикла и переходит к следующей итерации.

Также есть конструкция "do-while". Она выглядит следующим образом:

do{

    // Код
}while(file < 100);

Эта конструкция эквивалентна предыдущей записи с "while" и обеспечивает выполнение кода, пока условие выполняется.

Вот и все на сегодня. Мы рассмотрели математические функции, циклы и на следующем уроке поговорим о массивах и их обработке. Удачи!

Содержание

00:00 - Вступление

00:48 - Функции округления

01:20 - Функция MathRound

02:10 - Функция MathCeil

02:30 - Функция MathFloor

02:50 - Округление до определенного разряда

04:25 - Функция MathMax

05:10 - Функция MathMin

05:20 - Функция MathMod

06:50 - Функция MathPow

07:20 - Функция MathSqrt

07:50 - Функция MathRand

09:15 - Функция MathSrand

10:40 - Функция MathExp

11:10 - Функция MathLog и MathLog10

11:25 - Функции MathTan, MathSin, MathCos, MathArcsin, MathArccos, MathArctan

12:35 - Оператор цикла For

14:30 - Оператор цикла While

16:25 - Оператор break

16:45 - Оператор continue

17:25 - Оператор do while

18:50 - Заключение

 

MQL5 программирование: Массивы


MQL5 программирование: Массивы

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

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

Массив может быть одномерным или многомерным. Одномерный массив - это совокупность однотипных данных. Например, у нас может быть объявлен одномерный массив из 50 целых чисел типа int. Многомерный массив состоит из одномерных массивов. Например, у нас может быть двумерный массив, состоящий из 7 одномерных массивов, каждый из которых состоит из 50 чисел.

Для создания массива используются квадратные скобки. Число в скобках указывает количество элементов в массиве. Нумерация элементов всегда начинается с 0. Последний элемент одномерного массива имеет номер на единицу меньше размера массива. То есть, если у нас есть одномерный массив из 50 элементов, то последний элемент будет иметь индекс 49.

Для доступа к элементам массива используется индексация. Индекс массива - это целое число. В языке MQL5 допускаются не более четырехмерные массивы. Индексация элементов производится от 0 до размера измерения - 1.

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

Для получения значения конкретного элемента достаточно обратиться к массиву по его индексу. Например, myArray[0] будет равно первому элементу массива, myArray[1] - второму и так далее.

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

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

Давайте скомпилируем и запустим нашу программу и будем использовать принты, чтобы они не мешали нам. Как видим, в нашем массиве 5 нулей. В данном случае ошибки не возникают, так как в нашем массиве пять элементов.

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

Мы также можем задавать конкретные значения каждому элементу массива. Для этого используем инициализацию массива, например: int myArray[5] = {3, 12, 50, 45, 785};. Проверим, и действительно у нас все 5 элементов массива были инициализированы этими значениями.

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

Еще у нас есть функция ArrayCopy(), которая копирует содержимое одного массива в другой. Попробуем скопировать содержимое массива 3 в массив 4 и выведем его на печать. Как видим, содержимое массива 4 теперь такое же, как у массива 3.

Мы также можем сравнивать массивы одинакового типа с помощью функции ArrayCompare(). Проверим массивы 3 и 4. Они у нас одинаковые, и функция вернула 0.

Для заполнения массива одним значением можно использовать функцию ArrayFill(). Эта функция заполняет определенный диапазон массива заданным значением. Попробуем заполнить пять элементов массива числом 99 и выведем его на печать.

Есть также функции, которые позволяют проверить тип массива. Например, функция ArrayIsDynamic() проверяет, является ли массив динамическим или статическим. Попробуем проверить массив 4 - он действительно динамический.

Также есть функция ArrayIsSeries(), которая проверяет, является ли массив временной серией. Наш массив не является временной серией, и функция вернула false.

Мы можем также находить максимальное и минимальное число в массиве с помощью функций ArrayMaximum() и ArrayMinimum(). Попробуем найти максимальное и минимальное число в третьем массиве. Максимальное число - 785, а минимальное - 3.

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

Содержание

00:00 Вступление

00:14 Что такое массив

01:42 Доступ к элементам массива

03:32 Инициализация массива

05:56 Доступ к несуществующим элементам массива

07:03 Функция ArrayResize

07:48 Статические и динамические массивы

08:07 Функция ArrayInitialize

10:14 Функция ArraySize

10:28 Изменение значений элементов массива

11:15 Функция ArrayPrint

11:55 Функция ArrayCopy

13:40 Функция ArrayCompare

14:10 Функция ArrayFill

15:07 Функция ArrayIsDynamic

15:30 Функция ArrayIsSeries

15:45 Функция ArrayMaximum/ArrayMinimum

16:45 Заключение

 

MQL5 программирование: Функции


MQL5 программирование: Функции

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

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

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

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

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

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

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

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

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

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

Мы говорим, что наша функция ничего не возвращает. Давайте теперь вернемся к функции "myfunction". Ну, давайте поменяем тип "вдобавок" на "integer" и поговорим о том, что параметры, которые передаются функции, могут иметь значение по умолчанию, которые задаются константами соответствующего типа. А может быть, и не заданы параметры, значению по умолчанию. В данном случае давайте зададим параметру "b" значение по умолчанию. Пусть еще будет у нас "integer r" равный 5. "p" не знаю, пусть будет равно true по умолчанию, и "s" равно "абракадабра". Вот, дальше давайте мы распечатаем все наши параметры в данном случае у этой функции. Обязательным для задать параметром является параметр "a", потому что у него нет значения по умолчанию. Все остальные параметры при вызове функции можно не указывать, но при этом они будут принимать значения наших параметров по умолчанию. Вроде все.

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

Давайте вернем, например, в данном случае у нас не выражение, поэтому скобки ставить не нужно. Если у нас это число или какая-то единственная переменная, вот, можно переменной "res" вернуть, либо ноль. Так, скомпилируем, и давайте теперь запустим этот скрипт в нашем MetaTrader, который уже был прикреплен к графику, и соответственно, он распечатал все наши значения. То есть это значение "а", которое мы передали непосредственно функции, 34 и 2023, и все остальные параметры, как вы видите, приняли значение по умолчанию. Если мы через запятую зададим еще параметр "p", например, и параметр "n" у нас будет 8, то соответственно, после компиляции мы увидим, что действительно наши параметры, которые мы передали функции, приняли новые значения 0, 2 и 8. Кроме того, у нас функция с типом "integer" и соответственно она что-то возвращает. Поэтому мы создадим новую переменную "result", например, которая будет принимать значение, которое возвращается из нашей функции, и его заодно тоже распечатаем, чтобы убедиться, что это действительно так работает. И как мы видим, у нас возвращается последним принтом ноль.

Теперь по поводу вот этих параметров с значением по умолчанию пара замечаний. Например, вот такое объявление будет неправильно, и соответственно, мы получим в компиляторе ошибку, что мы пропустили значение по умолчанию для параметра "n". Как мы видим, если мы поменяем местами, то у нас все будет хорошо. Единственное, а тут у нас "integer" должен быть, то есть 7, и там 8 и 3, например, вот в данном случае никаких ошибок мы в компиляторе не увидим. То есть все параметры, у которых нету дефолтных значений по умолчанию, мы пишем в начале, а все параметры, у которых значение по умолчанию предполагается, мы пишем в конце. И соответственно, важно не нарушать порядок следования этих параметров. То есть, если мы зададим "а" и "n", то мы уже не можем задать только "с", нам придется задавать значение и для параметров "b" и "r".

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

Дело в том, что существуют два метода, с помощью которых машинный язык может передавать аргументы под программе. То есть функция, первый способ - это передача параметра по значению, это как раз именно то, что мы вот делали в наших предыдущих примерах. Собственно, этот метод копирует значение аргумента, который передается в функцию, функции в формальный параметр, функция, то есть в "a", "b" и так далее. Поэтому любые изменения этого параметра внутри функции не имеют никакого влияния на соответствующий аргумент вызова. То есть давайте мы это проверим, к примеру, мы зададим переменную "one", какой-нибудь, например, так. Это должен быть тип "double". "one" равно 0.32.

И собственно первым аргументом будем передавать "one". Дальше мы внутри этой функции, "a" один, точнее, "a" он уже "a" равно "a + 1", то есть единичка мы прибавим. Вот дальше мы выведем эту переменную "a" принтом, и здесь ниже мы тоже, уже когда все у нас уже работает, тоже выведем эту переменную нашу принтом, и посмотрим, что у нас получилось. Как мы видим, внутри функции у нас действительно к нашей переменной, к нашему параметру прибавилось единичка, то есть у нас 1.32. Но когда мы печатаем то, что мы в эту функцию передали, вот эту переменную, она так и осталась 0.32, то есть все, что внутри функции, все эти параметры, изменяемые внутри функции, они будут все эти изменения действительны в рамках этой функции.

Даже если бы я назвал этот параметр не "one", а "а", то эффект был бы точно таким же. Здесь "132", а здесь все же осталась "032". Нужно быть внимательным к этому. Так вот, я быстро написал еще одну функцию "malfunction2". И здесь, как мы видим, перед нашими параметрами, после того, как мы объявили тип параметра и перед тем, как мы объявили название параметра, мы поставили такой значок амперсанда. Дело в том, что есть еще один способ передачи аргументов в функцию, и это передача по ссылке. В этом случае ссылка на параметр, то есть именно ссылка на параметр, передается в функцию.

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

Давайте проверим это сейчас, скомпилируем и посмотрим, что у нас случилось. И действительно, "а" и "b" перед вызовом у нас были 14 и 8, а "а" и "b" после вызова - 28 и 4. Соответственно, они изменились не только внутри функции, но и глобально. Приходится передавать параметры именно по ссылке, чтобы исключить возможность изменения фактических параметров, которые передаются при вызове функции. Чтобы исключить изменение содержимого переменной, объявленной с модификатором const, при попытке изменить содержимое такой переменной, компилятор выдаст предупреждение.

Перегрузка функций - это создание нескольких функций с одним именем, но с разными параметрами. Это позволяет использовать различные функции для одних и тех же целей. В данном примере у нас есть функция "averageFromArray", которая вычисляет среднее значение массива чисел типа double, и функция "averageFromArray", которая вычисляет среднее значение массива чисел типа integer. Компилятор выбирает нужную функцию в зависимости от типов и количества аргументов, которые мы передаем функции. Проверим это, и действительно, в первом случае мы получили среднее значение 3, а во втором случае 3.3.

Содержание

00:00 - Вступление

00:49 - Зачем нужны функции

02:23 - Определение функции

03:46 - Прототип функции

05:55 - Функции с типом void

07:33 - Параметры функции по умолчанию

14:03 - Передача параметров по значению

16:30 - Передача параметров по ссылке

19:41 - Перегрузка функций

22:26 - Заключение

 

MQL5 программирование: Дата и Время (datetime)


MQL5 программирование: Дата и Время (datetime)

Привет всем! Мы продолжаем изучать MetaTrader 5 с нуля, и сегодня у нас будет интересный и разнообразный урок. Мы поговорим о дате и времени, а также коснемся понятия макроподстановок и познакомимся со структурами данных.

В MetaTrader 5 для хранения даты и времени используется специальный тип данных - datetime. Этот тип предназначен для хранения даты и времени в виде количества секунд, прошедших с 1 января 1970 года. Он занимает 8 байт в памяти и по своей сути является типом "integer" для времени.

В MetaTrader 5 выделен отдельный тип переменной для времени datetime. Таким образом, мы можем записать нашу переменную следующим образом:

datetime myDateTime;

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

datetime myDateTime = D'2023.06.30 10:15:30';

Диапазон значений даты и времени может быть от 1 января 1970 года до 31 декабря 3000 года. При задании можно опустить либо дату, либо время. Например, можно записать только время или только дату:

datetime onlyTime = D'10:15:30'; datetime onlyDate = D'2023.06.30';

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

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

  • __DATE__ - дата компиляции файла без времени.
  • __DATETIME__ - дата и время компиляции файла.
  • __LINE__ - номер строки в исходном коде, где расположен данный макрос.
  • __FILE__ - имя текущего компилируемого файла.
  • __PATH__ - абсолютный путь к текущему компилируемому файлу.
  • __FUNCTION__ - имя функции, в теле которой расположен данный макрос.
  • __FUNCSIG__ - сигнатура функции, в теле которой расположен данный макрос.
  • __MQLBUILD__ и __MQL5BUILD__ - номер сборки компилятора.

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

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

Print("Line: ", __LINE__);
Print("File: ", __FILE__);
Print("Function: ", __FUNCTION__);

Также в языке MQL5, помимо типа datetime, дата может храниться в структуре. Структура - это набор элементов произвольного типа, объединенных логически. Для хранения даты и времени в MQL5 существует специальная структура MqlDateTime, которая содержит элементы типа integer для года, месяца, дня, часов, минут, секунд, дня недели и дня года.

Структура MqlDateTime выглядит следующим образом:

struct MqlDateTime
{
    int year;
    int month;
    int day;
    int hour;
    int minute;
    int second;
    int day_of_week;
    int day_of_year;
};
Обратите внимание, что день недели начинается с 0 для воскресенья, а далее идут понедельник, вторник и так далее. День года - это порядковый номер дня в году, начиная с 1 января (который имеет номер 0).

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

Давайте разберемся с функциями для работы с датой и временем. Начнем с функции TimeLocal(), которая возвращает локальное время компьютера, на котором запущен клиентский терминал. У нее есть два варианта использования: вызов без параметров или вызов с параметром типа datetime. В случае работы в тестере стратегий, локальное время равно времени сервера, моделируемого в соответствии с историческими данными.

Следующая функция TimeTradeServer() возвращает расчетное текущее время торгового сервера. Расчет значения времени производится в клиентском терминале и зависит от настроек времени на компьютере пользователя. У этой функции также есть два варианта использования и она возвращает значение типа datetime.

Функция TimeCurrent() возвращает последнее известное время сервера, то есть время прихода последней котировки по одному из выбранных символов в окне обзора рынка. Она также имеет два варианта использования и возвращает значение типа datetime.

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

Функция TimeGMTOffset() возвращает текущую разницу между временем GMT (Greenwich Mean Time) и локальным временем компьютера в секундах, с учетом перехода на зимнее или летнее время. Она также возвращает целочисленное значение.

Функции TimeToStruct() и StructToTime() используются для конвертации значений типа datetime в переменную типа MqlDateTime и обратно. Они возвращают значение true в случае успешного выполнения и false в случае ошибки. Для получения информации об ошибке можно использовать функцию GetLastError().

Содержание

00:00 Вступление

00:28 Тип datetime

01:00 Объявление переменных типа datetime

02:30 Макроподстановки

05:45 Структуры и MqlDateTime

08:40 Функция TimeCurrent

10:07 Функция TimeTradeServer

11:00 Функция TimeLocal

11:32 Функция TimeGMT

12:05 Функция TimeDaylightSavings

12:42 Функция TimeGMTOffset

13:27 Функции TimeToStruct и StructToTime

14:45 Заключение

 

MQL5 программирование: Работа со строками


MQL5 программирование: Работа со строками

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

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

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

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

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

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

Объявление строковой переменной может выглядеть следующим образом:

string myString;

Также можно объявлять переменные с присвоением им конкретных значений:

string myString = "Hello, World!";

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

Также стоит отметить, что значение строковых переменных, объявленных без параметров, как s1, не идентично пустой строке. Давайте убедимся в этом, сравнив две строки s1 и s2. После компиляции и запуска скрипта на графике, мы увидим, что выводится значение. Это означает, что строки действительно не равны. Фактически, неинициализированная строковая переменная имеет значение 'null' и отличается от пустой строки.

При работе со строками часто требуется проверять, не является ли строка пустой. Поэтому рекомендуется либо инициализировать все строковые переменные пустой строкой (как в случае с 's2'), либо выполнять двойную проверку на неравенство пустой строке и неравенство 'null'.

Очень удобно инициализировать все строки пустой строкой, даже если они изначально пусты. Такой подход упрощает проверку. Кроме того, для определения размера строки можно использовать функцию StringLen(). Для проверки длины строки s1, можно использовать следующую запись: 'if (StringLen(s1) != 0)'.

Кроме операции сложения строк с использованием знака плюс, существуют также функции для выполнения этого действия. Функции 'ToString' позволяет преобразовывать числовые значения в строковый формат. Например, можно использовать выражение 't1 = IntegerToString(value) + s3', чтобы объединить строки.

Также есть функция StringConcatenate(), которая работает аналогично. Она принимает любое количество параметров любого простого типа (integer, double) и объединяет их в строку. Функция возвращает длину сформированной строки. Например, можно использовать 't1 = ""; StringConcatenate(t1, s2, " ", 2, " ", 5)', чтобы получить строку, состоящую из s2 и указанных значений.

При формировании строк для вывода сообщений, например, с помощью функции 'Print', часто требуется добавлять числовые значения. Для преобразования целочисленных переменных в строку используется функция IntegerToString(). Это позволяет избежать потери данных и гарантировать правильное преобразование.

"property strict" означает строгую типизацию. Для избежания ошибок при конвертации числа в строку мы можем использовать функцию IntegerToString(). Это позволит нам корректно преобразовать число в целочисленное значение без потери данных.

Например, если у нас есть переменная "d" типа "double" со значением 1.0, использование функции IntegerToString() позволит нам корректно сконвертировать число в строку без округления.

Для конвертации числа с плавающей запятой в строку с определенным количеством разрядов мы можем использовать функцию "DoubleToString". Например, если у нас есть число "d" со значением 0.12345 и мы хотим ограничить количество разрядов до 3, мы можем вызвать функцию "DoubleToString(d, 3)".

Также мы можем конвертировать текущее время в строку, используя функцию TimeToString(). Это позволит нам получить строковое представление текущего времени. Например, если мы присвоим переменной "currentTime" значение "Now", мы можем преобразовать это значение в строку с помощью функции "TimeToStr(currentTime)".

Кроме того, мы можем использовать функцию EnumToString() для конвертации перечисления в строку. Например, если у нас есть тип перечисления "TLength" с возможными значениями "Short", "Medium" и "Long", и переменная "length" имеет значение "Medium", мы можем использовать функцию "EnumToString(TypeInfo(TLength), Ord(length))", чтобы получить строковое представление значения перечисления (в данном случае "Medium").

Аналогично, мы можем использовать функцию ColorToString() для преобразования значения типа "color" в строку. Например, если у нас есть переменная "color" со значением "clRed", мы можем вызвать функцию ColorToString(color), чтобы получить строку с RGB-кодом цвета (в данном случае "250, 0, 0").

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

Чтобы вывести специальные символы, мы можем использовать соответствующие символьные последовательности. Например, для вывода текста в кавычках, мы можем использовать обратный слеш перед кавычками. Также мы можем использовать двойной обратный слеш для вывода обратной черты и символьную последовательность "\t" для вывода символа табуляции.

И еще у нас поддерживается в языке MQL5 такой спецсимвол как "\n", это символ переноса строки. Давайте проверим, как он работает в функции Print, и мы увидим, что наша строка разбилась на 3 подстроки: "обратный \n", "обратный слеш \n" и "работает также функциях Alert и функции MessageBox.

Функция Comment действует только знаком перехода на новую строку, то есть слэш "\n", а знак табуляции при этом, к сожалению, игнорируется при использовании функции Print. Обычно знак обратного слеша "\n" заменяется на пробел в файлах, в которых сохраняются все сообщения, выводимые функцией Print. Знак обратного слеша также заменяется на пробел при формировании строки для вывода.

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

Если у нас, например, вещественное число типа double, мы будем использовать букву f. Давайте проверим. Действительно, ошибка, о чем нас предупредил компилятор. Давайте проверим теперь. Так, что-то не так пошло, а мы не вывели Print и String. Теперь давайте запустим наш скрипт и увидим, что действительно у нас первое значение вывелось как тип double. Кроме того, функция StringFormat() может конвертировать формат представления чисел, переводить числа из десятичной системы счисления восьмеричную или 16-ричную. Например, для перевода восьмеричную систему используется символ "о". Для вывода строковых переменных используется символ "s", то есть "%s".

Следующий довольно простой советник позволяет выводить сообщение на том языке, который выбран в интерфейсе терминала. Функция TerminalInfoString возвращает название выбранного языка, и дальше можно использовать, например, такое условие: если язык русский, возвращай значение на русском языке; если там испанский, возвращай на испанском языке и так далее, вплоть до десятков языков. В данной функции происходит определение языка терминала, и в зависимости от этого языка у нас выводится и возвращается строка на нужном нам языке. В ините у нас происходит вызов этой функции. Давайте мы скомпилируем этот советник, небольшой, и закинем его на график, и посмотрим, что у нас произойдет. Как видим, мы получили alert на именно русском языке.

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

Может быть им удобнее, чтобы так было. Тем не менее, прежде чем выполнять какие-нибудь действия на введенной строкой, желательно удалить пробелы с краев, чтобы избежать ошибок. Для этого в языке MQL5 существуют функции StringTrimLeft() и StringTrimRight(). Дадим какую-нибудь переменную с пробелами слева и справа и выведем ее сразу на печать, и увидим, что действительно у нас пробелы с обоих сторон.

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

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

Как видим, наша строка преобразовалась в нужный нам вид. Еще одна полезная функция называется StringFind(). Она возвращает номер позиции в строке, с которой начинается искомая подстрока, либо минус единицу, если строка не найдена. Допустим, нам нужно найти, с какой позиции в строке у нас начинаются точки с запятой. Мы используем функцию StringFind() и выведем это число, которое она вернет, в журнал. И у нас вывелось число семь.

Содержание

00:00 Вступление

00:25 Что такое текстовая строка

01:40 Пример применения строки во входных параметрах эксперта

02:40 Объявление строковой переменной

06:20 Сложение строк

07:52 Функция StringAdd

08:52 Функция StringConcatenate

11:52 Преобразование различных переменных в строку

18:15 Вывод специальных символов

20:45 Форматирование строк по шаблону

23:25 Сообщения на разных языках

25:35 Основные функции работы со строками

32:50 Преобразование строки в различные переменные

34:28 Заключение

 

MQL5 Программирование: Перечисления


MQL5 Программирование: Перечисления

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

Давайте создадим новый скрипт, и я покажу вам небольшой лайфхак. Обычно при создании скрипта не указываются свойства property скрипта. Это свойство нужно для отображения входных параметров скрипта. Если параметры не указаны при запуске скрипта, то они не будут отображаться. Позвольте мне удалить этот скрипт и создать его заново с добавлением входного параметра типа integer. После этого свойство script_show_inputs автоматически пропишется во вкладке Properties скрипта. Однако я бы также добавил strict для строгой проверки кода. В данном случае мы уберем strict, так как он нам не нужен, но я просто хотел продемонстрировать эту фишку.

Теперь давайте создадим перечисление внутри функции OnInit. Перечисление объявляется с использованием ключевого слова enum, а затем мы указываем значения, которые нам нужны, в фигурных скобках. Давайте рассмотрим абстрактные примеры таймфреймов: M1, M5, H1 и 4H. Обратите внимание, что мы указываем числовые значения для каждого элемента перечисления.

Теперь давайте выведем на печать значения из этого перечисления и посмотрим, какие имена скрываются за этими значениями. Для этого мы будем использовать функцию Print и обратимся к конкретному элементу перечисления по его имени. Запустим скрипт и увидим числа от 0 до 3. Заметьте, что функция Print возвращает конкретные числовые значения, а не имена. Значение 0 соответствует первому имени в перечислении, затем следуют числа 1, 2 и 3. Каждое следующее значение увеличивается на единицу по сравнению с предыдущим, а отсчет начинается с 0.

Мы также можем явно присвоить значения элементам перечисления с помощью оператора присвоения. Давайте скомпилируем код и посмотрим, что у нас получится. Заметьте, что значения теперь начинаются с 1, так как мы явно присвоили первому элементу значение -3. Все последующие значения увеличиваются на единицу относительно предыдущего. Если первое значение перечисления не присвоено явно, оно будет равно 0.

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

Значения перечисления можно использовать в различных операциях. Например, мы можем создать переменную типа int и сложить значение H1 (равное 60) и M1 (равное 1). Давайте выведем результат этой операции с помощью Print. Мы получим число 61.

Значение перечисления, заданное при объявлении, остается неизменным на протяжении выполнения программы. Изменить его в процессе выполнения или присвоить ему новое значение нельзя.

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

Рассмотрим пример использования перечислений в торговом советнике. Предположим, что у нас есть переменная, и если ее значение соответствует определенному значению в перечислении, то советник будет только покупать или только продавать. Если значение не соответствует ни одному из значений, то ничего не делать. В этом случае мы можем использовать оператор switch, с которым мы уже знакомились на четвертом уроке по MQL5.

Давайте рассмотрим простой пример. Создадим перечисление TradeType, в котором определим значения BUY и SELL. У нас также есть переменная tradeDirection, которая указывает направление торговли. В функции OnStart мы применяем оператор switch и в зависимости от значения tradeDirection устанавливаем флаги переменных соответствующим образом.

После этого мы можем компилировать и протестировать наш скрипт в терминале. Заметим, что значение переменной tradeDirection может быть либо BUY, либо SELL, либо не соответствовать ни одному из значений. В зависимости от выбранного значения, скрипт будет выполнять определенные действия.

Использование оператора switch с перечислениями предоставляет гибкость и удобство при разработке программ. Однако важно отметить, что пользовательские перечисления не так часто используются в программах на MQL5. Зато в языке MQL5 существует множество заранее созданных перечислений, предоставляемых разработчиками. Эти перечисления могут быть полезными при разработке программ.

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

Содержание

00:00 Вступление

00:27 Создание нового скрипта

01:45 Объявление перечислений

03:33 Присвоение значений членам перечисления

04:15 Правила пересчета значений членов перечисления

06:30 Операции с членами перечисления

07:10 Практическое применение перечислений для объявления переменных

07:50 Использование перечислений и оператора switch

10:40 Заключение

Причина обращения: