Индикатор трендовых линий с учетом подхода Т.Демарка

Автор: lexy Вторник, Сентябрь 9th, 2014 Нет комментариев

Рубрика: Разное

Борьба  покупателей-«быков» и продавцов-«медведей» наглядно иллюстрируется трендовыми линиями. Томас Демарк разработал методику объективного выбора двух точек для построения  TD-линии тренда. (Более подробно о подходе Т. Демарка к техническому анализу смотри  http://alpari-idc.ru/ru/demark/ ).

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

 

Некоторые особенности кода предлагаемого индикатора в MQL 4

 

      В индикаторе используются четыре буфера. Два буфера для кода стрелок, направления линии и два буфера для удлинения TD-линии в левую сторону.

Начальные десять баров (влево от второй TD-точки) отрисовываются  буферами  индикатора цветом «aqua».

#property indicator_chart_window #property indicator_buffers 4 #property indicator_color1 Chartreuse #property indicator_color2 Tomato #property indicator_color3 Aqua #property indicator_color4 Aqua // ----- indicator_buffers double TrendUpBuffer[]; double TrendDownBuffer[]; double TrendLineBufferUp[]; double TrendLineBufferDown[];

 Инициализируем  функции, управляющие расчетом и визуализацией индикатора

int init() { //---- indicators SetIndexStyle(0,DRAW_ARROW); // тип, стиль линии индикатора SetIndexArrow(0,236); // значек для линии индикаторов SetIndexBuffer(0,TrendUpBuffer); // обяъявление одномерного массива SetIndexEmptyValue(0,0.0); // значение пустой величины для индикатора. SetIndexStyle(1,DRAW_ARROW); SetIndexArrow(1,238); SetIndexBuffer(1,TrendDownBuffer); SetIndexEmptyValue(1,0.0); SetIndexStyle(2,DRAW_LINE); SetIndexBuffer(2,TrendLineBufferUp); // для восходящей линии SetIndexEmptyValue(2,0.0); SetIndexStyle(3,DRAW_LINE); SetIndexBuffer(3,TrendLineBufferDown); // для нисходящей линии SetIndexEmptyValue(3,0.0); //---- return(0);

Деинициализацию можно оставить по умолчанию пустой.

int deinit() { // DelObj1(); // DelObj2(); return(0); }

Создаем функции удаления удаление объекта с указанным именем. 

 void DelObj1() { ObjectDelete("TrDdown"); // Удаление объекта с указанным именем. } void DelObj2() { ObjectDelete("TrDup"); }

Поиск опорных точек (для удобства) будем вести в отдельных циклах для пиков и для впадин. Поиск начинаем со 2-го бара, т.к. потом потребуется сравнение с правым (не нулевым) баром для выяснения истинности трендовой линии.

 

Проверим условие #1 (цена Max бара должна быть больше цен левого и правого баров).

 for(int i=2;i<48;i++) // 48 часов - 2-а дня // i- индекс проверяемого бара { if(High[i]>High[i+1]&&High[i]>High[i-1]) {

Проверим условие #2 (Опорный ценовой максимум должен быть  выше цены закрытия за два бара до регистрации).

При совпадении выполнения условий  #1-го и #2-го ставим счетчик совпадений.

 if(High[i]>Close[i+2]) { U++; // счетчик совпадений и #1-го и #2-го условий if(U==1) {

Далее переходим к регистрации параметров Первой опорной точки по пикам:

         // цена Первой опорной точки при выполнении условий #1 и #2
         TD_up[1]=High[i];
         index_up_1=i;                               // индекс Первой опорной точки
         Pr_up_Cl_1=Close[i-1]; // цена закрытия бара, следующего за опорной точкой
         time_up_1=iTime(NULL,0,index_up_1);          // время Первой опорной точки

Здесь для контроля выполнения программы можно вставить следующий проверочный код:

         // это удобочитаемое время для контроля хода выполнения операторов
         Time_up_1=TimeToStr(time_up_1,TIME_DATE|TIME_MINUTES);
         Print("  Up цена Первой опорной точки = ",TD_up[1],"  ;  индекс = ",
               index_up_1,"  время = ",Time_up_1);

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

 } if(U==2)
 { // цена Второй опорной точки при выполнении условий #1 и #2 TD_up[2]=High[i]; index_up_2=i; // индекс Второй опорной точки time_up_2=iTime(NULL,0,index_up_2);// время Второй опорной точки

Здесь для контроля выполнения программы можно вставить следующий проверочный код:

           Time_up_2=TimeToStr(time_up_2,TIME_DATE|TIME_MINUTES);
           Print("  Up цена Второй опорной точки = ",TD_up[2],"  ;  индекс = ",
                 index_up_2,"  время = ",Time_up_2);

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

           // условие нисходящего тренда (правая TD-точка должна быть ниже левой)
           if((U==2 && TD_up[1]<TD_up[2])==false)
             {
              Print(" Up Не выполнены условия Нисходящего тренда ");
              U--; TD_up[2]=0.0; index_up_2=0; time_up_2=0;  continue;
              }

          Если условие не выполнено, уменьшаем счетчик на единицу, обнуляем  значения цены, индекса, времени и возвращаемся в начало цикла для поиска другой Второй опорной точки. Если условие выполнено, делаем расчет скорости падения TD-линии.

            else
             {
              Print(" Up выполнены условия Нисходящего тренда ");
              // расчет скорости падения TD_max по двум выявленным точкам
              V_up=(TD_up[2]-TD_up[1])/(index_up_2-index_up_1);//скорость(пипсы/бар)
              // расчетное значение TD линии на 1-ом баре правее Max
              Pr_Tr_up_1=TD_up[1]-V_up;
              // если от цены 1-й опорной точки отнять произведение скорости падения
              // TD-линии на  кол-во  баров, получается  расчетная цена  нисходящего
              Pr_Tr_up_0=TD_up[1]-(index_up_1*V_up);           // тренда на "0" баре

Теперь проверим условие #3 (для последнего опорного ценового максимума цена закрытия  следующего (справа) бара должна быть ниже расчетного значения скорости падения TD-линии) – это условие истинности Нисходящего тренда.

 // проверим условие #3(для последнего опорного ценового максимума цена // закрытия следующего ( справа ) бара должна быть ниже расчетного // значения падения TD-линии) if((Pr_up_Cl_1< Pr_Tr_up_1)==false) { Print(" Up Не выполнено условие истинности Нисходящего тренда!"); i=index_up_1+2; TD_up[1]=0.0; TD_up[2]=0.0; time_up_1=0; time_up_2=0; index_up_1=50; index_up_2=50; U=0; continue; }

     Если не выполнено условие #3 истинности тренда, то поиск TD-точек приходится начинать с самого начала. Для этого необходимо обнулить все значения переменных полученные ранее, а поиск начинать с бара на два шага левее первого найденного значения Первой опорной точки.


Если условие истинности выполнено запоминаем значения переменных для построения трендовой линии.

 else { // если выполнено условие #3 - тренд истинен Print(" Up выполнены условия истинности Нисходящего тренда "); // запоминаем значения переменных для построения TD_Down линии TDu1=TD_up[1]; // цена 1-ой точки T_u1=time_up_1; // время 1-ой точки TDu2=TD_up[2]; // цена 2-ой точки T_u2=time_up_2; // время 2-ой точки TrendDownBuffer[index_up_1]=TDu1+5*Point;// ставим стрелку вниз

Теперь заполним буфер 10-тью значениями трендовой линии слева от Второй опорной точки:

 // цены 10 баров трендовой линии влево от левой TD-точки for(int k=index_up_2;k<index_up_2+10;k++) TrendLineBufferDown[k]=Pr_Tr_up_0+k*V_up; Print(" выходим из цикла поиска т.к.2-е TD-точки найдены"); break; }

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

 } } } } //==================================================================================+

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

В этом блоке первые два оператора управляют толщиной (STYLE_SOLID) TD-линии при наличии только одной трендовой линии на данном этапе. Рисуем  Нисходящую линию и выходим из цикла поиска пиков для TD-точек, предварительно удалив ранее имеющуюся линию.

     Применяя выше перечисленные рассуждения, дописываем код для восходящей линии.

//==================================================================================+
 // для Min точек (впадин) for(int j=2;j<48;j++) // 48 часов - 2-а дня // j- индекс проверяемого бара { // проверим условие #1 (цена бара должна быть меньше цен левого и правого баров) if(Low[j]<Low[j+1]&&Low[j]<Low[j-1]) { // проверим условие #2 (Опорный ценовой Минимум должен быть // ниже цены закрытия за два бара до регистрации <слева от Min>) if(Low[j]<Close[j+2]) { D++; // счетчик совпадений и #1-го и #2-го условий if(D==1) { TD_down[1]=Low[j]; index_down_1=j; Pr_down_Cl_1=Close[j-1]; time_down_1=iTime(NULL,0,j); Time_down_1=TimeToStr(time_down_1,TIME_DATE|TIME_MINUTES); Print(" D цена Первой опорной точки ",TD_down[1]," ; индекс ",index_down_1, " ; Close справа ",Pr_down_Cl_1," ; ",Time_down_1); } if(D==2) { TD_down[2]=Low[j]; index_down_2=j; time_down_2=iTime(NULL,0,j); Time_down_2=TimeToStr(time_down_2,TIME_DATE|TIME_MINUTES); Print(" D цена Второй опорной точки ",TD_down[2]," индекс ",index_down_2, " время ",Time_down_2); // условие восходящего тренда (правая Min точка должна быть выше левой) if((D==2 && TD_down[1]>TD_down[2])==false) { Print(" D Не выполнены условие Восходящего тренда! "); D--; TD_down[2]=0.0; continue; } else { Print(" D выполнены условия Восходящего тренда"); // расчет скорости подъема TD_min по двум выявленным точкам V_down=(TD_down[1]-TD_down[2])/(index_down_2-index_down_1); //расчетное значение линии на 1-ом баре правее Min Pr_Tr_down_1=TD_down[1]+V_down; } // проверим условие #3 (для последнего (справа) ценового минимума цена // закрытия следующего бара должна быть выше расчетного значения // скорости подъема TD-линии. if((Pr_down_Cl_1> Pr_Tr_down_1)==false) { i=index_down_1+1; TD_down[1]=0.0; TD_down[2]=0.0; time_down_1=0; time_down_2=0; index_down_1=50; index_down_2=50; D=0; continue; } else { // выполнено условие #3 - тренд истинен Print(" D выполнены условия истинности Восходящего тренда "); TDd1=TD_down[1]; T_d1=time_down_1; TDd2=TD_down[2]; T_d2=time_down_2; // расчетная цена трендовой линии на "0" баре Pr_Tr_down_0=TD_down[1]+(index_down_1*V_down); TrendUpBuffer[index_down_1]=TDd2-2*Point; // ставим стрелочку вверх // цены 10 баров трендовой линии влево от Второй опорной точки for(int n=index_down_2;n<index_down_2+10;n++) TrendLineBufferUp[n]=Pr_Tr_down_0-n*V_down; Print(" D выходим из цикла поиска т.к.2-е TD-точки найдены "); break; } } } } } } // ----------------------------------------------------------------------------+

   Блок отрисовки трендовых линий построен так, что последняя по времени TD-линия отрисовывается жирной сплошной линией (STYLE_SOLID), а линия предшествовшая ей, но противоположного направления отрисовывается тонкой пунктирной линией (STYLE_DOT).

   Может возникнуть такая ситуация, что тренд продолжительное время идет в одном направлении, при этом не будет найдена Вторая TD-точка тренда противоположного направления, а промежуточные значения цены, времени и индекса будут записываться в переменные. Чтобы эти промежуточные значения не отражались на построении трендовых линий, необходимо поставить фильтр условия отрисовки линий: например, если не найдена Вторая TD-точка, то значение цены будет равно «0″, в тоже время значение индекса Первой точки будет зафиксировано, и если оно окажется меньше значения Первой TD-точки линии противоположного направления, то последняя трендовая линия, имеющая истинные параметры, может быть отрисована не тем стилем и не тем цветом. Именно поэтому и поставлен временной фильтр. Смотри прикрепленный файл.

// ----------------------------------------------------------------------------+
// отрисовка трендовых линий вправо от Второй опорной точки
// ----------------------------------------------------------------------------+
    if(TDd2==0.0)   index_down_1=50;
    if(TDu2==0.0)   index_up_1=50;
     else
    {
    Print("  TDd2 = ",TDd2,"   index_up_1 = ",index_up_1,"  >  index_down_1 = ",index_down_1);
     Print("  Up Рисуем  Нисходящую и выходим из цикла поиска пиков для TD-точек");
       DelObj1(); // предварительно удалив ранее имеющуюся линию
        ObjectCreate("TrDdown",OBJ_TREND,0,T_u2,TDu2,T_u1,TDu1);
     if(index_up_1>index_down_1)
      {           // предшествующее направление тренда рисуется:
       ObjectSet("TrDdown",OBJPROP_COLOR,Yellow);
       ObjectSet("TrDdown",OBJPROP_WIDTH,1);  // тонкой линией и
       ObjectSet("TrDdown",OBJPROP_STYLE,STYLE_DOT);// пунктиром
       }
      else
       {                // самое последнее направление тренда рисуется:
        ObjectSet("TrDdown",OBJPROP_COLOR,Yellow);
        ObjectSet("TrDdown",OBJPROP_WIDTH,2);           // более толстой
        ObjectSet("TrDdown",OBJPROP_STYLE,STYLE_SOLID); // сплошной линией
       }
      }
// -----------------------------

     if(TDd2==0.0)   index_down_1=50;
      else
      {
    Print("  TDd1 = ",TDd1,"   index_up_1 = ",index_up_1,"  <  index_down_1 = ",index_down_1);
      Print("  D Рисуем  Восходящую и выходим из цикла поиска впадин для TD-точек");
        DelObj2(); // предварительно удалив, ранее имеющуюся линию
         ObjectCreate("TrDup",OBJ_TREND,0,T_d2,TDd2,T_d1,TDd1);
       if(index_up_1<index_down_1)
        {   

         ObjectSet("TrDup",OBJPROP_COLOR,Yellow);
         ObjectSet("TrDup",OBJPROP_WIDTH,1);
        ObjectSet("TrDup",OBJPROP_STYLE,STYLE_DOT);
        }
         else
          {
          ObjectSet("TrDup",OBJPROP_COLOR,Yellow);
          ObjectSet("TrDup",OBJPROP_WIDTH,2);
          ObjectSet("TrDup",OBJPROP_STYLE,STYLE_SOLID);
          }
         }
// ----------------------------------------------------------------------------+
   return(0);
  }

Примечание: практически все операторы «Print(…)» служат для визуального контроля хода выполнения программы, поэтому их можно «закомментировать», а также операторы типа string (TimeToStr()) нужны тоже для контроля.

 

Заключение

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

 

Прикрепленные файлы:
 TL_by_Demark_v6.mq4 (13.4 Kb)
Источник: mql4.com

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

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты