Наши рекомендации:

  1. Главная
  2. Уроки MQL4
  3. 2.9 Создаем информационную панель с сигналами индикаторов на вход. Графические объекты OBJ_RECTANGLE_LABEL, OBJ_LABEL

2.9 Создаем информационную панель с сигналами индикаторов на вход. Графические объекты OBJ_RECTANGLE_LABEL, OBJ_LABEL

Доброго времени суток!

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

Создаем информационную панель

Для начала нам необходимо придумать какую либо ТС. Для этого примера я решил использовать данные трех простых индикаторов: MA, RSI и Bollinger Bands.

Логика данной ТС будет следующая:

  1. Если Moving Average указанного периода выше текущей цены — сигнал на продажу. Если ниже — на покупку.
  2. Если RSI находится выше отметки 60 (т.е. в зоне перекупленности) — сигнал на продажу. Если ниже 40 (т.е. в зоне перепроданности)  — на покупку.
  3. Если цена пересекла верхнюю линию BB, либо отходит от нее не больше, чем на 30% от всей ширины канала — сигнал на продажу. Если же цена пересекла нижнюю линию BB, либо рядом с ней, но не более 30% от всей ширины канала — сигнал на покупку.

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

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

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

Вводим переменную PipsDivided на глобальном уровне, а также массив SymbolsList, который в последствии будет содержать в себе наш список пар.

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

Далее нам необходимо переписать данные стринговой переменной AllSymbols в пользовательский массив. Для этого вначале нужно воспользоваться строковой функцией StringSplit, чтобы разбить текст на элементы с указанным разделителем. В нашем случае разделитель это знак запятой «,». Его необходимо перевести в целый тип данных ushort с помощью функции StringGetCharacter.

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

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

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

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

Создаем функцию построения прямоугольного лейбла:

Пишем функцию создания текстовой метки:

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

В первой функции RectLabelCreate создается объект с именем «DV|Rect1″ по заранее определенным мною координатам Х и Y с уже заданной шириной и высотой. Цвет темно серый, тип рамки BORDER_RAISED и левый верхний угол привязки. т.е. ноль. Пять функций out_Label создают заголовки с заданным именем объекта, текстом, типом шрифта, координатами и цветом. Расположение элементов на графике по Х и Y подбирается скрупулёзно вручную. Т.е. указываются цифры по обоим осям, смотрится, как это выглядит в терминале и при необходимости значения правятся.

В итоге полностью функция OnInit будет будет иметь вид:

А промежуточный код индикатора будет выглядеть на графике так:

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

Объявляется она в функции OnDeinit. Общий текст в имени всех наших объектов будет «DV|», т.е. сокращение от названия нашего проекта DaVinci FX. Соответственно, все элементы с этим текстом будут сразу же удалены после снятия советника с графика, тогда как остальные пользовательские элементы останутся не тронутыми.

Пишем код расчета индикаторов с дальнейшим построением лейблов

Переходим к функции OnCalculate. В ней будет выполняться расчет данных индикаторов и обновление их на графике каждый тик. При построении и смещении лейблов на графике нам нужны координаты Х и Y, которые будут меняться по мере перехода к новой строке/колонке. Зададим их.

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

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

Продолжаем заполнять тело цикла for расчетами для каждой колонки по очереди: Spread, MA, RSI и BB. Дальнейший код пишем вместо трех точек, что я указал выше. Начнем с расчета спреда. Создаем переменную Spread и узнаем его значение через функцию MarketInfo. Поделим полученное значение на переменную PipsDivided, чтобы преобразовать его в старые пункты. Чтобы зрительно видеть максимально допустимый спред разделим цвет лейблов на красный и зеленый. Допустим, что при спреде ниже или равен 1.5 пункта лейбл должен сигнализировать о том, что условия входа в сделку благоприятные. А при значении выше — цвет будет красный.

Если спред по всем вашим парам завышен, подумайте о новом, более подходящем брокере.

Скомпилируйте полученный код, индикатор должен отобразить следующее:

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

Ее тип будет SMA, построение по цене закрытия, период будет считываться из настроек. Соответственно у нас может быть три условия:

  • Если МА выше текущей цены с отступом в 5 пунктов — сигнал на продажу.
  • Если МА ниже текущей цены с отступом в 5 пунктов — сигнал на покупку.
  • Если МА находится рядом с ценой — пропускаем сигнал.

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

Показания индикатора Moving Average мы получаем с помощью уже известной нам встроенной функции iMA. В параметры передаем текущий символ из массива, текущий таймфрейм (т.е. ноль), период из внешних настроек, метод усреднения SMA и цену закрытия для расчета. Данные будут браться для текущего (нулевого) бара.

Как я уже говорил, после работы с колонкой одного индикатора необходимо делать отступ по оси X, чтобы перейти к следующей колонке. В нашем случае это 60 пикселей. Также, если вас не устраивают внешний вид выбранных мною стрелочек направления сигнала, вы можете заменить их на номера 224, 225 и 226, либо вообще отобрать свой набор символов из таблицы шрифта Wingdings.

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

  1. Значение линии индикатора больше или равно 60. Тогда сигнал на продажу и стрелочку создаем с направлением вниз красного цвета.
  2. Значение линии индикатора меньше или равно 40. Тогда сигнал на покупку и стрелочку создаем с направлением вверх зеленого цвета.
  3. Иное. Если ни одно из двух условий не совпадет, то создается горизонтальная стрелка серого цвета — сигнала нет.
Значения 40 и 60 можно изменить, а также вынести во внешние переменных, это уже на ваше усмотрение.

Сделали отступ по оси Х и сразу дописываем строки для расчета последнего индикатора Bollinger Bands. Данный трендовый индикатор создает три линии: центральную, созданную по данными Moving Averages и две линии над и под ним с указанным отклонением. Нам нужны две линии канала. Создадим две переменные и с помощью функции iBands получим необходимые значения. Задаем следующие параметры: символ из массива, ТФ, период индикатора и отклонения из внешних переменных, нулевой сдвиг, цену закрытия для расчета и индекс линии индикатора. В нашем случае это две константы MODE_UPPER и MODE_LOWER для верхней и нижней линии канала соответственно.

Условие входа, которое я писал вначале немного сумбурное, но так даже интереснее. Для сигнала на продажу мы учитываем два условия на выбор:

  1. Чтобы цена пересекла границу верхнего канала и была выше его.
  2. Чтобы цена располагалась внутри канала, но на расстоянии в заданном пределе от верхней границы. Будем использовать процент расстояния от этой границы до нижнего канала. Т.е. если представить, что ширина всего канала равна 100%, то для сигнала в продажу наша цена должна отходить от верхнего канала не больше, чем на 30%. Для наглядности скриншот:

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

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

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

В итоге тело заполненной функции OnCalculate будет иметь вид:

Законченная информационная панель будет выглядеть так:

Заключение

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

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

Данным уроком я заканчиваю второй раздел, посвященный созданию индикаторов. Этот и предыдущие уроки вполне раскрывают возможности терминала в плане работы с ними. Следующий, третий раздел своего курса обучения языку MQL4 я посвящу созданию и работе с Советниками.

Хочу заменить, что мои уроки созданы для публикации только на сайте команды DaVinci FX Group и предоставляются бесплатно.

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

0. Начало работы

4 комментария. Оставить новый

  • Андрей
    20.12.2020 12:27

    Привет, отличная статья.
    К сожалению кнопка для скачивания кода не кликабельная.

    Ответить
  • Леонид
    31.01.2021 15:52

    Здравствуйте.
    Подскажите, есть ли возможность прокруткой мыши двигать по вертикали OBJ_RECTANGLE_LABEL
    Спасибо.

    Ответить
    • Добрый день. Объект OBJ_RECTANGLE_LABEL привязан к графику по осям Х и Y, он не смещается при изменениях на графике.
      Если вам нужен объект с привязкой к цене и времени, то используйте тип объекта OBJ_RECTANGLE

      Ответить

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Заполните поле
Заполните поле
Пожалуйста, введите корректный адрес email.
Вы должны согласиться с условиями для продолжения

Меню