//+------------------------------------------------------------------+ //| TL_by_Demark_v6.mq4 | //| Построение линий тренда с учетом Подхода Т.Демарка Genkov | //| genkov@bk.ru | //+------------------------------------------------------------------+ #property copyright "Genkov" #property link "genkov@bk.ru" #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[]; //------ input parameters int index_up_1,index_up_2,index_down_1,index_down_2; double V_up,V_down,Pr_up_Cl_1,Pr_down_Cl_1,Pr_Tr_up_0,Pr_Tr_down_0; double TD_up[50],TD_down[50],TDu1,TDu2,TDd1,TDd2,Pr_Tr_down_1,Pr_Tr_up_1; datetime time_up_1,time_up_2,T_u1,T_u2,T_d1,T_d2,time_down_1,time_down_2; string Time_down_1,Time_down_2,Time_up_1,Time_up_2; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ 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); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { DelObj1(); DelObj2(); return(0); } void DelObj1() { ObjectDelete("TrDdown"); // Удаление объекта с указанным именем. } void DelObj2() { ObjectDelete("TrDup"); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { int U=0,D=0; // внутренние переменные обнуляются при каждом тике //=======================================================================+ // ищем претендентов на опорные TD_точки: начинаем поиск со 2-го бара т.к. // потом потребуется сравнение с правым баром (не нулевым). Для Max точек // проверим условие #1(цена бара должна быть больше цен левого и правого баров) for(int i=2;i<24;i++) // 48 часов - 2-а дня // i- индекс проверяемого бара { if(High[i]>High[i+1]&&High[i]>High[i-1]) { // проверим условие #2(Опорный ценовой максимум должен быть // выше цены закрытия за два бара до регистрации <слева от Max>) 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-точка должна быть ниже левой) if((U==2 && TD_up[1]TD_down[2])==false) { Print(" D TD_down[1] = ",TD_down[1]," > TD_down[2] = ",TD_down[2]); Print(" D Не выполнены условие Восходящего тренда! "); D--; TD_down[2]=0.0; if(index_down_2>20) {time_down_1=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) { Print(" D Не выполнены условие истинности Восходящего тренда! "); Print(" time_down_1 = ",Time_down_1," time_down_2 = ",Time_down_2); i=index_down_1+2; 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 выполнены условия истинности Восходящего тренда "); Print(" time_down_1 = ",Time_down_1," time_down_2 = ",Time_down_2); 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 time_up_1 = ",Time_up_1); DelObj1(); // предварительно удалив ранее имеющуюся линию ObjectCreate("TrDdown",OBJ_TREND,0,T_u2,TDu2,T_u1,TDu1); if(time_up_1 time_down_1 = ",Time_down_1); DelObj2(); // предварительно удалив, ранее имеющуюся линию ObjectCreate("TrDup",OBJ_TREND,0,T_d2,TDd2,T_d1,TDd1); ////// TrendDownBuffer[index_down_1]=0.0; if(time_down_1