考虑 T. Demark 方法的趋势线指标
简介
买家(“牛市力量”)和卖家(“熊市力量”)的角力可以使用趋势线表现。Thomas Demark 开发的客观方法是在趋势绘制的 TD-线上选择两个点(你可以在此处找到 T. Demark 有关技术分析方法的详细信息)。
在 T. Demark 看来,对交易者最重要的是市场的最后状态,在指标的建议版本中,趋势的最后方向用粗实线绘制,这对于分析当前状态以了解趋势之前最邻近的方向并不奇怪,其中趋势之前最邻近的方向以细虚线绘制。
该指标的 MQL4 代码中的一些特点
指标中使用了四个缓冲区。其中两个用于线条方向的箭头代码,两个用于 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); // the type and the style of the indicator line SetIndexArrow(0,236); // the icon for the indicator line SetIndexBuffer(0,TrendUpBuffer); // the declaration of the unidimensional array SetIndexEmptyValue(0,0.0); // the size of the empty value of the indicator SetIndexStyle(1,DRAW_ARROW); SetIndexArrow(1,238); SetIndexBuffer(1,TrendDownBuffer); SetIndexEmptyValue(1,0.0); SetIndexStyle(2,DRAW_LINE); SetIndexBuffer(2,TrendLineBufferUp); // for the rising line SetIndexEmptyValue(2,0.0); SetIndexStyle(3,DRAW_LINE); SetIndexBuffer(3,TrendLineBufferDown); // for the descending line SetIndexEmptyValue(3,0.0); //---- return(0);
去初始化可默认留空。
int deinit() { // DelObj1(); // DelObj2(); return(0); }
创建用于删除具有指定名称对象的函数。
void DelObj1() { ObjectDelete("TrDdown"); // Deleting of the object with the specified name. } void DelObj2() { ObjectDelete("TrDup"); }
我们将在单独的循环中搜索检查点(出于方便),以找出峰顶和谷底。我们从第二个柱开始搜索,因为需要将其跟右侧的(非零)柱比较以说明趋势线的真实性。
我们来检查条件 #1(Max 柱的价格必须高于右侧和左侧柱的价格)。
for(int i=2;i<48;i++) // 48 hours - 2 days // i- index of the bar to be verified { if(High[i]>High[i+1]&&High[i]>High[i-1]) {
然后检查条件 #2(支撑价格最大值应高于两个柱以外登记前的收盘价格)。
以防条件 #1 和条件 #2 同时满足,我们置入了匹配计数器。
if(High[i]>Close[i+2]) { U++; // the counter of matches of the 1st and the 2nd conditions if(U==1) {
然后我们进入第一个检查点参数的峰值登记:
// The price of the First check point when the conditions #1 and #2 are fulfilled TD_up[1]=High[i]; index_up_1=i; // the index of the First check point Pr_up_Cl_1=Close[i-1]; // the close price of the bar that follows the check point time_up_1=iTime(NULL,0,index_up_1); // the time of the first check point
这里可以插入以下检验代码以控制程序运行:
// this is an easy-to-follow time to control the operators processing Time_up_1=TimeToStr(time_up_1,TIME_DATE|TIME_MINUTES); Print(" Up price of First check point = ",TD_up[1]," ; index = ", index_up_1," time = ",Time_up_1);
由于计数器已经触发过一次,我们在后续重复中发现第二个点并进入第二个检查点参数的峰值登记。
} if(U==2) { // The price of the Second check point when the conditions #1 and #2 are fulfilled TD_up[2]=High[i]; index_up_2=i; // the index of the Second check point time_up_2=iTime(NULL,0,index_up_2);// the time of the Second check point
这里可以插入以下检验代码以控制程序运行:
Time_up_2=TimeToStr(time_up_2,TIME_DATE|TIME_MINUTES); Print(" Up price of Second check point = ",TD_up[2]," ; index = ", index_up_2," time = ",Time_up_2);
现在我们有了两个 TD-检查点,需要检查下跌趋势的条件,即第一个检查点的价格必须低于第二个检查点的价格。
// the condition of the downtrend (the right TD-point must be lower than the left one) if((U==2 && TD_up[1]<TD_up[2])==false) { Print(" Up the conditions of the downtrend are not fulfilled "); U--; TD_up[2]=0.0; index_up_2=0; time_up_2=0; continue; }
如果不满足条件,我们将计数器降低 1 并将价格、指数和时间的值归零,返回循环开始,以继续搜索另一第二检查点。如果满足条件,则计算 TD-线下跌的速度。
else { Print(" Up the conditions of the downtrend are fulfilled "); // the calculation of the speed of TD_max falling by two discovered points V_up=(TD_up[2]-TD_up[1])/(index_up_2-index_up_1);//speed(pips/bar) // the calculated value of TD-line on the first bars which is to the right of Max Pr_Tr_up_1=TD_up[1]-V_up; // if we subtract the product of speed of TD-line falling times number of bars // from the price of the 1-st check point, we'll obtain the price of the Pr_Tr_up_0=TD_up[1]-(index_up_1*V_up); // downtrend on the "0" bar
现在我们来检验条件 #3(对于最后的支撑价格最高值,下一个(右侧)柱的收盘价格必须低于 TD-线下跌速度的计算值) - 这是确认下跌趋势的条件。
// let's check the condition #3 (for the last supporting price maximum the close // price for the next (to the right) bar must be lower than the calculated // value of the speed of TD-line falling) if((Pr_up_Cl_1< Pr_Tr_up_1)==false) { Print(" Up The condition of verity of downtrend is not fulfilled!"); 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 { // if the condition #3 is fulffiled, the trend is true Print(" Up the conditions of Downtrend verity are fulfilled "); // memorize the values of variables for drawing the TD_Down line TDu1=TD_up[1]; // price of the 1-st point T_u1=time_up_1; // time of the 1-st point TDu2=TD_up[2]; // price of the 2-nd point T_u2=time_up_2; // price of the 2-nd point TrendDownBuffer[index_up_1]=TDu1+5*Point;// put the down arrow
现在用第二个检查点左侧的趋势线的 10 个值填充缓冲区。
// prices of 10 bars of the trend line to the left of TD-point for(int k=index_up_2;k<index_up_2+10;k++) TrendLineBufferDown[k]=Pr_Tr_up_0+k*V_up; Print(" exit from the cycle of searching, because 2 TD-points are found"); break; }
插入缺失的大括号。
}
}
}
}
//==================================================================================+
如果满足检验条件,将在第二个检查点左侧的 10 个柱上绘制趋势线。现在将使用 ObjectCreate() 函数在右侧绘制趋势线。为此,程序的最后包含一个趋势线绘制程序块。
在程序块中,前两个运算符控制 TD-线的粗度(STYLE_SOLID)在程序块中,前两个运算符控制 TD-线的粗度。我们绘制下降线并退出搜索 TD-点峰值的循环,初步删除之前存在的线。
使用上述的推理,我们编写了上升线的代码。
//==================================================================================+ // for Min points (troughs) for(int j=2;j<48;j++) // 48 hours - 2 days // j- index of the bar to be checked { // let's check the conditon #1 (the price of the bar must be lower than the prices of the left and the right bars) if(Low[j]<Low[j+1]&&Low[j]<Low[j-1]) { // let's check the condition #2 (The supporting price Minimum must be lower than // the close price of the bar beyond two bars before the registration <to the left of Min>) if(Low[j]<Close[j+2]) { D++; // the counter of coincidences of the 1-st and the 2-nd conditions 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 price of the First check point ",TD_down[1]," ; index ",index_down_1, " ; Close to the right ",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 price of the Second check point ",TD_down[2]," index ",index_down_2, " time ",Time_down_2); // the condition of the rising trend (the right Min point must be higher than the left one) if((D==2 && TD_down[1]>TD_down[2])==false) { Print(" D The conditions of the Rising trend are not fulfilled! "); D--; TD_down[2]=0.0; continue; } else { Print(" D the conditions of the Rising trend are fulfilled"); // the calculation of the speed of TD_min rising by two discovered points V_down=(TD_down[1]-TD_down[2])/(index_down_2-index_down_1); // the calculated value of the line on the 1-st bar to the right of Min Pr_Tr_down_1=TD_down[1]+V_down; } // let's check the condition #3 (for the last (to the right) price minimum, // the close price of the next bar must be higher than the calculated value // of the speed of TD-line rising). 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 { // the condition #3 is fulfilled, the trend is true Print(" D the conditions of Rising trend verity are fulfilled "); TDd1=TD_down[1]; T_d1=time_down_1; TDd2=TD_down[2]; T_d2=time_down_2; // the calculated price of the trend line on the "0" bar Pr_Tr_down_0=TD_down[1]+(index_down_1*V_down); TrendUpBuffer[index_down_1]=TDd2-2*Point; // put the up arrow // the price of 10 bars of the trend line to the right of the Second check point for(int n=index_down_2;n<index_down_2+10;n++) TrendLineBufferUp[n]=Pr_Tr_down_0-n*V_down; Print(" D exit the cycle of searching, because two TD-points are found "); break; } } } } } } // ----------------------------------------------------------------------------+
绘制趋势线的程序块使最新的 TD-线以粗实线绘制(STYLE_SOLID),在它前面方向相反的线以细虚线绘制(STYLE_DOT。
可能会发生趋势长时间沿一个方向移动的情况。如果是这样的话,就不会找到相反趋势的第二个 TD-点,将价格、时间和指数的中间值写入变量。为了使中间值不影响趋势线的绘制,应该插入线条绘制条件过滤器:例如,如果未找到第二条 TD-线,价格值将设置为“0”,同时,第一个点的指数值将会固定,如果该值低于相反方向线的第一个 TD-点的值,则具有真参数的最后趋势线可以用其他线型和颜色绘制。这就是指定时间过滤器的原因。查看一下附件。
// ----------------------------------------------------------------------------+ // the drawing of the trend lines to the right of the Second check point // ----------------------------------------------------------------------------+ 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 We draw the Descending one and exit from the cycle of searching the peaks for the TD-points"); DelObj1(); // preliminary deleting the previously existed line ObjectCreate("TrDdown",OBJ_TREND,0,T_u2,TDu2,T_u1,TDu1); if(index_up_1>index_down_1) { // the previous direction of the trend is drawn with: ObjectSet("TrDdown",OBJPROP_COLOR,Yellow); ObjectSet("TrDdown",OBJPROP_WIDTH,1); // thin line and ObjectSet("TrDdown",OBJPROP_STYLE,STYLE_DOT);// dotted line } else { // the very last direction of the trend is drawn with: ObjectSet("TrDdown",OBJPROP_COLOR,Yellow); ObjectSet("TrDdown",OBJPROP_WIDTH,2); // thicker line ObjectSet("TrDdown",OBJPROP_STYLE,STYLE_SOLID); // solid line } } // ----------------------------- 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 We draw the Rising one and exit from the cycle of searching the troughs for TD-points"); DelObj2(); // preliminary deleting the previously existed line 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(...)" 运算符都为程序执行的可视化控制服务,所以可以对其“注释”,字符串(TimeToStr())类型的运算符对于控制也是必不可少的。
总结
我希望,不仅是交易新手使用该指标,而且经验丰富的交易者同样使用,无论是用于市场交易还是对执行的出价进行分析。
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/1507