
T. Demark のアプローチを考慮したトレンドラインインディケータ
はじめに
買い手(『ベア』)と売り手(『ブル』)の間の葛藤はトレンドラインによって表されます。Thomas Demark はトレンド描画の TD ラインについての 2 つの点を客観的に選択する方法を開発しました( ここでテクニカル分析に対する T. Demark のアプローチにすいての詳細が参照できます)。
T. Demark によると、トレーダーにとってもっとも重要なのは市場の直近の状態であるため、提供されているバージョンのインディケータでは太い実線で描かれ、トレンドの直近の方向を知ることは現在の状態を分析するのに当然のことです。それは細い点線で描かれます。
提案されるインディケータの MQL4 コード機能
このインディケータではバッファが4個使用されています。2個はライン方向の→のコード用、別の2個は TD ラインを左側に伸ばすためのものです。
最初の10本のバー(2番目の TD ポイントの左)は«水色»でインディケータバッファによって描かれています。
#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"); }
頂上と底に対する個別のサイクルでチェックポイント(便宜のため)検索します。検索は2番目のバーから始めます。なぜならそれを正しいバー(ゼロ以外)と比較し、トレンドラインの心理を明確にします。
条件No.1 (最大バーの価格が左右のバーより大きい)を確認します。
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]) {
条件No.2(サポート価格最大値が登録前の2本のバーの終値より大きい)を確認します。
条件No.1とNo.2が一致しえ満たされる場合、一致のカウンターを設定します。
if(High[i]>Close[i+2]) { U++; // the counter of matches of the 1st and the 2nd conditions if(U==1) {
そして「第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);
カウンターは一度起動したので、のちの反復に第2のポイントを見つけ、「第2」チェックポイントパラメータのバイ・ピーク登録に渡します。
} 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);
これで2つの TD チェックポイントを取得しました。下落トレンドの条件も確認する必要があります。すなわち、「第1」チェックポイントの価格は「第2」チェックポイントの価格より低くなければなりません。
// 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減らし、価格値、インデックス、時刻をゼロ設定します。そして、別の「第2」チェックポイントを検索するためサイクルの始めに戻ります。条件が満たされれば、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
ここで条件 No.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; }
下落トレンドの真実性の条件 No.3 が満たされなければ、Td ポイント検索を再び始めます。そのためには、以前に取得した変数すべての値をゼロ設定する必要があります。そして最初に見つけた「第1」のチェックポイント値からバー2本分左にあるバーから検索を始めます。
条件が満たされれば、トレンドラインを描くために計算された変数の値を記憶します。
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
「第2」チェックポイントから左にトレンドラインの値を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; }
入っていない中括弧を入れます。
}
}
}
}
//==================================================================================+
検証条件が満たされれば、トレンドラインは「第2」チェックポイントの左のバー10本に描かれます。ここで、このラインは ObjectCreate() 関数によって右側へ描かれることになります。このためにプログラム末尾にはトレンドライン描画ブロックかあります。
このブロックでは、この段階ではトレンドライン1本だけに関して、最初の 2 つの演算子が TD ライン (STYLE_SOLID)の太さを制御します。われわれは「下降」ラインを描き、あらかじめ以前に存在したラインを削除して、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; } } } } } } // ----------------------------------------------------------------------------+
トレンドライン描画のブロックは一番若いラインが太い実線(STYLE_SOLID)で描かれ、その前の逆方向ラインは細い点線(STYLE_DOT)で描かれるように作成されます。
長時間トレンドが一方向に向かう状況が発生する可能性があります。そのような場合には、逆トレンドの「第2」TD ポイントは検出されず、価格の中間値、時間、インデックスが変数に書き込まれます。この中間値がトレンドライン描画に影響を与えないようにするため、線描画条件のフィルターを挿入する必要があります。たとえば、「第2」 TD ラインが検出されなければ、価格値は "0" に設定され、同時に「第1」TD ポイントのインデックスが修正され、この値が逆方向のラインの「第1」ポイント値を下回るようならば、真のパラメータを持つ直近のトレンドラインは別のスタイルと色で描かれる、というようにです。そのためにタイム・フィルターが指定されるのです。添付ファイルを見ます。
// ----------------------------------------------------------------------------+ // 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




- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索