Язык MQL — Урок 11 «Как создать свой индикатор?»

На прошлом уроке по изучению языка MQL4 мы научились использовать индикаторы Forex в своих советниках для MT4. Но сразу возникает вопрос: «А как быть, если мы не нашли необходимого нам индикатора?» — Конечно же мы его можем написать сами на языке MQL4.

Поэтому на сегодняшнем уроке мы будем изучать: «Как создать свой индикатор для MT4».

Возьмем для примера «Стратегию форекс на внутреннем Баре». Прочитав данную стратегию — мы понимаем что нам не хватает подсветки этого самого «внутреннего бара».

Давайте исправим эту ситуацию, написав свой индикатор форекс.

Запускаем мастер создания советников в MetaEditor:

Мастер создания индикаторов

Назовем наш создаваемый индикатор форекс — «inBar» и добавим параметр для изменения цвета подсветки:

Параметры индикатора

Следующее окно оставим без изменений:

Назначение буферов вывода

После нажатия кнопочки «Готово» получим пустой шаблон индикатора для Metatrader4:

//+——————————————————————+
//| inBar.mq4 |
//| Copyright © 2010. |
//| http://strategy4you.ru |
//+——————————————————————+
#property copyright «Copyright © 2010.»
#property link «http://strategy4you.ru»
#property indicator_chart_window
extern color BoxColor=Red;
//+——————————————————————+
int init() {return(0);}
//+——————————————————————+
int deinit() {return(0);}
//+——————————————————————+
int start()
{int counted_bars=IndicatorCounted();
return(0);}
//+——————————————————————+ 

Я снова удалил лишнии комментарии для наглядности. Теперь читаем определение «внутреннего бара»:

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

Отсюда делаем вывод: необходимо анализировать 2 свечи. Причем High предыдущей свечи должен быть больше High следующей и Low предыдущей должен быть меньше Low следующей.

В MQL индексы свечей идут в обратном порядке (0 — это последяя свеча, 1 — предыдущяя и т.д.). Запишем условие:

if(High[i]<High[i+1] && Low[i]>Low[i+1])

Теперь необходимо в цикле перебрать все свечи и подсветить удовлетворяющие условию:

for(int i=0; i<limit; i++)
if(High[i]<High[i+1] && Low[i]>Low[i+1])
{string name=«inBar»+TimeToStr(Time[i]);
ObjectDelete(name);
ObjectCreate(name,OBJ_RECTANGLE,0,Time[i],High[i+1],Time[i+1],Low[i+1]);
ObjectSet(name,OBJPROP_BACK,true);
ObjectSet(name,OBJPROP_COLOR,BoxColor);}

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

ObjectSet(name,OBJPROP_BACK,true);

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

Осталось прояснить — сколько свечей нам надо проанализировать. Ведь индикатор перерисовывается при каждом тике (поступлении котировки). И если мы будем анализировать всю историю котировок каждый раз — компьютер станет очень сильно тормозить.

Разработчики позаботились и об этой проблеме. В языке MQL существует функция IndicatorCounted() которая возвращает количество баров, не измененных после последнего вызова индикатора. Отняв от общего количества баров (Bars) количество баров не измененных после последнего вызова индикатора получим количество измененных. Но нам надо анализировать 2 свечи. Поэтому добавим условие:

if(counted_bars>0) counted_bars—;

Если нет не измененных баров — анализируем все. А если хоть один бар изменится (изменяется только последний бар), то проанализируем на 1 бар больше.

Наша функция start() приобретает следующий вид:

int start()
{int limit;
int counted_bars=IndicatorCounted();
if(counted_bars>0) counted_bars—;
limit=Bars-counted_bars;
for(int i=0; i<limit; i++)
if(High[i]<High[i+1] && Low[i]>Low[i+1])
{string name=«inBar»+TimeToStr(Time[i]);
ObjectDelete(name);
ObjectCreate(name,OBJ_RECTANGLE,0,Time[i],High[i+1],Time[i+1],Low[i+1]);
ObjectSet(name,OBJPROP_BACK,true);
ObjectSet(name,OBJPROP_COLOR,BoxColor);}
return(0);}

Компилируем и присоединяем наш индикатор для Metatrader 4 «inbar» к графику:

График с индикатором

Мы добились чего хотели. Внутренние бары индикатор для нас подсвечивает. Но при удалении индикатора с графика — подсветка остается — Непорядок…

Это может нам помешать при работе с другими индикаторами. Для исправления данной ситуации можно просто удалить все нарисованные прямоугольники: ObjectsDeleteAll(0,OBJ_RECTANGLE) в функции деинициализации deinit().

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

Поэтому мы используем другой метод: будем удалять только те прямоугольники — которые сами нарисовали. Они имеют у нас уникальное имя с постоянной частью: string name=«inBar»+TimeToStr(Time[i]);

Вот по этой части и будем их находить и удалять:

int deinit()
{for(int i=ObjectsTotal()-1;i>=0;i—)
{string name=ObjectName(i);
if(StringFind(name,«inBar»)==0) ObjectDelete(name);}
return(0);}

Теперь можно работать с нашим индикатором не боясь что-то испортить.

Скачать: Индикатор форекс «InBar»

Похожие статьи:

18 комментариев

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

  2. все правельно, смотрю сегодня что то поменялось на сайте, прямо какой то хаус, и сейчас начинаю сомневаться что я эти уроки читал. А есть ли какие координаты для общения? У меня есть архив сделок, по одной стратегии, хотелось бы узнать ваше мнение на сколько реально глядя по истории счета написать стратегию… в принципе еще есть куча вопросов, жалко что общение на данном форуме будет занимать очень много времени. Сама идея создания данного сайта мне понравилась — а Вы молодцы!! Ничего подобного вроде я больше не нашел

  3. Здравствуй, Александр!

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

  4. Добрый день!
    К сожалению в MQL4 нет возможности определить: выделен объект или нет. Кроме того, может быть выделено несколько объектов. Поэтому объекты идентифицируются по имени. Все остальные свойства можно получить зная имя объекта. Если имя не известно, но известно что объект данного типа один на графике, то можно получить его имя простым перебором:
    for(int i=0;i<ObjectsTotal();i++)
    {string name=ObjectName(i);
    if(ObjectType(name)==OBJ_HLINE) Alert(name);} //находим горизонтальную линию

  5. Здравствуйте Александр! Хотел написать индикатор для МТ, но если честно затруднился, может и на элементарных вещах. Написание его в Metastock выглядит вот так » (Mov(C,5,S) — Mov(C,14,S)/ Mov(C,14,S)*100) » . По русски: (МА(по закрытию, период5, SEMPLE) — МА(закрытие, 14, SEMPLE) деление на МА(закрытие, 14, SEMPLE) умножение на 100). Как это реализовать в МТ ни как не соображу. Если возможно объясните в какую сторону рыть.
    P.S. В Metastock это реализовано проще.

  6. Олег
    Так и пишите как описали «по русски»: iMA(NULL,0,5,0,MODE_SMA,PRICE_CLOSE,0)-iMA(NULL,0,14,0,MODE_SMA,PRICE_CLOSE,0)/iMA(NULL,0,5,0,MODE_SMA,PRICE_CLOSE,0)*100

  7. Cдраствуйте palt.
    Ваш индикатор хорош, но его каждый раз нужно
    перезагружать, чтобы коретно отображалось для
    чего он был сосдан. Я немного подправил и теперь
    работает корекно. Нужно всеволеш заменить (0 на 1)
    Было for(int i=0; i<limit; i++)
    стало for(int i=1; i<limit; i++)
    Незнаю как выделить цветом, вопщем разберутся
    кто захочет.

  8. Skoch
    Прекрасно. Значит я своей цели добился. Ученик превзошел учителя 😉

  9. У вас тут ошибка, ссылка ведёт не туда:

    «Возьмем для примера «Стратегию форекс на внутреннем Баре».»

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

  10. Dima
    Ссылку проверил — работает. Форум делать не хочу по той простой причине, что без модерации будет просто свалка, а на модерацию нет времени.

  11. Добрый день! Спасибо Вам большое за Ваш учебник , и за труды. Не подскажите как , имея массив
    Trb[1,0,23,4,0,5,0] -к примеру

    написать функцию SeekMaxIdx(), которая искала бы
    максимальный индекс , но с условием 0. Спасибо большое!

  12. Добрый день! Спасибо Вам большое за Ваш учебник , и за труды. Не подскажите как , имея массив

    Trb[1,0,23,4,0,5,0] -к примеру

    написать функцию SeekMaxIdx(), которая искала бы

    максимальный индекс , но с условием 0. Спасибо большое!
    (Извините — не корректно что-то получилось 1 раз, пришлось повторить)

  13. Доброго времени суток Александр! А как написать советник по этой стратегии (внутренний бар), с выставлением отложек buy-sell stop?

  14. Здравствуйте! Я в mql чайник, собственно как и в любом другом языке программирования, познания на школьном уровне. Помогите пожалуйста, перелопатил инет, не могу найти то что нужно. Идея в том чтобы найти определенную свечу, открытую/закрытую в определенное время и выдать всю инфу по ней, цена открытия/закрытия, тени. Спасибо!!!

  15. хотелось бы узнать про написание индикаторов для форекс тестера ! Очень эта тема интересна!

  16. Спасибо за уроки.

    Присоединяюсь к:
    «Dima 27.06.2011 в 5:43 11
    У вас тут ошибка, ссылка ведёт не туда: »

    «Возьмем для примера «Стратегию форекс на внутреннем Баре».» — ссылка указывает на эту же страницу.

    Я так понял что была задумка отправить на страницу с описанием стратегии «на внутреннем баре»?

Оставить комментарий

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