Введение в MQL5 (Часть 12): Руководство для начинающих по созданию пользовательских индикаторов
Введение
На данный момент мы помимо прочего рассмотрели работу со встроенными индикаторами, создание советников, фундаментальные концепции MQL5, применение наших знаний на практике. Пришло время научиться создавать собственные индикаторы с нуля. Мы получим более глубокое понимание того, как работают индикаторы изнутри, что позволит нам полностью контролировать их работу и устройство, а не зависеть от встроенных функций. Вы когда-нибудь задумывались, как строятся скользящие средние или MACD - два встроенных индикатора MQL5? Можно ли создавать индикаторы без таких функций, как iRSI или iMA?
Используя проектный подход, мы разделим процесс на две основные части. Во-первых, мы построим индикатор скользящей средней полностью с нуля, не используя функцию iMA. Далее мы сделаем еще один шаг и преобразуем скользящую среднюю из традиционной линейной формы в индикатор в виде свечи. Кроме того, этот практический метод откроет новые возможности для разработки торговых инструментов, которые будут соответствовать именно вашим требованиям.
Скользящая средняя в виде линии

Скользящая средняя в виде свечей

В этой статье вы узнаете:
- Как создать пользовательские индикаторы с нуля на MQL5.
- Разницу между построением индикаторов в линейном формате и в формате свечей.
- Как использование индикаторные буферы для хранения и отображения расчетных значений.
- Как правильно настроить свойства индикатора.
- Как создать пользовательский индикатор скользящей средней на MQL5.
- Как отобразить буферы индикатора с помощью SetIndexBuffer().
- Как обработать данных о ценах с помощью функции OnCalculate().
- Как определить цвет свечей на основе движения цены.
Статья рассчитана на новичков, поэтому проблем с пониманием возникнуть не должно. Каждая строка кода будет подробно объяснена, а сложные идеи будут разбиты на выполнимые шаги. После прочтения статьи у вас должно быть четкое понимание того, как работают пользовательские индикаторы в MQL5, поскольку я постараюсь изложить все просто и доступно.
1. Пользовательские индикаторы
1.1. Что такое пользовательские индикаторы?
Пользовательские индикаторы — это индикаторы, которые по умолчанию отсутствуют в MQL5. В отличие от встроенных индикаторов MetaTrader 5, таких как скользящие средние (MA), индекс относительной силы (RSI) или MACD, пользователи могут создавать собственные индикаторы для выполнения определенных вычислений, подачи сигналов или представления рыночных данных так, как они считают нужным.
Встроенные индикаторы легко интегрировать в торговые стратегии, поскольку к ним можно получить прямой доступ с помощью таких функций, как iMA(), iRSI() и iMACD(). Но когда дело доходит до настройки, они ограничены. С другой стороны, пользовательские индикаторы обеспечивают полный контроль над расчетами, логикой и отображением графиков, позволяя создавать инструменты, соответствующие вашим конкретным торговым требованиям. Эти индикаторы будут особенно полезны трейдерам, желающим проводить анализ рынка методами, не поддерживаемыми встроенными индикаторами. Используя программирование на языке MQL5, вы можете разрабатывать уникальные индикаторы, обеспечивающие более полное понимание движения цен, трендов и возможных торговых возможностей.
Аналогия
Представьте, что вы обустраиваете в своем жилом помещении книжную полку. Встроенные индикаторы можно сравнить с магазином с предварительно собранными книжными полками. Эти книжные полки имеют заранее определенные размеры, формы и характеристики и доступны в стандартных исполнениях. Для большинства людей они просты в использовании, удобны и эффективны. Однако предварительно собранная книжная полка может не подойти или не удовлетворить ваши требования, если ваше пространство имеет нестандартную форму или вам требуются специальные полки для редких томов.
С другой стороны, пользовательские индикаторы подобны книжной полке, которую вы делаете сами. Точные размеры, количество полок и материалы можно выбрать, чтобы создать книжную полку, которая впишется в ваше пространство и позволит расставить книги так, как вам удобно. Аналогично, в торговле пользовательские индикаторы обеспечивают точность и гибкость, которых не могут дать встроенные индикаторы, позволяя вам разрабатывать решения, соответствующие вашей уникальной стратегии.
1.2. Различия между советниками и индикаторами
Хотя индикаторы и советники оценивают рыночные данные во многом схожим образом, их функции существенно различаются. Поскольку советники предназначены для автоматизации торговли, помимо анализа рынка они также совершают сделки в соответствии с заданными правилами. Они способны управлять рисками, изменять стоп-лосс, определять уровни тейк-профита, а также открывать и закрывать ордера. Каждый раз при обновлении цены вызывается OnTick() — одна из важнейших функций советника. С помощью этой функции советник может следить за движением цен в реальном времени и проверять соблюдение торговых критериев перед размещением ордера.
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // }
Индикаторы, напротив, не могут совершать сделки. Они только анализируют рынок. Вместо OnTick() индикаторы используют метод OnCalculate(), который анализирует исторические и текущие данные для выработки торговых показателей. Расчет значений индикаторов, обновление элементов графика и представление визуальных сигналов, таких как линии тренда или цветные свечи, выполняются с помощью OnCalculate().
Индикаторы просто предоставляют полезную информацию; окончательное решение принимается трейдерами, в отличие от советников, которые созданы для того, чтобы действовать. Хотя оба инструмента изучают рыночные данные, индикаторы и советники служат разным целям. В то время как индикаторы помогают трейдерам вручную интерпретировать рынок и принимать обоснованные торговые решения, советники действуют в соответствии с торговыми возможностями.
//+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { // }
Аналогия
Рассматривайте индикаторы и советники как два отдельных торговых инструмента. Советник анализирует рынок, делает выбор и совершает сделки автономно, подобно беспилотному автомобилю. Без участия человека система применяет торговые методы, постоянно отслеживает колебания рынка и контролирует риски.
Индикатор, с другой стороны, действует скорее как GPS: он указывает направление, но не выполняет никаких действий. Он анализирует рыночные данные, выявляет закономерности и помогает трейдерам понимать изменения цен. Например, скользящая средняя может указывать на то, движется ли рынок вверх или вниз, но она не может инициировать или прекращать сделки. Индикатор только предоставляет информацию; окончательный выбор остается за вами, советник же торгует за вас.
2. Настройка проекта
Теперь, когда мы знаем, что такое пользовательские индикаторы и чем они отличаются от советников и встроенных индикаторов, давайте рассмотрим, как создавать и модифицировать наши индикаторы в MQL5. В этом разделе мы подробно рассмотрим эту процедуру, чтобы получить четкое представление о том, как создать индикатор. В этом уроке мы с нуля построим два уникальных индикатора, не используя никаких готовых процедур, таких как скользящая средняя.
2.1. Линейная скользящая средняя
Первый индикатор будет представлять собой простой индикатор скользящей средней, который рассчитывает и отображает три различных скользящих средних:
- Период 200 применяется к максимальной цене.
- Период 100 применяется к цене закрытия.
- Период 50 применяется к цене открытия.
Чтобы создать собственный индикатор, необходимо сначала понять логику его работы. Прежде чем писать какой-либо код, мы должны определить, как индикатор будет обрабатывать рыночные данные и отображать соответствующую информацию. Этот шаг гарантирует, что наш подход хорошо структурирован и прост в реализации. Составление псевдокода является важным шагом в дополнение к пониманию его логики. Создание псевдокода облегчает разделение реализации на более мелкие и легкоуправляемые части. Это снижает вероятность ошибок и повышает эффективность процесса кодирования.
В этом разделе сначала будет рассмотрена логика, необходимая для определения и отображения трех скользящих средних с использованием различных источников цен. Прежде чем писать реальный код, мы сначала составим черновик псевдокода, который послужит руководством для нашей реализации. Этот структурированный подход поможет нам создать четко определенный пользовательский индикатор, одновременно закрепив ключевые концепции программирования на MQL5.
Псевдокод:
// Настройка индикатора
1. Настройте индикатор для отображения в окне графика.
2. Определите 3 буфера для хранения данных скользящих средних (MA200, MA100, MA50).
3. Определите 3 графика для отображения скользящих средних на графике.
// Настройка свойств отображения
4. Для MA200:
- Обозначение: "MA 200"
- Тип: линия
- Стиль: тире-точка-точка
- Ширина: 1
- Цвет: синий
5. Для MA100:
- Обозначение: "MA 100"
- Тип: линия
- Стиль: тире
- Ширина: 1
- Цвет: коричневый
6. Для MA50:
- Обозначение: "MA 50"
- Тип: линия
- Стиль: точка
- Ширина: 1
- Цвет: фиолетовый
// Определение буферов
7. Создайте буферы для хранения рассчитанных значений для:
- MA200
- MA100
- MA50
// Определение входных параметров
8. Разрешим пользователю устанавливать период для каждой скользящей средней:
- MA200: период по умолчанию = 200
- MA100: период по умолчанию = 100
- MA50: период по умолчанию = 50
// Функция инициализации
9. При инициализации индикатора:
- Назначьте буфер соответствующему графическому элементу.
- Установите количество начальных баров, которые следует пропустить для каждой скользящей средней:
- MA200: пропустить первые 200 баров
- MA100: пропустить первые 100 баров
- MA50: пропустить первые 50 баров
// Функция расчета
10. Для каждой новой свечи или при обновлении графика:
Максимальные цены, цены закрытия и открытия предыдущих 200, 100 и 50 баров будут суммированы для каждого бара, разделены на соответствующее время, а результаты будут сохранены в соответствующих буферах для определения MA200, MA100 и MA50.
2.2. Свечная скользящая средняя
Далее мы создадим другой индикатор скользящей средней, который будет отображать ценовые тренды в формате свечей. Этот индикатор будет использовать скользящую среднюю с периодом 5 и визуально представлять ее значения с помощью свечей вместо линий. Отображая данные скользящей средней таким образом, мы можем более эффективно выделять краткосрочные тренды и отфильтровывать рыночный шум. Это позволит получить уникальный взгляд на движение цен, сохраняя при этом принципы расчета скользящей средней.
Каждый проект будет подробно объяснен, при этом каждая строка кода будет достаточно простой для понимания новичками. К концу этой части у вас появится практический опыт создания и модификации индикаторов с нуля, что даст вам полезные навыки для дальнейших проектов.
Псевдокод:
// Настройка индикатора
1. Настройте отображение индикатора в отдельном окне.
2. Создайте 5 массивов (буферов) для хранения:
- цен открытия (OpenBuffer)
- максимальных цен (HighBuffer)
- минимальных цен (LowBuffer)
- цен закрытия (CloseBuffer)
- Цвета свечей (ColorBuffer: 0 = зеленый, 1 = красный)
3. Определите графический элемент для отображения свечей.
// Настройка свойств отображения
4. Для графического элемента:
- Обозначение: "Candles" (свечи)
- Тип: цветные свечи (DRAW_COLOR_CANDLES)
- Цвета: зеленый — бычий, красный — медвежий.
- Стиль: сплошной
- Ширина: 1
// Определение входных параметров
5. Разрешить пользователю устанавливать период сглаживания (по умолчанию = 5).
// Функция инициализации
6. При инициализации индикатора:
- Назначьте каждому буферу соответствующий ему индекс данных или цвета.
- Установите количество начальных баров, которые необходимо пропустить (равное периоду сглаживания).
// Функция расчета
7. Для каждой новой свечи или при обновлении графика:
- Проверьте, достаточно ли баров для расчета (по крайней мере, баров "периода").
- Если недостаточно, вывести сообщение об ошибке и остановиться.
8. Для каждого бара от бара "период-1" до последнего бара:
Рассчитайте сглаженные цены открытия, максимума, минимума и закрытия:
- Сложите цены открытия, максимума, минимума и закрытия за последний "период" баров.
- Разделите каждую сумму на "период", чтобы получить среднее значение.
- Сохраните результаты в OpenBuffer, HighBuffer, LowBuffer и CloseBuffer.
Установите цвет свечи:
- Если сглаженная цена закрытия >= сглаженной цене открытия, установите зеленый цвет (0).
- В противном случае установите красный цвет (1).
3. Создание и настройка пользовательских индикаторов
Теперь мы можем создавать и изменять наши пользовательские индикаторы, поскольку мы написали псевдокод. Имея четко определенную стратегию, мы начнем постепенно воплощать логику в жизнь, следя за тем, чтобы индикатор работал так, как задумано. Мы можем эффективно визуализировать движения рынка и изменять индикатор в соответствии с нашими потребностями, правильно организовав наш код.
3.1. Построение индикатора скользящей средней в виде линии
Первый шаг в создании индикатора — представить, как вы хотите, чтобы он выглядел и работал. Крайне важно задать себе несколько важных вопросов, которые помогут вам понять устройство и реализацию:
- Должен ли индикатор отображаться в главном окне графика или в отдельном окне?
- Сколько буферов потребуется индикатору для хранения и отображения данных?
- Какой тип графика следует использовать — линейный, гистограмму, свечи или что-то другое?
- Какие цвета следует назначить различным элементам для лучшей видимости?
- Будет ли индикатор использовать несколько источников данных, таких как максимальные и минимальные цены, цены открытия и закрытия?
Ответив на эти вопросы, вы сможете создать четкую схему для своего индикатора, что сделает процесс разработки более плавным и структурированным.
Пример:
//INDICATOR IN CHART WINDOW #property indicator_chart_window //SET INDICATOR BUFFER TO STORE DATA #property indicator_buffers 3 //SET NUMBER FOR INDICATOR PLOTS #property indicator_plots 3
Объяснение:
Индикатор в окне графика#property indicator_chart_window
Вместо отображения пользовательского индикатора в отдельном окне эта директива указывает MetaTrader 5 отображать его сразу на основном графике, отображающем динамику цены. Чтобы построить индикатор в другом окне (например, RSI или MACD), мы бы использовали:
#property indicator_separate_window
Эта директива гарантирует, что индикатор будет отображаться в отдельном окне под основным графиком, а не будет наноситься непосредственно на ценовой график.
Настройка индикаторных буферов для хранения данных
#property indicator_buffers 3
Рассчитанные значения, которые будут отображены на графике, хранятся в массивах, называемых индикаторными буферами. Каждый буфер представляет собой отдельный элемент индикатора. В этом случае мы будем хранить три различных набора значений, поскольку мы создаем три индикаторных буфера. Для хранения значений каждой скользящей средней по отдельности требуются три буфера, поскольку мы строим индикатор скользящей средней с тремя различными периодами (50, 100 и 200).
Установка количества графических элементов индикатора
#property indicator_plots 3
Директива определяет сколько графических элементов (plots) будет содержать индикатор. Здесь под элементов понимается отдельное графическое представление. Потребуется три элемента, поскольку мы рисуем три скользящие средние: по одной для каждой из 50-, 100- и 200-периодных скользящих средних.
Цвет, стиль и формат (например, линия, гистограмма или свечи) можно настраивать для каждого графика. Здесь каждый из трех графиков будет отображен в виде линии, представляющей отдельную скользящую среднюю.
Итог
- Индикатор будет отображен на основном графике (#property indicator_chart_window).
- Он будет хранить три набора значений, используя индикаторные буферы (#property indicator_buffers 3).
- Он построит три различных скользящих средних (#property indicator_plots 3).
Такая настройка гарантирует, что индикатор правильно рассчитывает и отображает три скользящие средние на ценовом графике.

Настройка свойств графика выполняется после определения основных характеристик нашего индикатора. Чтобы указать, как индикатор будет выглядеть на графике, при построении пользовательского индикатора на языке MQL5 необходимо предоставить атрибуты построения. Тип рисунка, стиль линии, толщина, цвет и надписи определяются этими параметрами. Понимание этих параметров поможет вам в создании и изменении индикаторов для различных вариантов использования, поскольку эта статья посвящена разработке пользовательских индикаторов с использованием проектного подхода.
Примеры:
//INDICATOR IN CHART WINDOW #property indicator_chart_window //SET INDICATOR BUFFER TO STORE DATA #property indicator_buffers 3 //SET NUMBER FOR INDICATOR PLOTS #property indicator_plots 3 //SETTING PLOTS PROPERTIES //PROPERTIES OF THE FIRST MA (MA200) #property indicator_label1 "MA 200" //GIVE PLOT ONE A NAME #property indicator_type1 DRAW_LINE //TYPE OF PLOT THE FIRST MA #property indicator_style1 STYLE_DASHDOTDOT //STYLE OF SPOT THE FIRST MA #property indicator_width1 1 //LINE THICKNESS THE FIRST MA #property indicator_color1 clrBlue //LINE COLOR THE FIRST MA //PROPERTIES OF THE SECOND MA (MA100) #property indicator_label2 "MA 100" //GIVE PLOT TWO A NAME #property indicator_type2 DRAW_LINE //TYPE OF PLOT THE SECOND MA #property indicator_style2 STYLE_DASH //STYLE OF SPOT THE SECOND MA #property indicator_width2 1 //LINE THICKNESS THE SECOND MA #property indicator_color2 clrBrown //LINE COLOR THE SECOND MA //PROPERTIES OF THE THIRD MA (MA50) #property indicator_label3 "MA 50" //GIVE PLOT TWO A NAME #property indicator_type3 DRAW_LINE //TYPE OF PLOT THE THIRD MA #property indicator_style3 STYLE_DOT //STYLE OF SPOT THE THIRD MA #property indicator_width3 1 //LINE THICKNESS THE THIRD MA #property indicator_color3 clrPurple //LINE COLOR THE THIRD MA
Объяснение:
Первая скользящая средняя (MA 200)
#property indicator_label1 "MA 200" //GIVE PLOT ONE A NAME #property indicator_type1 DRAW_LINE //TYPE OF PLOT THE FIRST MA #property indicator_style1 STYLE_DASHDOTDOT //STYLE OF SPOT THE FIRST MA #property indicator_width1 1 //LINE THICKNESS THE FIRST MA #property indicator_color1 clrBlue //LINE COLOR THE FIRST MA
Первая скользящая средняя (MA200) будет отображаться в виде синей пунктирной линии толщиной 1.
Вторая скользящая средняя (MA 100)
#property indicator_label2 "MA 100" //GIVE PLOT TWO A NAME #property indicator_type2 DRAW_LINE //TYPE OF PLOT THE SECOND MA #property indicator_style2 STYLE_DASH //STYLE OF SPOT THE SECOND MA #property indicator_width2 1 //LINE THICKNESS THE SECOND MA #property indicator_color2 clrBrown //LINE COLOR THE SECOND MA
Вторая скользящая средняя (MA100) будет отображена как коричневая пунктирная линия толщиной 1.
Третья скользящая средняя (MA 50)
#property indicator_label3 "MA 50" //GIVE PLOT TWO A NAME #property indicator_type3 DRAW_LINE //TYPE OF PLOT THE THIRD MA #property indicator_style3 STYLE_DOT //STYLE OF SPOT THE THIRD MA #property indicator_width3 1 //LINE THICKNESS THE THIRD MA #property indicator_color3 clrPurple //LINE COLOR THE THIRD MA
Третья скользящая средняя (MA50) будет отображена в виде фиолетовой пунктирной линии толщиной 1.
Понимание взаимосвязи между свойствами графических элементов в MQL5
Для каждого графического элемента (линии, гистограммы, стрелки и т. д.) требуется набор характеристик, определяющих его внешний вид при определении того, как индикатор должен отображаться на графике. Для назначения свойств в MQL5 используются нумерованные суффиксы, такие как indicator_label1, indicator_type1, indicator_style1 и т. д.
Благодаря этой нумерации все свойства графического объекта на определенном участке гарантированно принадлежат друг другу. Давайте рассмотрим ее подробнее:
- indicator_label1 присваивает имя первому элементу, что облегчает его идентификацию.
- indicator_type1 определяет, как будет отображаться первый элемент (например, в виде линии).
- indicator_style1 определяет стиль линии для этого первого графика (сплошная, пунктирная, точечная и т. д.).
- indicator_width1 управляет толщиной первого графика.
- indicator_color1 задает цвет для первого графика.
Пример для прояснения взаимосвязи
Представьте эти свойства как соответствующий набор для каждой скользящей средней:
| Свойство | Чем управляет | First MA (200) | Second MA (100) | Third MA (50) |
|---|---|---|---|---|
| indicator_labelX | Имя скользящей средней | "MA 200" | "MA 100" | "MA 50" |
| indicator_typeX | Тип элемента | DRAW_LINE | DRAW_LINE | DRAW_LINE |
| indicator_styleX | Стиль линий | STYLE_DASHDOTDOT | STYLE_DASH | STYLE_DOT |
| indicator_widthX | Толщина | 1 | 1 | 1 |
| indicator_colorX | Цвет | clrBlue | clrBrown | clrPurple |
Такой подход гарантирует, что каждое свойство соответствует определенной скользящей средней, и позволяет нам упорядоченно указывать множество графических элементов. Таким образом, изменение indicator_style2 повлияет только на вторую скользящую среднюю. При изменении indicator_color3 изменится только цвет третьей скользящей средней. Мы можем управлять внешним видом каждой скользящей средней на графике, не создавая путаницы, сохраняя последовательность и организацию этих характеристик.
Помимо множества типов графиков, стилей линий и цветов, которые мы использовали в нашем индикаторе скользящей средней, MQL5 предлагает множество других возможностей настройки графиков индикатора. Используя эти параметры, разработчики могут проектировать различные типы индикации: от простых линий до более сложных визуализаций, таких как полосы, стрелки и гистограммы. Мы применяем проектный подход, концентрируясь на одном индикаторе и представляя основные идеи, которые могут быть использованы для других индивидуальных индикаторов, поскольку существует слишком много переменных, чтобы обсуждать их в одной статье. Однако полезно знать, что есть и другие варианты выбора.
В целом, различные стили графических элементов можно анализировать, используя ту же логику, что использована в этой статье. Однако это не всегда так для всех видов элементов. Например, DRAW_LINE требует только один буфер на элемент, а DRAW_CANDLES требует четыре буфера для построения одной свечи. Вы можете обратиться к Справочнику MQL5 для полного описания множества доступных типов элементов и их особенностей.
Объявление двойных переменных для хранения индикаторных буферов происходит после настройки атрибутов графика. Эти буферы имеют решающее значение, поскольку они хранят вычисленные значения, которые будут отображены на графике. Функция SetIndexBuffer() должна использоваться для привязки переменных к буферам индикаторов после их объявления. Этот этап гарантирует, что данные, хранящиеся в буферах, могут быть отображены точно и правильно назначены соответствующим элементам.
Пример:
//INDICATOR IN CHART WINDOW #property indicator_chart_window //SET INDICATOR BUFFER TO STORE DATA #property indicator_buffers 3 //SET NUMBER FOR INDICATOR PLOTS #property indicator_plots 3 //SETTING PLOTS PROPERTIES //PROPERTIES OF THE FIRST MA (MA200) #property indicator_label1 "MA 200" //GIVE PLOT ONE A NAME #property indicator_type1 DRAW_LINE //TYPE OF PLOT THE FIRST MA #property indicator_style1 STYLE_DASHDOTDOT //STYLE OF SPOT THE FIRST MA #property indicator_width1 1 //LINE THICKNESS THE FIRST MA #property indicator_color1 clrBlue //LINE COLOR THE FIRST MA //PROPERTIES OF THE SECOND MA (MA100) #property indicator_label2 "MA 100" //GIVE PLOT TWO A NAME #property indicator_type2 DRAW_LINE //TYPE OF PLOT THE SECOND MA #property indicator_style2 STYLE_DASH //STYLE OF SPOT THE SECOND MA #property indicator_width2 1 //LINE THICKNESS THE SECOND MA #property indicator_color2 clrBrown //LINE COLOR THE SECOND MA //PROPERTIES OF THE THIRD MA (MA50) #property indicator_label3 "MA 50" //GIVE PLOT TWO A NAME #property indicator_type3 DRAW_LINE //TYPE OF PLOT THE THIRD MA #property indicator_style3 STYLE_DOT //STYLE OF SPOT THE THIRD MA #property indicator_width3 1 //LINE THICKNESS THE THIRD MA #property indicator_color3 clrPurple //LINE COLOR THE THIRD MA //SET MA BUFFER TO STORE DATA double buffer_mA200[]; //BUFFER FOR THE FIRST MA double buffer_mA100[]; //BUFFER FOR THE SECOND MA double buffer_mA50[]; //BUFFER FOR THE THIRD MA //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //SETTING BUFFER SetIndexBuffer(0, buffer_mA200, INDICATOR_DATA); //INDEX 0 FOR MA200 SetIndexBuffer(1, buffer_mA100, INDICATOR_DATA); //INDEX 1 FOR MA100 SetIndexBuffer(2, buffer_mA50, INDICATOR_DATA); //INDEX 1 FOR MA50 //--- return(INIT_SUCCEEDED); }
Объяснение:
//SET MA BUFFER TO STORE DATA double buffer_mA200[]; //BUFFER FOR THE FIRST MA double buffer_mA100[]; //BUFFER FOR THE SECOND MA double buffer_mA50[]; //BUFFER FOR THE THIRD MA
Эти массивы (buffer_mA200, buffer_mA100, buffer_mA50) служат хранилищем для рассчитанных значений каждой скользящей средней.
Каждый буфер соответствует определенной скользящей средней:
- buffer_mA200 → хранит значения для MA 200
- buffer_mA100 → хранит значения для MA 100
- buffer_mA50 → хранит значения для MA 50
При отображении индикатора значения, хранящиеся в этих буферах, будут отображены на графике. Для хранения рассчитанных значений индикатора в MQL5 необходимы индикаторные буферы. Без буферов сохранить и показать результаты было бы невозможно.
//SETTING BUFFER SetIndexBuffer(0, buffer_mA200, INDICATOR_DATA); //INDEX 0 FOR MA200 SetIndexBuffer(1, buffer_mA100, INDICATOR_DATA); //INDEX 1 FOR MA100 SetIndexBuffer(2, buffer_mA50, INDICATOR_DATA); //INDEX 2 FOR MA50
SetIndexBuffer() используется для привязки каждого буфера к системе построения графических элементов индикатора.
Принимает три параметра:
- Индекс буфера → определяет порядок использования буферов (начиная с 0).
- Переменная буфера → буфер, в котором будут храниться значения для этого индекса.
- Тип буфера → INDICATOR_DATA указывает, что буфер содержит значения индикатора.
Разбивка каждой строки:
- SetIndexBuffer(0, buffer_mA200, INDICATOR_DATA); → присваивает buffer_mA200 индексу 0 (первая скользящая средняя).
- SetIndexBuffer(1, buffer_mA100, INDICATOR_DATA); → присваивает buffer_mA100 индексу 1 (вторая скользящая средняя).
- SetIndexBuffer(2, buffer_mA50, INDICATOR_DATA); → присваивает buffer_mA50 индексу 2 (третья скользящая средняя).
Это гарантирует, что индикаторная система MQL5 правильно распознает и отображает каждый буфер. Без этого шага индикатор не будет работать правильно.
Глубокое понимание математических основ и принципов, лежащих в основе индикатора, имеет решающее значение для его создания. Только когда индикатор точно оценивает изменения цен, используя надежную математическую или логическую основу, его можно считать полезным. Прежде чем применять индикатор на практике в MQL5, необходимо понимать, как он работает и какие входные данные необходимы для его эффективного расчета.
Например, возьмем скользящую среднюю:
Снижая колебания цен, скользящая средняя упрощает выявление рыночных тенденций, не подвергаясь влиянию временных изменений.
Чтобы рассчитать скользящую среднюю, нам необходимо учесть:
Период
Количество исторических свечей, используемых для расчета скользящей средней, зависит от таймфрейма. Например, последние 200 свечей усредняются с помощью 200-периодной скользящей средней. Хотя скользящая средняя более чувствительна к недавним изменениям при более коротком периоде, более длительный период создает более плавную линию, которая медленнее реагирует на изменения цен.
Тип цены
Скользящую среднюю можно рассчитать с использованием различных типов цен, таких как:
- Close Price → использует цену закрытия каждой свечи.
- Open Price → использует цену открытия каждой свечи.
- High Price → использует максимальную цену каждой свечи.
- Low Price → использует минимальную цену каждой свечи.
В этом проекте мы будем работать с тремя различными скользящими средними:
- MA 200 (применяется к максимальной цене)
- MA 100 (применяется к цене закрытия)
- MA 50 (применяется к цене открытия)
Понимание этих основных концепций гарантирует, что мы сможем правильно рассчитать и визуализировать скользящую среднюю, не полагаясь на встроенные функции MQL5, такие как iMA().
Пример:
//INDICATOR IN CHART WINDOW #property indicator_chart_window //SET INDICATOR BUFFER TO STORE DATA #property indicator_buffers 3 //SET NUMBER FOR INDICATOR PLOTS #property indicator_plots 3 //SETTING PLOTS PROPERTIES //PROPERTIES OF THE FIRST MA (MA200) #property indicator_label1 "MA 200" //GIVE PLOT ONE A NAME #property indicator_type1 DRAW_LINE //TYPE OF PLOT THE FIRST MA #property indicator_style1 STYLE_DASHDOTDOT //STYLE OF SPOT THE FIRST MA #property indicator_width1 1 //LINE THICKNESS THE FIRST MA #property indicator_color1 clrBlue //LINE COLOR THE FIRST MA //PROPERTIES OF THE SECOND MA (MA100) #property indicator_label2 "MA 100" //GIVE PLOT TWO A NAME #property indicator_type2 DRAW_LINE //TYPE OF PLOT THE SECOND MA #property indicator_style2 STYLE_DASH //STYLE OF SPOT THE SECOND MA #property indicator_width2 1 //LINE THICKNESS THE SECOND MA #property indicator_color2 clrBrown //LINE COLOR THE SECOND MA //PROPERTIES OF THE THIRD MA (MA50) #property indicator_label3 "MA 50" //GIVE PLOT TWO A NAME #property indicator_type3 DRAW_LINE //TYPE OF PLOT THE THIRD MA #property indicator_style3 STYLE_DOT //STYLE OF SPOT THE THIRD MA #property indicator_width3 1 //LINE THICKNESS THE THIRD MA #property indicator_color3 clrPurple //LINE COLOR THE THIRD MA //SET MA BUFFER TO STORE DATA double buffer_mA200[]; //BUFFER FOR THE FIRST MA double buffer_mA100[]; //BUFFER FOR THE SECOND MA double buffer_mA50[]; //BUFFER FOR THE THIRD MA //SET MA PERIOD input int period_ma200 = 200; //PERIOD FOR THE FIRST MA input int period_ma100 = 100; //PERIOD FOR THE SECOND MA input int period_ma50 = 50; //PERIOD FOR THE THIRD MA //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //SETTING BUFFER SetIndexBuffer(0, buffer_mA200, INDICATOR_DATA); //INDEX 0 FOR MA200 SetIndexBuffer(1, buffer_mA100, INDICATOR_DATA); //INDEX 1 FOR MA100 SetIndexBuffer(2, buffer_mA50, INDICATOR_DATA); //INDEX 1 FOR MA50 //SETTING BARS TO START PLOTTING PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, period_ma200); PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, period_ma100); PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, period_ma50); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //CALCULATE THE MOVING AVERAGE FOR THE THE First MA (MA200) for(int i = period_ma200 - 1; i < rates_total; i++) { double sum = 0.0; for(int j = 0; j < period_ma200; j++) { sum += high[i - j]; } buffer_mA200[i] = sum / period_ma200; } //CALCULATE THE MOVING AVERAGE FOR THE THE SECOND MA (MA100) for(int i = period_ma100 - 1; i < rates_total; i++) { double sum = 0.0; for(int j = 0; j < period_ma100; j++) { sum += close[i - j]; } buffer_mA100[i] = sum / period_ma100; } //CALCULATE THE MOVING AVERAGE FOR THE THE THIRD MA (MA50) for(int i = period_ma50 - 1; i < rates_total; i++) { double sum = 0.0; for(int j = 0; j < period_ma50; j++) { sum += open[i - j]; } buffer_mA50[i] = sum / period_ma50; } //--- return value of prev_calculated for next call return(rates_total); }
Объяснение:
//SET MA PERIOD input int period_ma200 = 200; //PERIOD FOR THE FIRST MA input int period_ma100 = 100; //PERIOD FOR THE SECOND MA input int period_ma50 = 50; //PERIOD FOR THE THIRD MA
- Эти входные переменные определяют период каждой скользящей средней.
- Период определяет, сколько прошлых свечей МА будет использовать для своего расчета.
- period_ma200 = 200 означает, что MA200 будет использовать последние 200 свечей для расчета средней цены.
- period_ma100 = 100 означает, что MA100 будет использовать последние 100 свечей для расчета среднего значения.
- period_ma50 = 50 означает, что MA50 будет использовать последние 50 свечей для расчета среднего значения.
- Поскольку это входные переменные, трейдеры могут изменять их в настройках индикатора, не меняя код.
//SETTING BARS TO START PLOTTING PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, period_ma200); PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, period_ma100); PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, period_ma50);
Зачем это нужно?
- Поскольку для вычисления значения скользящей средней с периодом 200 необходимо 200 предыдущих свечей, она не может ничего построить до первых 200 свечей.
- PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, period_ma200); сообщает MetaTrader о необходимости начать отрисовку MA200 только после того, как будут доступны 200 свечей.
- PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, period_ma100); делает то же самое для MA100 (начинается после 100 свечей).
- PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, period_ma50); гарантирует, что MA50 запустится после 50 свечей.

//+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[])
Центральная функция каждого пользовательского индикатора OnCalculate() автоматически вызывается при получении нового тика или обновлении исторических данных. Она имеет решающее значение для расчетов индикаторов, поскольку обрабатывает ценовые данные и изменяет буферы индикаторов. OnCalculate() создан специально для индикаторов и обеспечивает прямой доступ к историческим ценовым данным без необходимости использования других процедур, таких как CopyOpen(), CopyClose() или ArraySetAsSeries(), в отличие от OnTick(), который используется в советниках.
Разница между OnCalculate() и OnTick()| Свойство | OnCalculate() | OnTick() |
|---|---|---|
| Используется в | Индикаторы | Эксперты |
| Вызывается, когда | Появляется новый тик или обновляется график | Появляется новый тик |
| Доступ к ценовым данным | Использует встроенные массивы (open[], close[] и т.д.) | Требуются функции типа CopyClose() для извлечения данных |
| Назначение | Рассчитывает и обновляет значения индикаторов | Выполняет торговую логику, размещает ордера |
| Параметры | Описание |
|---|---|
| rates_total | Общее количество доступных свечей (баров) на графике. |
| prev_calculated | Количество ранее рассчитанных баров (помогает оптимизировать производительность). |
| time[] | Временная метка каждой свечи (например, 2024.02.02 12:30). |
| open[] | Цена открытия каждой свечи. |
| high[] | Максимальная цена каждой свечи |
| low[] | Минимальная цена каждой свечи. |
| close[] | Цена закрытия каждой свечи. |
| tick_volume[] | Количество тиков (обновлений цены) в пределах свечи. |
| volume[] | Общий объем сделок за свечу. |
| spread[] | Спред (разница между ценой спроса и предложения) для каждой свечи. |
// CALCULATE THE MOVING AVERAGE FOR THE FIRST MA (MA200) for(int i = period_ma200 - 1; i < rates_total; i++) { double sum = 0.0; for(int j = 0; j < period_ma200; j++) { sum += high[i - j]; // SUM OF HIGH PRICES OVER THE PERIOD } buffer_mA200[i] = sum / period_ma200; // CALCULATE THE AVERAGE }
Цикл for, который перебирает ценовые данные, используется для расчета первой скользящей средней (MA200). У нас достаточно предыдущих точек данных для расчета среднего значения, поскольку цикл начинается с period_ma200 - 1. Он продолжается до rates_total, представляющего собой общее количество предоставленных точек ценовых данных. Этот метод позволяет избежать ошибок, которые могут возникнуть при попытке доступа к несуществующим точкам данных (например, отрицательным значениям индекса). У каждого бара на графике есть скользящая средняя, систематически определяемая циклом, которая затем соответствующим образом обновляет буфер индикатора.
Чтобы сохранить накопленную сумму высоких цен за заданный период времени (в данном случае 200), мы инициализируем переменную сумму внутри цикла. Вложенный цикл for проходит по последним 200 барам от 0 до period_ma200. Sum += high[i - j]; используется в каждой итерации для прибавления максимальной цены определенного бара к переменной суммы. Двигаясь назад от текущего индекса i, формула i - j гарантирует, что мы суммируем максимальные цены последних 200 баров. Эта процедура эффективно суммирует все максимальные цены за указанный период.
Получив сумму максимальных цен за 200 периодов, мы делим эту сумму на длину периода, чтобы получить среднее значение: buffer_mA200[i] = sum / period_ma200; Вычисленное значение скользящей средней для каждого бара впоследствии представляется этим окончательным значением, которое затем сохраняется в соответствующем индексе buffer_mA200. Вычисляя среднее значение последних 200 максимальных цен, скользящая средняя сглаживает колебания цен и позволяет трейдерам выявлять долгосрочные закономерности. Хотя другие скользящие средние используют другие типы цен (закрытие и открытие) и периоды (100 и 50), для них справедливы те же рассуждения.

3.2. Построение индикатора скользящей средней в виде свечей
В этом разделе мы разработаем другой тип индикатора скользящей средней, который использует формат свечей для отображения движения цен. Этот индикатор будет использовать пятипериодную скользящую среднюю и использовать свечи вместо линий для графического отображения своих значений. Представляя данные скользящей средней таким образом, мы можем более успешно отфильтровывать рыночный шум и выделять краткосрочные тренды. Это позволит сохранить основы расчетов скользящей средней, одновременно предлагая особую точку зрения на движение цен.
Цена открытия, цена закрытия, максимальная цена и минимальная цена — это четыре основных ценовых компонента, из которых состоит свеча. Формат свечи требует независимых вычислений скользящей средней для этих четырех значений, в отличие от линейного стиля, для которого требуется только одно значение цены за период (например, закрытие или открытие). Соответственно, нам требуется минимум четыре буфера для одного графика, по одному для каждого из скользящих средних значений, которые представляют цены открытия, закрытия, максимума и минимума. Структура этого индикатора гарантирует, что данные скользящей средней представлены таким образом, который максимально точно имитирует реальные модели свечей, что облегчает анализ ценового тренда с использованием хорошо известных визуальных подсказок.
Пример:
#property indicator_separate_window #property indicator_buffers 5 #property indicator_plots 1 //---- plot ColorCandles #property indicator_label1 "Candles" #property indicator_type1 DRAW_COLOR_CANDLES #property indicator_color1 clrGreen, clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- indicator buffers double OpenBuffer[]; double HighBuffer[]; double LowBuffer[]; double CloseBuffer[]; double ColorBuffer[]; int period = 5; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0, OpenBuffer, INDICATOR_DATA); SetIndexBuffer(1, HighBuffer, INDICATOR_DATA); SetIndexBuffer(2, LowBuffer, INDICATOR_DATA); SetIndexBuffer(3, CloseBuffer, INDICATOR_DATA); SetIndexBuffer(4, ColorBuffer, INDICATOR_COLOR_INDEX); PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, period); return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { if(rates_total < period) { Print("Error: Not enough bars to calculate."); return 0; } for(int i = period - 1; i < rates_total; i++) { if(i - period + 1 < 0) continue; double sumClose = 0.0; double sumOpen = 0.0; double sumHigh = 0.0; double sumLow = 0.0; for(int j = 0; j < period; j++) { int index = i - j; if(index < 0) continue; // Prevent out-of-bounds access sumClose += close[index]; sumOpen += open[index]; sumHigh += high[index]; sumLow += low[index]; } if(period > 0) { OpenBuffer[i] = sumOpen / period; HighBuffer[i] = sumHigh / period; LowBuffer[i] = sumLow / period; CloseBuffer[i] = sumClose / period; } else { Print("Error: Division by zero prevented."); return 0; } ColorBuffer[i] = (CloseBuffer[i] >= OpenBuffer[i]) ? 0 : 1; } return rates_total; }
Объяснение:
#property indicator_separate_window #property indicator_buffers 5 #property indicator_plots 1 //---- plot ColorCandles #property indicator_label1 "Candles" #property indicator_type1 DRAW_COLOR_CANDLES #property indicator_color1 clrGreen, clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- indicator buffers double OpenBuffer[]; double HighBuffer[]; double LowBuffer[]; double CloseBuffer[]; double ColorBuffer[]; int period = 5;
Свойства и буферы для пользовательского индикатора, отображающего скользящую среднюю в формате японских свечей, определяются этим кодом. Для свечи обычно требуется четыре буфера: по одному для компонентов цены открытия, максимума, минимума и закрытия. Однако, поскольку для определения и хранения цвета каждой свечи необходим дополнительный буфер (ColorBuffer), этому индикатору требуется пять буферов.
Свойства индикатора
- #property indicator_separate_window гарантирует, что индикатор будет отображаться в отдельном окне, а не на графике цены.
- #property indicator_buffers 5 определяет количество используемых буферов. Несмотря на то, что для свечи требуется всего четыре буфера (открытие, максимум, минимум и закрытие), пятый буфер необходим для назначения цвета каждой свече.
- #property indicator_plots 1 указывает, что индикатор имеет только один график, на котором будут использоваться цветные свечи.
Настройки отрисовки и визуализации
- indicator_label1 "Candles" дает название графическому элементу.
- indicator_type1 DRAW_COLOR_CANDLES задает тип отрисовки, равный цветным свечам. В отличие от DRAW_LINE для этого типа требуются значения Open, High, Low и Close, а также индекс цвета.
- indicator_color1 clrGreen, clrRed назначает зеленый цвет бычьим свечам и красный — медвежьим свечам.
- indicator_style1 STYLE_SOLID обеспечивает четкие края свечей.
- indicator_width1 1 определяет толщину контура свечи.
Почему пять буферов вместо четырех?
Типичная структура свечи требует четырех буферов:
- OpenBuffer[] хранит скользящие средние цен открытия.
- HighBuffer[] хранит скользящие средние максимальных цен.
- LowBuffer[] хранит скользящие средние минимальных цен.
- CloseBuffer[] хранит скользящие средние цен закрытия.
Однако, поскольку индикатор использует цветные свечи, ему также необходим пятый буфер:
- ColorBuffer[] хранит цветовой индекс (0 для зеленого, 1 для красного). Благодаря дополнительному буферу скользящая средняя графически представлена медвежьими (красными) и бычьими (зелеными) свечами, что облегчает выявление ценовых паттернов.
//--- indicator buffers mapping SetIndexBuffer(0, OpenBuffer, INDICATOR_DATA); SetIndexBuffer(1, HighBuffer, INDICATOR_DATA); SetIndexBuffer(2, LowBuffer, INDICATOR_DATA); SetIndexBuffer(3, CloseBuffer, INDICATOR_DATA); SetIndexBuffer(4, ColorBuffer, INDICATOR_COLOR_INDEX); PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, period);
Для сохранения определенных значений скользящей средней в формате свечей этот раздел кода сопоставляет буферы индикатора. Этот вариант скользящей средней в виде свечей использует четыре буфера (OpenBuffer, HighBuffer, LowBuffer и CloseBuffer) для хранения эквивалента скользящей средней цен открытия, максимума, минимума и закрытия, в отличие от традиционной линейной версии, которой требуется только один буфер для хранения рассчитанных значений для построения графика.
Пятый буфер, называемый ColorBuffer, также используется для определения цвета каждой свечи, различая медвежьи (красные) и бычьи (зеленые) свечи. Чтобы гарантировать правильную обработку и отображение данных индикатором, функция SetIndexBuffer() связывает каждый буфер с отдельным индексом графика. Чтобы предотвратить построение неполных или вводящих в заблуждение элементов, PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, period); гарантирует, что индикатор начнет построение графика только после того, как будет доступно достаточное количество баров.
if(rates_total < period) { Print("Error: Not enough bars to calculate."); return 0; } for(int i = period - 1; i < rates_total; i++) { if(i - period + 1 < 0) continue; double sumClose = 0.0; double sumOpen = 0.0; double sumHigh = 0.0; double sumLow = 0.0; for(int j = 0; j < period; j++) { int index = i - j; if(index < 0) continue; // Prevent out-of-bounds access sumClose += close[index]; sumOpen += open[index]; sumHigh += high[index]; sumLow += low[index]; } if(period > 0) { OpenBuffer[i] = sumOpen / period; HighBuffer[i] = sumHigh / period; LowBuffer[i] = sumLow / period; CloseBuffer[i] = sumClose / period; } else { Print("Error: Division by zero prevented."); return 0; } ColorBuffer[i] = (CloseBuffer[i] >= OpenBuffer[i]) ? 0 : 1; } return rates_total;
Этот сегмент кода начинается с определения того, имеется ли достаточно ценовых баров для продолжения вычислений. Имеется достаточно точек исторических данных (или "баров") для вычисления скользящего среднего на основе определенного пользователем периода благодаря условию if (rates_total < period). Функция возвращает 0 и выводит сообщение об ошибке, если баров недостаточно. Этот шаг крайне важен, поскольку без достаточных данных невозможно выполнить осмысленный расчет скользящего среднего, а попытка сделать это может привести к получению неточной статистики.
Цикл for выполняет итерацию по данным о ценах, начиная с индекса period - 1 и доходя до rates_total, после того как будет проверено, что имеется достаточное количество баров. Каждый бар обрабатывается циклом, который начинается в назначенное время и продолжается. В этом цикле текущий индекс бара представлен переменной i. Используя информацию о ценах из баров за предыдущий период, этот цикл определяет скользящую среднюю для каждого бара. Цикл гарантирует, что расчет начнется только тогда, когда будет доступно необходимое количество баров, переходя к следующей итерации, если индекс i - period + 1 меньше 0.
Внутри цикла четыре переменные инициализируются значением 0,0: sumClose, sumOpen, sumHigh и sumLow. В этих переменных будут храниться накопленные суммы соответствующих данных о ценах за указанный период. Информация о цене из каждого бара внутри периода собирается с использованием второго цикла for, на этот раз повторяющегося от 0 до period -1. Вычитая j из текущего индекса i, внутренний цикл извлекает каждый из предыдущих баров и вычисляет сумму цен закрытия, открытия, максимума и минимума за указанный период. Цикл позволяет избежать неверных данных, используя условие if(index < 0) для предотвращения доступа к записям в массивах, выходящим за пределы допустимого диапазона.
Чтобы избежать деления на ноль, код определяет, больше ли период нуля, после сбора данных о ценах за период. Код определяет среднее значение цен открытия, максимума, минимума и закрытия за период и сохраняет результат в буферах OpenBuffer, HighBuffer, LowBuffer и CloseBuffer, если период допустим. Вычисленные значения свечей сохраняются в этих буферах. Наконец, цвет свечи задается путем обновления ColorBuffer. Свеча окрашивается в зеленый цвет (значение 0), когда цена закрытия больше или равна цене открытия, что означает бычий тренд; если цена закрытия меньше или равна цене открытия, свеча окрашивается в красный цвет (значение 1), что означает медвежий тренд.
Значение rates_total, которое указывает MetaTrader, сколько баров было успешно обработано, возвращается в конце функции OnCalculate. Для последующих вызовов метода OnCalculate это значение имеет решающее значение, поскольку оно отслеживает количество обработанных баров и гарантирует правильную обработку обновлений данных в реальном времени.

Работая со свечным форматом, мы также заложили основу для более продвинутых индикаторов, таких как графики Хейкин-Аши, которые будут рассмотрены в будущих статьях.
Заключение
В статье были представлены такие базовые концепции, как создание пользовательских индикаторов, использование скользящих средних и визуализация данных в различных форматах, например в виде линий и свечей. Мы также изучили, как использовать буферы и настраивать графические элементы для представления данных. В будущих статьях мы сосредоточимся на еще более интересных проектах. Лучший способ обучения для новичков — это проектный подход, который разбивает обучение на выполнимые этапы, не перегружая ненужными подробностями. Этот метод обеспечивает постепенное продвижение и более глубокое понимание ключевых понятий.
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/17096
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Единый мультитаймфреймовый Ренко: Синтез временных измерений рынка
Возможности Мастера MQL5, которые вам нужно знать (Часть 55): SAC с приоритетным воспроизведением опыта
Моделирование рынка (Часть 13): Сокеты (VII)
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Спасибо за усилия. Исреал. Спасибо.
Я хотел бы прокомментировать эту часть серии по настройке индикатора.
Вы не использовали prev_calculated. Это означает, что при каждом тике
ваш код будет пересчитывать каждый предыдущий рассчитанный бар заново.
Вы не использовали prev_calculated. Это означает, что при каждом тике
ваш код будет пересчитывать каждый предыдущий рассчитанный бар заново.