Графические объекты

Следуя известному изречению «Лучше один раз увидеть, чем сто раз услышать» в этом уроке научимся работать с тем, что видно на графике — графические объекты.

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

Задача:
Скрипт должен читать историю и расставлять на графике значки как «советник». Значок открытия должен выставится по цене и времени открытия. Значок закрытия поместить на график в точке закрытия ордера (время и цена). Между ними должна быть пунктирная линия, что бы по ее наклону можно визуально определить закрылся ордер в профит или убыток. Значки Buy и Sell ордеров должны быть разного цвета.

Реализация в скрипте:

  • Создаем пользовательский скрипт;
  • В цикле for перебираем поочередно все ордера из истории счета  и расставляем значки:
for(int i = OrdersHistoryTotal()-1; i >= 0; i--)
 {
  if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) == false) continue;

Отбираем только ордера соответствующие финансовому инструменту открытого графика.

if(Symbol() != OrderSymbol()) continue;

Определяем тип ордера и назначаем соответствующий цвет.

switch(OrderType())
 {
  case 0: arr_col = Blue; break;
  case 1: arr_col = Red;  break;
  default: continue;
 }

У каждого графического объекта должно быть оригинальное имя, создаем его.

name = "open_" + OrderTicket();

Создаем объект с помощью функции ObjectCreate.
ObjectCreate (имя, тип объекта, номер окна, время 1, цена 1, время 2, цена 2, время 3, цена 3);
Параметры для объекта:
Имя – оригинальное, двух объектов с одинаковым именем не может быть.
Тип объекта – может быть стрелка, метка, линия и тд.
Номер окна – индекс окна, на которое будет помещен объект. Ноль — основное окно графика.
Время 1 – время первой координаты.
Цена 1 – цена первой координаты.
Время 2 – время второй координаты.
Цена 2 – цена второй координаты.
Время 3 – время третьей координаты.
Цена 3 – цена третьей координаты.
Для объектов, например стрелок, используются только первые координаты (время, цена), линий по две координаты, каналу три пары координат.

Итак, ставим значок (OBJ_ARROW) на график где был открыт ордер, координаты время открытия и цена открытия.

ObjectCreate(name,OBJ_ARROW,0,OrderOpenTime(),OrderOpenPrice());

Указываем, какой именно будет значок, наш имеет код 1.

ObjectSet(name,OBJPROP_ARROWCODE,1);

Коды объектов OBJ_ARROW.

Графические объекты: Часть 1

Окрашиваем в нужный цвет.

ObjectSet(name,OBJPROP_COLOR,arr_col);

Теперь второй значок, где ордер был закрыт. Имя, координаты (время закрытия и цена закрытия), код значка 3, цвет тот же.

name = "close_" + OrderTicket();
ObjectCreate(name,OBJ_ARROW,0,OrderCloseTime(),OrderClosePrice());
ObjectSet(name,OBJPROP_ARROWCODE,3);
ObjectSet(name,OBJPROP_COLOR,arr_col);

И наконец, от одного значка к другому рисуем линию (OBJ_TREND) и задаем ей нужные свойства. Для линии уже нужно две точки координат, начало линии (время открытия, цена открытия) и конец (время закрытия, цена закрытия). Стиль линии пунктирный – STYLE_DOT, ширина – 1 и цвет.

name = OrderTicket();
ObjectCreate(name,OBJ_TREND,0,OrderOpenTime(),OrderOpenPrice(),OrderCloseTime(),OrderClosePrice());
ObjectSet(name,OBJPROP_RAY,0);
ObjectSet(name,OBJPROP_STYLE,STYLE_DOT);
ObjectSet(name,OBJPROP_WIDTH,1);
ObjectSet(name,OBJPROP_COLOR,arr_col);

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

Скрипт видит только историю с вкладки «История Счета» в окне «Терминал». На вкладке можно выбрать период, за который хотите просмотреть историю.

Полный код скрипта:

/+------------------------------------------------------------------+
//|                                      History of transactions.mq4 |
//|                                    Copyright 2013, FinTrader.PRO |
//|                                             |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, FinTrader.PRO"
#property link      "https://fintrader.pro"

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
 {
  color arr_col;
  string name;
  for(int i = OrdersHistoryTotal()-1; i >= 0; i--)
   {
    if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) == false) continue;
    if(Symbol() != OrderSymbol()) continue;
    switch(OrderType())
     {
      case 0: arr_col = Blue; break;
      case 1: arr_col = Red;  break;
      default: continue;
     }
    name = "open_" + OrderTicket();
    ObjectCreate(name,OBJ_ARROW,0,OrderOpenTime(),OrderOpenPrice());
    ObjectSet(name,OBJPROP_ARROWCODE,1);
    ObjectSet(name,OBJPROP_COLOR,arr_col);
    name = "close_" + OrderTicket();
    ObjectCreate(name,OBJ_ARROW,0,OrderCloseTime(),OrderClosePrice());
    ObjectSet(name,OBJPROP_ARROWCODE,3);
    ObjectSet(name,OBJPROP_COLOR,arr_col);
    name = OrderTicket();
    ObjectCreate(name,OBJ_TREND,0,OrderOpenTime(),OrderOpenPrice(),OrderCloseTime(),OrderClosePrice());
    ObjectSet(name,OBJPROP_RAY,0);
    ObjectSet(name,OBJPROP_STYLE,STYLE_DOT);
    ObjectSet(name,OBJPROP_WIDTH,1);
    ObjectSet(name,OBJPROP_COLOR,arr_col);
   }
  return(0);
 }
//+------------------------------------------------------------------+

Мусорить нехорошо, поэтому напишем еще один скрипт, который уберет все объекты с графика.
Здесь нам поможет функция ObjectsDeleteAll, которая удаляет все объекты. Поэтому скрипт предельно простой, нужно вписать только одну строчку.

//+------------------------------------------------------------------+
//|                                             DeleteAllObjects.mq4 |
//|                                    Copyright 2013, FinTrader.PRO |
//|                                             |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, FinTrader.PRO"
#property link      "https://fintrader.pro"

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
 {
  ObjectsDeleteAll();
  return(0);
 }
//+------------------------------------------------------------------+

Далее научимся изменять свойства объекта и получать от него информацию.

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

Зная имя объекта можно с помощью функции ObjectGet(имя, идентификатор свойства объекта) получить значения свойств объекта. И уже знакомой вам функцией ObjectSet изменить свойство объекта на нужное.
Не зная имени объекта нужно организовать цикл для перебора всех объектов на графике, что бы найти нужный.

Функция ObjectsTotal дает общее число объектов на графике.
Функция ObjectName по порядковому номеру возвращает имя объекта из списка.

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

Скрипт Historyoftransactions для каждого ордера рисовал трендовую линию с именем конкретного ордера. Нужно найти трендовую линию соответствующую последнему ордеру, имя линии (номер ордера) должно быть наибольшим.

Номер ордера в числовом значении, а имя объекта имеет тип string, поэтому перед сравнением имя преобразовываем в тип integer StrToInteger(name).

Запускаем цикл, и находим нужный объект.

for(int j = 0; j < ObjectsTotal(OBJ_TREND); j++)
 {
  if(StrToInteger(ObjectName(j)) < StrToInteger(name)) continue;
  name = ObjectName(j);
 }

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

if(ObjectGet(name,OBJPROP_STYLE) == STYLE_DOT)
 {
  Comment(" Последний закрытый ордер:",
          "n Номер ордера: ",name,
          "n Цена открытия: ",ObjectGet(name,OBJPROP_PRICE1),
          "n Цена закрытия: ",ObjectGet(name,OBJPROP_PRICE2),
          "n Время открытия: ",TimeToStr(ObjectGet(name,OBJPROP_TIME1),TIME_DATE|TIME_MINUTES),
          "n Время закрытия: ",TimeToStr(ObjectGet(name,OBJPROP_TIME2),TIME_DATE|TIME_MINUTES));
 }

Полный код скрипта.

//+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|                                    Copyright 2013, FinTrader.PRO |
//|                                             |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, FinTrader.PRO"
#property link      "https://fintrader.pro"

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
 {
  string name = "0";
  for(int j = 0; j < ObjectsTotal(OBJ_TREND); j++)
   {
    if(StrToInteger(ObjectName(j)) < StrToInteger(name)) continue;
    name = ObjectName(j);
   }
  if(ObjectGet(name,OBJPROP_STYLE) == STYLE_DOT)
   {
    Comment(" Последний закрытый ордер:",
            "n Номер ордера: ",name,
            "n Цена открытия: ",ObjectGet(name,OBJPROP_PRICE1),
            "n Цена закрытия: ",ObjectGet(name,OBJPROP_PRICE2),
            "n Время открытия: ",TimeToStr(ObjectGet(name,OBJPROP_TIME1),TIME_DATE|TIME_MINUTES),
            "n Время закрытия: ",TimeToStr(ObjectGet(name,OBJPROP_TIME2),TIME_DATE|TIME_MINUTES));
   }
  return(0);
 }
//+------------------------------------------------------------------+

Пользовательские функции — https://forexlab.ru/mql-user-functions/

You May Also Like