Язык MQL — Урок 13 «Работа с графическими объектами MT4»

Добрый день, Уважаемые подписчики!

Сегодня я публикую очередной урок по пришедшему мне вопросу:

Уважаемый Александр.
Имеется ли в MQL4 возможность работать с такими графическими объектами MetaTraderа, как трендовые, вертикальные и горизонтальные линии, каналы и т.д., имеющими в среде MetaTrader собственные имена и параметры? Если да — рассажите об этом в одном из своих уроков.

Давайте рассмотрим как работать с объектами MetaTraderа 4 на примере трендовой линии. Существует множество стратегий форекс, основаных на трендовых линиях. Например Стратегия форекс “3 касания” или Стратегия форекс “Trend Lines” и т.д. Обычно работают такие трговые стратегии на отскок цены от трендовой линии или на пробой трендовой линии. Рассмотрим как написать советника MT4 который будет отслеживать приближение цены к трендовой линии и открывать ордера с целью получить прибыль при ее отскоке. Конечно советник не будет полностью автоматическим. Трейдеру придется в ручную рисовать трендовую линию, но сидеть ждать подхода цены к трендовой линии будет не нужно.

Для начала определимся с параметрами, что нам нужно настраивать:
— риск для расчета лота
— тейкпрофит
— стоплосс
— расстояние от трендовой линии до установки ордера (цена может несколько пунктов не дойти до трендовой линии)

Подключим нашу библиотеку MyLib и укажем внешние параметры:
//+——————————————————————+
//|                                                    TrendLine.mq4 |
//|                                                Copyright c 2010. |
//|                                                http://strategy4you.ru |
//+——————————————————————+
#property copyright «Copyright c 2010.»
#property link      «http://strategy4you.ru»
#include  <MyLib.mqh>
extern int    MaxRisk=2;
extern int    TakeProfit=600;
extern int    StopLoss=30;
extern int    Delta=5;
//+——————————————————————+
int init() {return(0);}
//+——————————————————————+
int deinit() {Comment(«»);return(0);}
//+——————————————————————+
int
start()
{
return
(0);}
//+——————————————————————+

Проверим что есть трендовая линия и она в единственном экземпляре:
 if(ObjectsTotal(OBJ_TREND)!=1)
{Comment(«Нарисуйте 1 трендовую линию!»);
return(0);}

Получим ИМЯ трендовой линии:
for(int i=0;i<ObjectsTotal();i++)
{string name=ObjectName(i);
if(ObjectType(name)==OBJ_TREND) break;}

Проверим что трендовая линия нарисована правильно (по движению цены):
datetime t1=ObjectGet(name,OBJPROP_TIME1);
datetime t2=ObjectGet(name,OBJPROP_TIME2);
if(t1>t2)
{Comment(«Неправильно нарисована трендовая линия!»);
return(0);}

Продолжим линию (свойство луч):
ObjectSet(name,OBJPROP_RAY,true);

Определим тренд (вверх или вниз):
bool trend=false;
double p1=ObjectGet(name,OBJPROP_PRICE1);
double p2=ObjectGet(name,OBJPROP_PRICE2);
if(p1<p2) trend=true;

Определим текущее значение трендовой линии и сообщим ее параметры:
double pr=ObjectGetValueByShift(name,0);
Comment(«Name=»,name,»   Trend=»,trend,»   Value=»,pr);

Осталось подсчитать количество открытых ордеров и если их нет и цена подошла к трендовой линии открыть ордер.
Подсчитаем кол-во ордеров:
int oBuy=0,oSell=0;
for(i=OrdersTotal()-1;i>=0;i—)
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol())
{if(OrderType()==OP_BUY) oBuy++;
if(OrderType()==OP_SELL) oSell++;}

Если нет ордеров и цена подошла к трендовой линии — откроем ордер:
double tp=0,sl=0;
double Lot=GetLot(MaxRisk);
if(Lot==0.0) {Alert(«Недостаточно средств!»);return(0);}
if(oBuy+oSell==0 && trend && Bid>=pr && Bid<=pr+Delta*Point)
{if(TakeProfit>0) tp=Ask+TakeProfit*Point;
if(StopLoss>0) sl=Ask-StopLoss*Point;
NewOrder(OP_BUY,Lot,Ask,tp,sl);}
if(oBuy+oSell==0 && !trend && Ask<=pr && Ask>=pr-Delta*Point)
{if(TakeProfit>0) tp=Bid-TakeProfit*Point;
if(StopLoss>0) sl=Bid+StopLoss*Point;
NewOrder(OP_SELL,Lot,Bid,tp,sl);}

Советник форекс готов! Осталось его протестировать. Советники форекс подобного типа, тестируют только в визуальном режиме как в Уроке 10 «Работа с внешними индикаторами». Запустим тестирование и нарисуем трендовую линию:

Трендовая линия

Наблюдаем как идет тестирование. Вот цена подошла к трендовой линии и открылся ордер:

Открылся ордер

Далее цена развернулась и подошла к нашему профиту:

Развитие ситуации

В итоге ордер закрылся по тейкпрофиту и мы получили прибыль:

Ордер закрыт

Как видно из тестов, созданный нами эксперт МТ4, работает. Его можно использовать как для торговли, так и для тренировки умения рисовать трендовые линии в тестере стратегий Metatrader 4.

Скачать:  советник TrendLine

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

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

  1. Отличный пример, спасибо!

    Подскажите каким образом можно организовать хранение промежуточных данных(между запусками советника\скрипта\индикатора), в привязке к объектам?

  2. Аркадий
    Для целей хранения данных между запусками в MQL существуют «глобальные переменные». Функция GlobalVariableSet() сохраняет значение, а GlobalVariableGet() извлекает. Посмотреть их можно нажав клавишу F3 в терминале или через меню: Сервис-Глобальные переменные.

  3. palt, т.е. спасибо за ответ!

    Я посмотрел эту функцию она может сохранять только double значения.

    Можно ли как то организовать сохранение чего то вроде Hashmap ? т.е. по 1 ключу сохранить структуру в которой будут и даблы и инты и строчки?

  4. Аркадий
    В таком случае советую почитать про работу с файлами. Функции: FileOpen(), FileClose(), FileWrite() и т.д.

  5. palt, Да видимо придется делать через файлы, может в mt5 с этим что то придумают, в любом случае спасибо за ответ!

  6. Здравствуйте, подскажите пожалуйста почему у меня вылазиет ошибка
    ‘MyLib.mqh’ — cannot open the program file
    вроде бы делал все как написано, может пропустил чего..

  7. Уважаемый Александр.
    Не могли бы вы подсказать:
    Почему при запросе:
    datetime t1=ObjectGet(name,OBJPROP_TIME1);
    t1 присваивается 10-тизначное значение. И совсем не похожее на тип datetime — значение даты и времени (например: 01.01.2010 12:00).

    С Уважением.

  8. ДЕНЬ ДОБРЫЙ! ВЫ ПРОДЕЛАЛИ ОГРОМНУЮ И НУЖНУЮ РАБОТУ ПО ОБУЧЕНИЮ НОВИЧКОВ КОИМ САМ И ЯВЛЯЮСЬ. ХОЧУ ВАС ЗА ЭТО ИСКРЕННЕ ПОБЛАГОДАРИТЬ !!!
    Я С ВОПРОСОМ ПО СОВЕТНИКУ ОПИСАНОМУ ВЫШЕ. ПОСЛЕ ПОЛУЧЕНИЯ ПРИБЫЛИ ОН ЗАКРЫВАЕТСЯ — УРА!!!
    А ЕСЛИ СОВЕТНИК ЗАКРОЕТСЯ С УБЫТКОМ, ЧТО ПРОИЗОЙДЁТ ДАЛЬШЕ?
    И ГЛАВНЫЙ ВОПРОС — ЕСЛИ ЗАКРОЕТСЯ С УБЫТКОМ — КАК СДЕЛАТЬ ЧТОБЫ СОВЕТНИК ОТКРЫЛСЯ ВНОВЬ ТАМ ЖЕ ГДЕ ОТКРЫВАЛСЯ В ПЕРВЫЙ РАЗ???
    БЛАГОДАРЮ вАС ЗА ОТВЕТ
    С УВАЖЕНИЕМ, ВЯЧЕСЛАВ .

  9. Это тип datetime (содержит время в секундах, прошедшее с 01.01.1970). Чтобы привести к читаемуму виду надо воспользоваться функцией TimeToStr();

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

  11. Установил на MT4 советник Trend Line. Когда переношу его на график то ничего не происходит с графиком, лишь в правом верхнем углу появляется название советника? Как заставить его заработать? Как ???

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

  13. Спасибо вам за уроки, щас пытаюсь создать своего робота… с нетерпением жду продолжения….

    Вопрос может не по теме — подскажите пожалуйста правильный пример функции «подгона стопа», то есть если цена подошла к +20 пунктов от цены открытого ордера, стоп подставился на +10, и так постоянно до закрытия….

    Заранее спасибо!

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

  15. виталий
    Вот пример простого трала:
    int TrailingStop=10;
    int TrailingStep=10;
    for(int i=OrdersTotal()-1;i>=0;i—)
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
    {if(OrderType()==OP_BUY)
    if(Bid-OrderOpenPrice())>TrailingStop*Point)
    if(OrderStopLoss()TrailingStop*Point)
    if(OrderStopLoss()>Ask+(TrailingStop+TrailingStep-1)*Point || OrderStopLoss()==0)
    EditOrder(Ask+TrailingStop*Point);}

  16. Спасибо за проделанную работу!
    Не могли бы вы подсказать, может я что-то не понимаю.
    Делаю простой скрипт на демо в Финаме, что бы показывал цену Alert(BId);
    Все работает, но почему-то выводит цену с 4 знаками после запятой, хотя котировки идут с 5 знаками на паре EURUSD. Так же расчеты iMA идут тоже с 4 знаками , а не с 5-ю.
    Что делаю не правильно, подскажите????

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

    Заранее спасибо!

  18. а зачем в советнике эти строки:

    int oBuy=0,oSell=0;
    for(i=OrdersTotal() −1;i>=0;i—)
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
    if(OrderSymbol()==Symbol())
    {if(OrderType()==OP_BUY) oBuy++;
    if(OrderType()==OP_SELL) oSell++;}

    если количетво ордеров можно подсчитать с помошью OrdersTotal() ???

  19. Прикольно! Но почему только 1 линия? Ведь какаято древняя линия может быть хорошим уровнем потдержки-сопротивления. Можно ли сделать так чтобы советник работал на нескольких линиях?

  20. извините. А как сделать, что бы советник ищё принимал 2 линию тренда? Вот например я нарисовал линию тренда. И советник уже сельнул по ней. но потом вижу, что уже тренд восходящий и хочу нарисовать линию восходящий тренда. Но советник его не принимает. Я удалил линию тренда, нарисовал новою, но сделка по старой линий тренда ищё стоит. Я рисую другую линию тренда и советник открывает позицию закрываю предыдущую. А я хочу сделать так, что бы советник закрывал сделку при открытия противоположной.

  21. Вот пример простого кода. Я рисую на графике 4 горизонтальных линии и программно хочу считывать цену по этим линиям. Подскажите, почему этот код для pr[i] выводит нули? Названия линий выводятся корректно, но вот цена по этим линиям =0. Спасибо.

    string name[4];
    double pr[4];
    for(int i=0;i<ObjectsTotal(OBJ_HLINE);i++)
    {
    name[i]=ObjectName(i);
    pr[i]=ObjectGetValueByShift(name[i],0);
    }
    Comment(StringConcatenate(name[0],» : «,DoubleToStr(pr[0],5),» || «,name[1],» : «,DoubleToStr(pr[1],5),» || «,name[2],» : «,DoubleToStr(pr[2],5),» || «,name[3],» : «,DoubleToStr(pr[3],5)));

    Результат: «Линия 1 : 0.00000 || Линия 2 : 0.00000 || Линия 3 : 0.00000 || Линия 4 : 0.00000»

  22. В примере простого трала, в строке if(OrderStopLoss()TrailingStop*Point) пропущено условие

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

  24. Александр, доскажите пожалуйста в чем ошибка кода и по чему не работает? Также хотел бы узнать у вас есть ли вероятно того, что можно добавить в код по барам? Например: бычий, бычий, медвежий, бычий, бычий. Заранее спасибо за ответ! С уважением, Олег Михайлович

  25. У меня вопрос к поиску OBJ_TREND, а можно как то определить выборку этих ОBJ_ , например, поиск N имени(или описания) объекта по цвету на N временном участке mql4?

    а то у меня например их много, и остальные убирать нехочется

    Подскажите

  26. У меня вопрос к поиску OBJ_TREND, а можно как то определить выборку этих ОBJ_ , например, поиск N имени(или описания) объекта по цвету на N временном участке ?

    а то у меня например их много, и остальные убирать нехочется

    Подскажите

  27. Здравствуйте, Александр.
    Подскажите пожалуйста, возможно ли отображение фигуры поверх графика, и на этой фигуре чтобы был текст? просто когда текст выводится на экран, то он сливается с графиком и поручения которые стоят тоже сильно перекрывают информацию которую вывожу, а мне важно видеть эту информацию, она должна всё время обновляться, поэтому Alert тут не поможет, только функция comment

  28. и ещё хотелось бы чтобы он фигура, к примеру прямоугольник, отображалась в левом правом углу
    Заранее спасибо!

  29. Если лень строить линию тренда вручную, для этого есть индикатор: «линия тренда Тома Демарка (TD)». Он автоматически строит линию тренда

  30. Здравствуйте! Подскажите, пожалуйста, как можно написать советник, чтобы он торговал при изменении цвета индикатора, для примера Хейкен Аши или другого цветного? Заранее благодарен за ответ!

  31. Отличные уроки!!!! Пару дней назад случайно наткнулся на этот сайт, огромное спасибо за ваш труд!!!

  32. здравствуйте,Я пользуюсь советником (e-MovingInWL2—перевод в безубыток всех ордеров),
    очень помогает в торговле,
    мне нужна Ваша помощь— добавить еще один параметр в этот же Советник
    — перевод в безубыток всех ордеров через определенное время (например через 2 часа)
    уровень безубытка одинаковый и для прохождения по тикам и по времени,

    Буду очень Вам благодарен

    С уважением
    Лева

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

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