ZigZag インディケータ:新鮮なアプローチと新しいソリューション
はじめに
トレーダーならだれでも既定のまたは大きな振幅の価格変動の分析に使うZigZag インディケータをかならず知っています。ZigZag の線は破線でそのノードは価格チャートの最大および最小値にあります。
このインディケータには以下のように数多くのバリエーションがあります。1、2、3、4、 5、6、7、8、 9、10、11、12、 13、14、15、 16。それでも多くのMQL5 プログラム開発者は自分自身の「理想の」 ZigZagを作成することに余念がありません。ZigZag インディケータの主な欠点は遅延、疑わしいノード(外部バー)の誤ったマーキング、満足のいかないパフォーマンスです。
私の意見では、もっとも洗練された ZigZag 実装は Yuri Kulikov (Yurich)によって提案されたものです。ほかにもひじょうにすぐれた MQL4 記事が何件かあります。 "Layman's Notes: ZigZag..." や "Show Must Go On, or Once Again about ZigZag"のようなものです。テーマは十分に研究され、ひじょうに多数の発行物が入手可能です。それについてはなにか引きつけられるものがまだあります。それには私も興味を引かれました。とくに高度な ZigZag インディケータを作成する可能性についてです。
本稿ではエンベロープ インディケータを用いて高度なZigZag を作成する方法についてお話します。連続したエンベロープに対する入力パラメータの特定の組合せを見つけることができ、そこでは ZigZag ノードはすべてエンベロープバンドの範囲 内にあると考えられます。
高度なZigZag を作成する方法
目標を設定します。2つのノードの座標を見つけること。2つのノードとは現在ノードと推定されるノードです(図1)。現在ノードはまだ完成されておらず座標が検索中または調整中のものです。その上それはつねに現在バー上(ゼロ)にあります。将来であれば推測されるノードが次のZigZag ノードの推定レベルを表示するはずです。
図1 新しZigZag ノードの推測:現在ノードと次ノード
目標は設定されました。高度なインディケータを構築する基礎として移動平均エンベロープを使用する方法についての考えも得ました(図2)。ZigZag ノードからの偏差が最小であるエンベロープを検索します。ZigZag の頂点と谷 に対するエンベロープは個別に検索するというのはきわめて合理的であると思えます。
図2 ZigZag インディケータと移動平均エンベロープ
推定の統計的有意性を高めるために、1つだけまたは10個のEnvelopesインディケータを使う代わりに異なるインプットデータを持つ100個以上のインディケータを使用する必要があります。それらはメインのインディケータラインの平均化期間と使用される価格(頂点に対する高値、谷に対する安値)が異なります。以下の表記と定型句を取り入れます。
- ZZ -ZigZag インディケータ
- ENV -Envelopes インディケータのメインライン(iMA インディケータと一致します)
- Envelopes(i) -i 番目のバーにおけるエンベロープインディケータのメインライン値
- ZZ(High) -ZigZag のピーク値
- ZZ(Low) - ZigZag のtrough値
- ENV(High) -ZigZag ピークに対応するEnvelopesインディケータのメインライン値
- ENV(Low) - ZigZag troughに対応するEnvelopesインディケータのメインライン値
- n_high -ZigZag ピーク数
- n_low -ZigZag troughs数
インディケータプールは2個あります。1つは頂点に対するもの、もう1つは谷 に対するものです(それぞれにインディケータは約100)。プールの各インディケータに対して Envelopes インディケータのメインラインからの ZigZag ノードの偏差を計算し、上記の式を用いて各プールインディケータに対する偏差の算術平均を求めます。下図はあるインディケータに対するメインラインENV から特定されるノードZZに関する偏差の略図を示しています。
図3 ENVからの ZZ ノードの偏差図
偏差の算術平均はエンベロープバンドをプロットするためにEnvelopes インディケータのメインラインが移動されるべきレベルを決定するのに使用されます。Envelopes インディケータの上側の線を引くために ZigZag の頂点からの偏差の算術平均が必要で、上下側の線を引くために ZigZagの谷からの偏差の算術平均が必要なのです。
特徴的な点を見つけ、ZigZag ノードを推測するために利用するのがエンベロープの上下ラインなのです。ふたたび1組の Envelopes インディケータで構成されるプールに着目します。既定のエンベロープのメインラインから得られるZigZag ノードの偏差の算術平均は各インディケータに対して計算されます。チャート内プールの結果のライン(上下ライン)をプロットしたら、以下が表示されます。
図4 平面上のEnvelopesライン
各ラインは個別の平面上にあるとすると、それらがすべて一緒に表面を作成するかたわら、上図だけが価格チャート平面上の各インディケータ予測を示すのです。これらラインの3D 画像はおおよそ以下のようなものです。
図5 3Dでの Envelopes ライン
ここで簡単に幾何学の学習を行います。Envelopes インディケータのラインのプールが 3D 表面であるとイメージします。価格チャートに対して平面を取り、現在(ゼロ)バーでその表面を切り取ります。
結果として曲線を表す表面の断面を取得します(上図は曲線が直線となる特殊ケースを表しています)。予測のためにはのちに計算に利用される曲線上の各点の座標を取得するので十分です。
次の断面特性が必要となります。最大および最小点、交点の重心(すべてのポイント値の算術的平均)。適切なデータは履歴に格納されているので取得した特徴点は現在(ゼロ)バーで予測されます。3個の特性ポイントは現および次 ZigZag ノードに対する基本としての役目を果たします。
Envelope バンドの検索が頂点と谷に対して個別に行われるため、結果断面を2個取得することとなります。1個はピーク、もう1個はボトムに対するものです。
予測値を得るにはもっとも近い特徴点を使用します。たとえば ZigZag 頂点を検索するときは切り取った平面を持つ Envelopes インディケータの上側ライン の表面の交点から得られる端面の特徴点を取ります。逆に 谷 を検索するときは切り取った平面を持つ Envelopes インディケータの 下側ラインの表面の交点から得られる断面の特徴点を取ります。
新インディケータの検証
これで方法は決定しました。それではインディケータを作成しましょう。まず ZigZag インディケータの最終ノードを見つけそれをチャートに描きます。このために取り組むタスクのために書くAdvancedZigZag クラスを使用します。
//+------------------------------------------------------------------+ //| AdvancedZigZag.mqh | //| Copyright 2013, DC2008 | //| https://www.mql5.com/ru/users/DC2008 | //+------------------------------------------------------------------+ #property copyright "Copyright 2013, DC2008" #property link "https://www.mql5.com/ru/users/DC2008" #property version "1.00" //+------------------------------------------------------------------+ //| GetExtremums.mqh | //+------------------------------------------------------------------+ #include <GetExtremums.mqh> // author of the code Yurich #property copyright "Copyright 2012, Yurich" #property link "https://www.mql5.com/ru/users/Yurich" //+------------------------------------------------------------------+ //| ZigZag node structure | //+------------------------------------------------------------------+ struct MqlZigZag { double price; // Node coordinate datetime t; // Time }; //+------------------------------------------------------------------+ //| The AdvancedZigZag class | //+------------------------------------------------------------------+ class AdvancedZigZag { private: MqlRates rt[]; dextremum zz[]; int history; double amplitude; public: dextremum zHL[]; MqlZigZag zzH[],zzL[]; int Count(const double range); int Read(const int nodes); AdvancedZigZag(const int bars); ~AdvancedZigZag(); }; //+------------------------------------------------------------------+ //| Class constructor | //+------------------------------------------------------------------+ AdvancedZigZag::AdvancedZigZag(const int bars) { history=bars; amplitude=0; } //+------------------------------------------------------------------+ //| The Read method of the class | //+------------------------------------------------------------------+ int AdvancedZigZag::Read(const int nodes) { CopyRates(NULL,0,TimeCurrent(),history,rt); int cnt=GetExtremums(amplitude,rt,zHL,nodes); return(cnt); } //+------------------------------------------------------------------+ //| The Count method of the class | //+------------------------------------------------------------------+ int AdvancedZigZag::Count(const double range) { amplitude=range; CopyRates(NULL,0,TimeCurrent(),history,rt); int cnt=GetExtremums(amplitude,rt,zz); ArrayResize(zzH,cnt); ArrayResize(zzL,cnt); int h=0; int l=0; for(int i=0; i<cnt; i++) { if(zz[i].type>0) { zzH[h]=(MqlZigZag)zz[i]; h++; } else { zzL[l]=(MqlZigZag)zz[i]; l++; } } ArrayResize(zzH,h); ArrayResize(zzL,l); return(cnt); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ AdvancedZigZag::~AdvancedZigZag() { }
メソッドは合計2つあります。
- Count メソッドは与えられた期間中(バー番号) ZigZag ノードをすべて見つけ、それをさまざまな配列に頂点を谷から分けて保存します。このようにエンベロープの分析と計算は簡単になります。
- Read メソッドは最終ノードを見つけそれを1個の配列に保存します。ZigZag インディケータを可視化するためにはこのメソッドが必要です。
GetExtremumsライブラリ(Yury Kulikovによる)もまたノード検索に必要となります。
Expert Advisorでインディケータも考慮に入れます。なぜインディケータではなく Expert Advisor なのでしょうか?もちろん好みの問題ですが、私はこの方が効率的だと思います。Expert Advisorのグラフィカルな特徴はもちろん弱いものですが、おなじシンボルインディケータが単独のストリームで処理するためパフォーマンスを高めます。各 EA はそれ自体の個別のストリームで処理を行います。それではコードを見ていきましょう。
//+------------------------------------------------------------------+ //| two_Comets.mq5 | //| Copyright 2013, DC2008 | //| https://www.mql5.com/ru/users/DC2008 | //+------------------------------------------------------------------+ #property copyright "Copyright 2013, DC2008" #property link "https://www.mql5.com/ru/users/DC2008" #property version "1.00" #include <AdvancedZigZag.mqh> //--- Depth of history for the indicator calculation input int depth_stories=5000; // Depth stories for calculating the indicator [bars] //--- Minimum ZigZag amplitude value input int amplitude=100; // The minimum value of the amplitude of the indicator [points] //--- Declaring the class AdvancedZigZag Azz(depth_stories); //--- #define NUMBER_MA 227 #define START_MA 5 //--- macros #define SIZE(i) (double)i*0.3<1?1:(int)(i*0.25) #define ObjF1 ObjectSetString(0,name,OBJPROP_FONT,"Wingdings") #define ObjF2 ObjectSetInteger(0,name,OBJPROP_ANCHOR,ANCHOR_CENTER) #define ObjF3(T) ObjectSetInteger(0,name,OBJPROP_TIME,T) #define ObjF4(P) ObjectSetDouble(0,name,OBJPROP_PRICE,P) #define ObjF5(size) ObjectSetInteger(0,name,OBJPROP_FONTSIZE,size) #define ObjF6(code) ObjectSetString(0,name,OBJPROP_TEXT,CharToString(code)) #define ObjF7(clr) ObjectSetInteger(0,name,OBJPROP_COLOR,clr) #define ObjF8 ObjectSetInteger(0,name,OBJPROP_COLOR,clrMagenta) #define ObjF9 ObjectSetInteger(0,name,OBJPROP_WIDTH,3) #define ObjF10 ObjectSetInteger(0,name,OBJPROP_BACK,true) #define ObjFont ObjF1;ObjF2; #define ObjCoordinates(T,P) ObjF3(T);ObjF4(P); #define ObjProperty(size,code,clr) ObjF5(size);ObjF6(code);ObjF7(clr); #define ObjZZ ObjF8;ObjF9;ObjF10; //--- double MA[1],sumHi[NUMBER_MA],sumLo[NUMBER_MA]; int handle_MA_H[NUMBER_MA],handle_MA_L[NUMBER_MA]; datetime t[1]; int H,L; int t_min,t_max; int err=-1; double sumH[2],maxH[2],minH[2]; double sumL[2],maxL[2],minL[2]; string name; int count; int shift; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { shift=PeriodSeconds()/30; //--- calculation of ZigZag nodes using historical data Azz.Count(amplitude*Point()); H=ArraySize(Azz.zzH); L=ArraySize(Azz.zzL); if(H<30 || L<30) { Print("Not enough data to calculate ZigZag nodes: "+ "increase the depth of history; "+ "or decrease the amplitude value."); return(-1); } //--- for(int i=0; i<NUMBER_MA; i++) { handle_MA_H[i]=iMA(NULL,0,i+START_MA,0,MODE_SMA,PRICE_HIGH); handle_MA_L[i]=iMA(NULL,0,i+START_MA,0,MODE_SMA,PRICE_LOW); } //--- return(0); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { ObjectsDeleteAll(0,-1,-1); for(int i=0; i<NUMBER_MA; i++) { IndicatorRelease(handle_MA_H[i]); IndicatorRelease(handle_MA_L[i]); } //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- get the current bar's opening time value CopyTime(NULL,0,0,1,t); //--- ZigZag: last 7 nodes count=Azz.Read(7); for(int i=1; i<count; i++) { name="ZZ"+(string)i; ObjectCreate(0,name,OBJ_TREND,0,0,0); ObjectSetInteger(0,name,OBJPROP_COLOR,clrRed); ObjectSetInteger(0,name,OBJPROP_WIDTH,10); ObjectSetInteger(0,name,OBJPROP_BACK,true); ObjectSetDouble(0,name,OBJPROP_PRICE,0,Azz.zHL[i-1].value); ObjectSetInteger(0,name,OBJPROP_TIME,0,Azz.zHL[i-1].time); ObjectSetDouble(0,name,OBJPROP_PRICE,1,Azz.zHL[i].value); ObjectSetInteger(0,name,OBJPROP_TIME,1,Azz.zHL[i].time); } //--- check for integrity of preliminary calculations if(err<0) { //--- calculate the sums of deviations of the nodes from MA for ZigZag peaks ArrayInitialize(sumHi,0.0); for(int j=H-1; j>=0; j--) { for(int i=0; i<NUMBER_MA; i++) { err=CopyBuffer(handle_MA_H[i],0,Azz.zzH[j].t,1,MA); if(err<0) return; sumHi[i]+=Azz.zzH[j].price-MA[0]; } } //--- calculate the sums of deviations of the nodes from MA for ZigZag troughs ArrayInitialize(sumLo,0.0); for(int j=L-1; j>=0; j--) { for(int i=0; i<NUMBER_MA; i++) { err=CopyBuffer(handle_MA_L[i],0,Azz.zzL[j].t,1,MA); if(err<0) return; sumLo[i]+=MA[0]-Azz.zzL[j].price; } } } } //+------------------------------------------------------------------+
ここで明確にすることが数点あります。
- iEnvelopes インディケータは iMA インディケータと置き換えられています。それは誤りでもなければ誤解でもありません。問題はiEnvelopes のメインラインが iMAと一致していることなのです。よって移動平均指数を利用する方が好都合です。
- 移動平均のプールを2とおり使用しています。それぞれ 227 行で構成されており、そのため合計 454の iMA を作成しているのです。それは多いのでしょうか少ないのでしょうか?基本的にそれは大きな数字です。しかしまず必要であればインディケータ数を変更することができます。そして次に統計が必要です。10数個のノードに対してエンベロープを検索する趣旨は何なのでしょうか?最低100個は必要です。
- インディケータ値 OnInit()の代わりにOnTick() ブロックでロードされます。データロードブロックが OnInit() にあれば、データの中にはロードされるのが遅いものがあり、結果としてインディケータは正確に完全に計算されなくなります。結局計算データが取得され err 変数値は静になりこのブロックは処理から除外されてしまいます。
結果のインディケータは最後の7個の ZigZag ノードをプロットし、既定の履歴についてその他ノードすべての座標を計算します(図6)。計算は一度だけ行われ、その計算データをのちに使用します。もちろんデータが定期的に更新されるように実装することもできますが、本稿では単一パスのままにしておきます。
図6 ZigZag インディケータ(7ノード)
そして Envelopes インディケータの表面の断面をプロットします。このためには OnTick() メソッドに以下を追加します。
//--- PEAKS sumH[0]=0.0; maxH[0]=0.0; minH[0]=0.0; for(int i=0; i<NUMBER_MA; i++) { CopyBuffer(handle_MA_H[i],0,t[0],1,MA); double envelope=MA[0]+sumHi[i]/H; if(i==0 || envelope<minH[0]) { minH[0]=envelope; t_min=SIZE(i); } if(envelope>maxH[0]) { maxH[0]=envelope; t_max=SIZE(i); } sumH[0]+=envelope; name="H"+(string)i; ObjectCreate(0,name,OBJ_TEXT,0,0,0); ObjFont ObjCoordinates(t[0]-(NUMBER_MA-i*2)*shift,envelope) ObjProperty(SIZE(i),158,clrBlue) } //--- TROUGHS sumL[0]=0.0; maxL[0]=0.0; minL[0]=0.0; for(int i=0; i<NUMBER_MA; i++) { CopyBuffer(handle_MA_L[i],0,t[0],1,MA); double envelope=MA[0]-sumLo[i]/L; if(i==0 || envelope<minL[0]) { minL[0]=envelope; t_min=SIZE(i); } if(envelope>maxL[0]) { maxL[0]=envelope; t_max=SIZE(i); } sumL[0]+=envelope; name="L"+(string)i; ObjectCreate(0,name,OBJ_TEXT,0,0,0); ObjFont ObjCoordinates(t[0]+(NUMBER_MA-i*2)*shift,envelope) ObjProperty(SIZE(i),158,clrGold) }
エンベロープラインで形成される表面の断面点を識別するには、ポイントはサイズを変えます。 Envelopesインディケータのメインラインの平均期間が大きいほど、ポイントは大きくなります(図7)。その上、断面は現(ゼロ)バーを異なる方向に横切る縦軸の周囲で回転します。頂点は右に90°、谷は左に90°です。
これでそれらは価格チャート平面に表示できます。最初それらは切り取った平面にありました(図5)。そして観測できませんでした。それらをわれわれに対して描画することができただけでその形についてなにも考えていませんでした。断面線はひじょうに特殊な形でることが判ります。これはグラフ分析に都合がよいようにされています。視覚的に断面は2つの彗星のようです。
図7 Envelopes インディケータプールの断面
断面特性の計算に進みます。最大、最小、重心(算術的平均)です。結果の値は現在バー上の点として表示されます。適切な特性のサイズに対応するポイントサイズを伴います。またそれらをのちの分析のため履歴に保存します。そのため既存コードに以下を追加します。
//--- PEAKS ... //--- midi string str=(string)t[0]; name="Hmidi"+str; ObjectCreate(0,name,OBJ_TEXT,0,0,0); ObjFont ObjCoordinates(t[0],sumH[0]/NUMBER_MA) ObjProperty(10,119,clrBlue) //--- max name="Hmax"+str; ObjectCreate(0,name,OBJ_TEXT,0,0,0); ObjFont ObjCoordinates(t[0],maxH[0]) ObjProperty(t_max,158,clrBlue) //--- min name="Hmin"+str; ObjectCreate(0,name,OBJ_TEXT,0,0,0); ObjFont ObjCoordinates(t[0],minH[0]) ObjProperty(t_min,158,clrBlue) ... //--- TROUGHS ... //--- midi name="Lmidi"+str; ObjectCreate(0,name,OBJ_TEXT,0,0,0); ObjFont ObjCoordinates(t[0],sumL[0]/NUMBER_MA) ObjProperty(10,119,clrGold) //--- max name="Lmax"+str; ObjectCreate(0,name,OBJ_TEXT,0,0,0); ObjFont ObjCoordinates(t[0],maxL[0]) ObjProperty(t_max,158,clrGold) //--- min name="Lmin"+str; ObjectCreate(0,name,OBJ_TEXT,0,0,0); ObjFont ObjCoordinates(t[0],minL[0]) ObjProperty(t_min,158,clrGold)
それではグラフとして表現するとどのように見えるか確認します。
図8 断面特性:それぞれ頂点と谷に対してプロットされた最大点、最小点、重心
高度な ZigZag ノードを見つけプロットすることで最期の仕上げを加える必要があります。下記を追加することでコードを強化します。
//--- ZigZag: advanced nodes if(Azz.zHL[0].type>0) // peak { ObjectDelete(0,"MIN"); ObjectDelete(0,"MINfuture"); name="MAX"; ObjectCreate(0,name,OBJ_TREND,0,0,0); ObjZZ ObjectSetDouble(0,name,OBJPROP_PRICE,0,Azz.zHL[1].value); ObjectSetInteger(0,name,OBJPROP_TIME,0,Azz.zHL[1].time); ObjectSetInteger(0,name,OBJPROP_TIME,1,t[0]); double price=minH[0]; ObjectSetDouble(0,name,OBJPROP_PRICE,1,price); if(Azz.zHL[0].value>minH[0]) { price=sumH[0]/NUMBER_MA; ObjectSetDouble(0,name,OBJPROP_PRICE,1,price); } if(Azz.zHL[0].value>sumH[0]/NUMBER_MA) { price=maxH[0]; ObjectSetDouble(0,name,OBJPROP_PRICE,1,price); } //--- into the future name="MAXfuture"; ObjectCreate(0,name,OBJ_TREND,0,0,0); ObjZZ ObjectSetDouble(0,name,OBJPROP_PRICE,0,price); ObjectSetInteger(0,name,OBJPROP_TIME,0,t[0]); ObjectSetDouble(0,name,OBJPROP_PRICE,1,maxL[0]); ObjectSetInteger(0,name,OBJPROP_TIME,1,t[0]+NUMBER_MA*shift); if(price<maxL[0]) ObjectSetDouble(0,name,OBJPROP_PRICE,1,sumL[0]/NUMBER_MA); if(price<sumL[0]/NUMBER_MA) ObjectSetDouble(0,name,OBJPROP_PRICE,1,minL[0]); } if(Azz.zHL[0].type<0) // trough { ObjectDelete(0,"MAX"); ObjectDelete(0,"MAXfuture"); name="MIN"; ObjectCreate(0,name,OBJ_TREND,0,0,0); ObjZZ ObjectSetDouble(0,name,OBJPROP_PRICE,0,Azz.zHL[1].value); ObjectSetInteger(0,name,OBJPROP_TIME,0,Azz.zHL[1].time); ObjectSetInteger(0,name,OBJPROP_TIME,1,t[0]); double price=maxL[0]; ObjectSetDouble(0,name,OBJPROP_PRICE,1,price); if(Azz.zHL[0].value<maxL[0]) { price=sumL[0]/NUMBER_MA; ObjectSetDouble(0,name,OBJPROP_PRICE,1,price); } if(Azz.zHL[0].value<sumL[0]/NUMBER_MA) { price=minL[0]; ObjectSetDouble(0,name,OBJPROP_PRICE,1,price); } //--- into the future name="MINfuture"; ObjectCreate(0,name,OBJ_TREND,0,0,0); ObjZZ ObjectSetDouble(0,name,OBJPROP_PRICE,0,price); ObjectSetInteger(0,name,OBJPROP_TIME,0,t[0]); ObjectSetDouble(0,name,OBJPROP_PRICE,1,minH[0]); ObjectSetInteger(0,name,OBJPROP_TIME,1,t[0]+NUMBER_MA*shift); if(price>minH[0]) ObjectSetDouble(0,name,OBJPROP_PRICE,1,sumH[0]/NUMBER_MA); if(price>sumH[0]/NUMBER_MA) ObjectSetDouble(0,name,OBJPROP_PRICE,1,maxH[0]); }
これで新規ノードのポジションを予測する新しい高度な ZigZag インディケータを入手しました(図9)。ノード自体は特徴断面点:最大点、最小点、重心にあります。このインディケータの実用的なタイトルは『2つの彗星』です。
将来のことになりますが、次ノードの完了時刻は判らないことに注意が必要です。基本的にノード1個の座標-価格が予測できるだけです。
図9 高度な ZigZag インディケータは現ノードと次ノードを予測します。i
結果分析と開発者への提言
インディケータの観測から以下を提示します。
- 予測されたノードからの ZigZag ノード座標の偏差は許容範囲内です。大量のノードは対応する断面の陰にあります。これは確かに定量的な評価です。より正確な結果は今後の記事に続きます。
- エンベロープラインの断面はマーケット動向と予想価格変動を示しています。最小平均期間(最小サイズ)を持つ点でできた彗星の尻尾に注意が必要です。それは価格方向で指示されています。彗星の尻尾はもっとも複雑な方法で曲がり、逆方向にまがる度合が大きいほど、トレンド変更の可能性が大きくなります。ただ異なる振幅を持つ異なるタイムフレームで変動を観察します。これはひじょうに興味深いものです。
- 価格変動に対するレジスタンスを強く表示する可能性のあるラインからの断面の特徴点です。よってそれらはサポートおよびレジスタンスラインとみなすことができます。
- 断面の重心がそれよりの先にくるとき(図9の頂点のように)、これは上昇トレンドが存在することを示しています。
結果入手したものはトレーディング戦略で試してみることのできるひじょうに興味深いインディケータです。
おわりに
- 本稿で検討した ZigZag インディケータノードを予測する方法により新しいインディケータ『2つの彗星』を作成することができました。
- 高度な ZigZag は、予測にすぎないとしても、新しいノードの可能性ある座標を表示します。
- 本稿で考察したアルゴリズムは ZigZag インディケータに限らず、たとえばフラクタルインディケータやセマフォインディケータのような、類似の高度なインディケータをプロットするのに利用可能です。
- 初心者の MQL5プログラマーの方はそれらがプログラムの中で繰り返されるコードの量を減らすためにどのようにマクロを策絵師するか確認するのがおもしろいと思われるかもしれません。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/646
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索