Лень - двигатель прогресса, или Как интерактивно работать с графикой

Vladimir | 12 августа, 2008

Введение

На одном из англоязычных форумов встретил я довольно интересное описание интерпретации фибо уровней. Основная мысль состоит в том, что коррекция импульсного движения стремится к зоне между 38,2 и 61,8 %. Посмотрев выложенный там видеоролик и испробовав самостоятельное построение фибо уровней на графиках, я пришел к использованию этого инструмента в собственной практике.

Я не буду останавливаться на достоинствах или недостатках этой системы. Здесь я хочу сказать о другом. Так как по своей природе я ленив (предполагаю, что в этом я не одинок), и все эти бесконечные построения и перестроения фиб для отыскания на графике этой разворотной зоны мне порядком надоели, решил я переложить часть работы на MQL4.

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

Обработка координат графических объектов

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

Необходимо так же отметить преимущества ручного построения:

Здесь я хочу показать, как реализовать индикатор пересечения построенной вручную линии тренда.

Вначале на любом графике построим линию тренда. Затем находим эту линию в списке объектов. Эта линия называется, например, так: Trendline 29344. Trendline – это определение самой линии, а 29344 – номер, который присвоен терминалом MetaTrader 4 этой линии.

Переименуем линию Trendline в TrDup - это будет линия тренда вверх.

Повторяем снова шаги по созданию еще одной трендовой линии и создаем трендовую линию TrDdown, с помощью которой мы будем показывать тренд вниз.

(индикатор 1_01_Tr_Alert настроен на взаимодействие именно с этими линиями, такие же имена использованы в индикаторе отрисовки трендовых линий демарка TL_by_Demark_v6)

Теперь, нам необходимо на языке MQL4 считать количество объектов, которые имеются на графике

int    obj_total=ObjectsTotal();

в переменной obj_total мы получаем общее количество объектов на графике.

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

// Определяем объект Трендовая линия
int    obj_total=ObjectsTotal();
  string index;
  for(int i=0;i<obj_total;i++)
    {
     index=ObjectName(i);
      string substrTL_down = StringSubstr (index, 0, 7);
            if (substrTL_down == "TrDdown") string TrDLine_down=index;
      string substrTL_up = StringSubstr (index, 0, 5);
            if (substrTL_up == "TrDup") string TrDLine_up=index;
    
    }

и присваиваем их названия строковым переменным TrDLine_down и TrDLine_up.

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

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

if ((Close[1]>ObjectGetValueByShift(TrDLine, 1)) && (Close[2]<ObjectGetValueByShift(TrDLine, 2)))

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

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

Примером может служить индикатор отображения цветовых зон фибо уровней, опубликованный на форуме Оникса: http://www.onix-trade.net/forum/index.php?act=attach&type=post&id=27033&setlanguage=1&langid=ru.

И дополненный индикатор зигзага от nen'a для автоматического построения фибо уровней по последней волне здесь: http://www.onix-trade.net/forum/index.php?act=attach&type=post&id=27175&setlanguage=1&langid=ru.

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

//+------------------------------------------------------------------+
//|                                               1.012_InfoFibo.mq4 |
//|                                                                  |
//|                                                     b2w@narod.ru |
//+------------------------------------------------------------------+
#property copyright "http://www.fibook.ru"
#property link      "b2w@narod.ru"
 
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Lime
#property indicator_color2 Red
//---- input parameters
extern bool Auto_Correct_Line = false;// Автокоррекция последней точки Фибо
extern bool ClearRectangle = true;//Удаление квадратов при перестройке фибоуровней
extern bool TargetZone = true;//Отрисовка целевых зон
extern int count_Alert=3; //число повторений Алерт
double fibs[] = {-0.618, -0.382, -0.237, 0.0, 0.145, 0.382, 0.618, 0.855, 1.0, 1.237, 1.382, 1.618};
color fibsColor[] = {Maroon, Green, ForestGreen, Teal, SteelBlue, ,
                         SteelBlue, Teal, ForestGreen, Green, Maroon};
double Old_Price;
color FontColor=Black;
string TextAlert[7];   
int y=0,count_a=0;
double ftime;
double win_idx;
string NameFibs;
double Spread;
double ExtMapBufferUP[];
double ExtMapBufferDN[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
      Spread=(Ask-Bid);
 
//---- indicators
   SetIndexStyle(0,DRAW_ARROW,0,1);
   SetIndexArrow(0,233);
   SetIndexBuffer(0,ExtMapBufferUP);
   SetIndexEmptyValue(0,0.0);
   SetIndexStyle(1,DRAW_ARROW,0,1);
   SetIndexArrow(1,234);
   SetIndexBuffer(1,ExtMapBufferDN);
   SetIndexEmptyValue(1,0.0);
   
      return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
if(ftime!=Time[0]) count_a=0;
//  int    counted_bars=IndicatorCounted();
//----
// Определяем есть или нет фибо-уровни
int    obj_total=ObjectsTotal();
  string index;
  for(int i=0;i<obj_total;i++)
    {
     index=ObjectName(i);
      string substr = StringSubstr(index, 0, 4);
            if (substr == "Fibo")  NameFibs=index;
      string substrTL = StringSubstr (index, 0, 9);
            if (substrTL == "Trendline") 
            string TrDLine=index;
      string substrPR = StringSubstr (index, 0, 5);
            if (substrPR == "Arrow") 
            string PR=index;
    }
 
 
// Параметры трендовой линии
      if (StringLen(TrDLine)>1)
         {
            if (ObjectGet(TrDLine, OBJPROP_PRICE1)>ObjectGet(TrDLine, OBJPROP_PRICE2))
               {
               if ((Close[1]>ObjectGetValueByShift(TrDLine, 1)) && 
                                        (Close[2]<ObjectGetValueByShift(TrDLine, 2)))
                 {
                  ExtMapBufferUP[1]=(Low[1]-5*Point); /*Alert (Symbol(),"  Trend UP вход");*/
                  c_alert(1);
                 }
               }
            else
            if (ObjectGet(TrDLine, OBJPROP_PRICE1)<ObjectGet(TrDLine, OBJPROP_PRICE2))
               {
               if ((Close[1]<ObjectGetValueByShift(TrDLine, 1)) && 
                                        (Close[2]>ObjectGetValueByShift(TrDLine, 2)))
                  {
                   ExtMapBufferDN[1]=(High[1]+5*Point);/*Alert (Symbol(),"  Trend DN вход");*/
                     c_alert(1);
                  }
               }         
         }
// Окончание расчета трендовой линии
if (StringLen(NameFibs) <1) return(-1);// Если фибо уровней нет, то выходим
// Определяем где построены Фибо - уровни    
double pr1=ObjectGet(NameFibs, OBJPROP_PRICE1);// первая цена High
double pr1vrem=ObjectGet(NameFibs, OBJPROP_TIME1);// первый тайм цены
double pr2=ObjectGet(NameFibs,OBJPROP_PRICE2);// вторая цена Low
double pr2vrem=ObjectGet(NameFibs, OBJPROP_TIME2);// второй тайм цены
double fibprop=(pr1-pr2);// Разница между HIGH и LOW
double Timeend=(Time[0]+(Period()*360)); // Правая сторона по времени для отображения фигур на графике
double TimeNachalo=(Time[0]+Period()*60); // Левая сторона по времени для отображения фигур на графике
//+++
            ObjectMove(PR, 0,Time[0], Bid);// Значек текущей цены
//+++
// Параметры прямоугольника зоны разворота..
double verx=(pr1-fibprop*0.382);
double niz=(pr2+fibprop*0.382);
string UP=DoubleToStr(verx+Spread,Digits); 
string DN=DoubleToStr(niz-Spread,Digits); 
  if (Auto_Correct_Line==true)
      {
         if (High[0]>pr1) ObjectMove(NameFibs, 0,Time[0], High[0]);
         if (Low[0]<pr2) ObjectMove(NameFibs, 1,Time[0], Low[0]);
      }
   if (ClearRectangle == true) ObjectsDeleteAll(0,OBJ_RECTANGLE);// Удаляем объекты ПРЯМОУГОЛЬНИКИ
// строим прямоугольники в цикле
        for( y=0;y<11;y++)
      {
      ObjectCreate(("Kvadrat"+y), OBJ_RECTANGLE, 0, TimeNachalo,(pr2+fibprop*fibs[y]), 
                                                        Timeend,(pr2+fibprop*fibs[y+1]) );  
      ObjectSet(("Kvadrat"+y),OBJPROP_COLOR,fibsColor[y]);
      }
// окончание построения 
 
                                /* Строим прямоугольник ЗОНЫ */
 ObjectCreate("Kvadrat", OBJ_RECTANGLE, 0, TimeNachalo, verx , Timeend , niz);  
 ObjectSet("Kvadrat",OBJPROP_BACK,false);
 
// массив текстовой информации
       TextAlert[0] =   "Внимание две цели "; 
       TextAlert[1] =   ("Ордер вверх * "+UP);
       TextAlert[2] =   ("Ордер вниз   * "+DN); 
       TextAlert[3] =   ("ЦЕЛЬ вверх 2  * "+(DoubleToStr(pr1+fibprop*0.618,Digits)));
       TextAlert[4] =   ("ЦЕЛЬ вверх 1  * "+(DoubleToStr(pr1+fibprop*0.382,Digits))); 
       TextAlert[5] =   ("ЦЕЛЬ вниз  1  * "+(DoubleToStr(pr2-fibprop*0.382,Digits))); 
       TextAlert[6] =   ("ЦЕЛЬ вниз  2  * "+(DoubleToStr(pr2-fibprop*0.618,Digits)));
double YDist[] = {20, 55, 80, 120, 150, 180, 210};
color TextAlertClr[] = {Yellow, Green, Red, Green, Green, Red, Red};
        
// Выводим на экран сообщение о вводе ордеров
              for(y=0;y<7;y++)
               ObjectDelete("TextAlerts"+y);
if (TargetZone == true)
      {
      if (Bid > niz && Bid < verx)
            for(y=0;y<7;y++)
                  {
                  ObjectCreate(("TextAlerts"+y), OBJ_LABEL, 0, 0, 0);  
                  ObjectSetText(("TextAlerts"+y),TextAlert[y], 12, "Times New Roman",TextAlertClr[y]);
                  ObjectSet(("TextAlerts"+y), OBJPROP_CORNER, 0);
                  ObjectSet(("TextAlerts"+y), OBJPROP_XDISTANCE, 10);
                  ObjectSet(("TextAlerts"+y), OBJPROP_YDISTANCE, YDist[y]);
                  }
      }
 
// Информер цены и названия валюты
ObjectDelete("Market_Price_Label101");
   ObjectCreate("Market_Text_Label101", OBJ_LABEL, 0, 0, 0);
   ObjectSetText("Market_Text_Label101", (Symbol()+"  "+Period()), 16, "Times New Roman", Yellow);
   ObjectSet("Market_Text_Label101", OBJPROP_CORNER, 2);
   ObjectSet("Market_Text_Label101", OBJPROP_XDISTANCE, 5);
   ObjectSet("Market_Text_Label101", OBJPROP_YDISTANCE, 5);
 
  return(0);
  }
 
//+------------------------------------------------------------------+
 
void c_alert(int w)
 {
 ftime=Time[0];
 if(count_a<count_Alert)
 {count_a+=1;
 PlaySound("ku_ku.wav");
 }
 }
 return;

На следующем рисунке показано пересечение трендовой линий на часовом графике GBPUSD.

Заключение

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

Ну а для того, чтобы вам было совсем просто, прилагаю готовый шаблон для графика GBP, который нужно положить в каталог \templates\

Сам индикатор помещаем в папку \experts\indicators\.

И звуковой файл - в папку \sounds\.