
MQL5でのレジスタンス・サポートレベルの描写
コンテンツ表
- イントロダクション
- 目的
- 簡潔にサポートレベルとレジスタンスレベルを描写する方法
- 極値を見つける方法
- 安値のインデックス(最初のバー)で極値のバーを求める関数Ext_1
- 後のすべての極値を見つけるための一般的な関数Ext_2
- 結果の処理
- サポートとレジスタンスのレベルの表示例
- 結論
イントロダクション
まず、サポートおよびレジスタンスが何であるか、取引で使用する方法をご紹介します。
すべてのトレンド、ライン、モデルは、古典的なトレンド分析の基礎となるサポートとレジスタンスの組み合わせによってできています。抵抗線は、トレーダー("ブル")が、それより高い価格で通貨を買わない最大値、オープンポジションを閉じる最大値に基づいています。金融商品の価格は、"ベア"の間で発生するロールバックに応答します。すなわち、サポートラインは、最小価格に基づいます。
これにより、極端に買われたときに最大の極値は形成され、極端に売られたときに最小の極値が形成されると考えられます。このような理由により、サポートとレジスタンスを描写する際、RSIを利用します。RSIはJohn Wilder氏が1978年に発表したインジケーターです。この指標は、通貨の買われ過ぎや売られ過ぎゾーンを決定します。
8期間でRSIインジケータを使用します。この値は観察の結果ではありません。 - このRSIの設定は、日足やそれ以上の足以外のチャートで、エリック・L・ナイマンの著書「小さなトレーダーの百科事典」によって推奨されています。RSI(8)の設定の結果に完全に満足するものだと思います。
高値と安値を探すときにティックを利用するかどうかということについて、二つの反対する見解があります。(High/Low)個人的には、極値点を探すときには、高い価格と低い価格を比較しています。それらを考慮にしたくない場合は、シンプルに以下のインジケータコードに少しの変更を加えることができます。
サポートとレジスタンスラインを使った取引は、ラインの外側で起こる可能性もラインのウ内側で起こる可能性もあります。
図1. 買いシグナル
比較的効果が薄い2番目の手法は、価格が片方の極値からロールバックした場合に、トレードの決定をする方法です。図1は、価格がレジスタンスラインからロールバックした後にサポートラインに到達せず、レジスタンスラインをブレイクしたケースを表しています。これは強い買いのシグナルです。「時間軸をクロスしているライン」で形成された角度を分析することにより、トレンドの方向を定義することができます。そして、価格が片方のラインをクロスしたとき、今のトレンドを強化、もしくは逆だと判断を下すことができます。例えば、サポートラインをクロスする前に、価格がレジスタンスの中心まで到達することがあります。(これはトレードシグナルを強化する要因です。)
"オートチャーティスト"と呼ばれるプラットフォームがあり、トレンドを認識するためにデザインされています。実験として、2ヶ月間、私はレジスタンスやサポートレベルからの価格のロールバックの信号を使用して、デモ口座で取引しました。 - この場合のほとんどのトランザクションは、ブレイクスルーレベルによるシグナルを仕様したトレードとは異なり、損失で終わりました。
サポートとレジスタンスのレベルもまた、トレンドの加速または減速を決定するために使用します。強気傾向のトレンドラインの角度の増加は、継続トレンドにつながる加速を、意味しています。弱気トレンドの角度の増加は、逆に、トレンドの鈍化を示しています。(低価格で描かれた)のサポートラインは強気トレンドのトレンドラインとして機能し、(高価格で描かれた)抵抗線は、弱気トレンドのトレンドラインとして機能します。
図2. ブルトレンドの減速
図3. ベアトレンドの減速
トレンドの減速は、最も近い将来、その反転を示唆しているかもしれません。
目的
支持線と抵抗線で形成されたチャートの分析は、テクニカル分析の最も古い方法の1つです。外国為替市場での取引の経験から、上記の方法は古典的ですが、まだ有効だと考えられます。多くのトレーダーが使用しているでしょう。手でMT5に支持線と抵抗線を描くことは、知識があるトレーダーには簡単な作業です。しかし、自動的にラインを描写するプログラムを生成するのは誰にでもできることではありません。
この記事では、サポートラインとレジスタンスラインを描写する私自身の方法を提案したいと思います。これはMQL5でもMQL4でも実装可能です。この情報を有効に活用できることでしょう。
簡潔にサポートレベルとレジスタンスレベルを描写する方法
多くの場合、価格はレジスタンスラインとサポートラインの間に位置します。この事実はGleb Slobodovの記事 をベースにしています。結果として、価格の病徴の範囲を定義する2つの水平レベルを得ることになります。どちらかのブレイクは、おそらく、買いまたは売りのシグナルです。しかし、この原則には欠点がいくつかあります。:
- 分析する足の数は手動で選択され、これがレジスタンスやサポートの値に影響します。
- 描画レベルの過程は完全に自動化され、自動取引システムを作成する可能性が排除されます。
- この方法を使うと、トレンドの方向と強さを分析する水平ラインを得ます。
Igor Geraskoのトレード手法のサポート・レジスタンスレベルのインジケーターは、水平レベルを定義しています。
この記事では、サポート・レジスタンスラインを描写する原則を紹介します。これにより、トレンドの方向、強さ、形状を決定することができます。これらのラインは、最小値と最大値の極値に基づいています。
極値を見つける方法
特定の期間における、高値と安値を決定する方法は難しくありません。分析するチャートの長さを選択することが重要です。チャートは常に変化するので、手動でセットすることはできません。チャートのセクションを見つけるには、RSIを使用します。MT5の指標の標準セットに含まれています。
買われ過ぎや売られ過ぎレベルはRSIのレベルに応じて決定されます。これらの瞬間に、通貨ペアチャートは、価格のロールバックにつながるその方向(傾向)から外れます。具体的には、最小値と最大値を探すするギャップで、極値が形成されることになります。
売られ過ぎの水準はRSIの35; 買われ過ぎの水準は65 (RSI = 50が中央値です). RSIの期間は8。
強いトレンドの中では、RSIは何度も上のラインをクロスし、下側に到達しないことがあります。トレンド方向に対応していないレベル調整の必要性につながります。
図4. 極値の足のゾーン
それぞれ上記の図では、極値バーの検索領域を指定しています。番号1、2、3、4と番号を対応させています。低いライン(=35 RSI)をクロスする前に、現在の足のRSIが買われ過ぎのゾーン(RSI>=65)に3回到達しています。したがって、最初の極値を探索するための3つの時間間隔があります。さらに、探索ゾーンは連続した3つの足によって順番に決定されます。
ゾーン1と3では、高値の足が見て取れ、ゾーン2、4では安値を見ることができます。結果として、4つの極値点を取得できます。 — 線を組み合わせることにより、プライスチャネルが出来上がります。
図5. 上昇チャネル
注意深く観察すると、最小値を探索する足の数が極めて少ないことに気付くかもしれません。たった、4本 (それぞれに2). 上昇トレンドの影響で、RSI=65の外側でインジケーターが35<RSI<65のチャネルの中にある間、RSIは最小レベルにかろうじてタッチします。よって、この記事でのインジケーターのコードは、RSIを中央にシフトして使います。 (50). 最初の極値点に応じて、RSIの高い値と低い値がセットされます。
すべての通貨ペア、RSIレベルチャート値と1つの後続の偏差の値のすべての期間は、実験的に選択されます。*これは極値を決定する上での欠点だと言えるでしょう。
安値のインデックス(最初のバー)で極値のバーを求める関数Ext_1
"Ext_1"の極値を探索する関数には、下記のインプットパラメータがあります。:
int Ext_1(double low, //RSIが低い 売られ過ぎ double high, //RSIが高い 買われ過ぎ int bars, //分析する足の数 不必要なデータは排除 //足 = 300 int h_rsi, //RSIのハンドル string symbol, //チャートのシンボル float distans, //インジケーターからの偏差 //初めの極値の足の境界を定義 ENUM_TIMEFRAMES period_trade) //チャートの期間
最初の2つの関数の入力パラメータは、RSI指標のパラメータです。レベルの指標線の位置は、インジケータラインの計算に何の役割も果たしません。目視のためにのみ使用されます。最小値と最大値を検索する価格帯を決定するために、これらのレベルを使用します。パラメーター"low" と "high" は、インジケータコードに設定され、関連する外部変数の値を取得します。:
input double Low_RSI = 35.0; // 極値を見つけるためのRSIの下側の水準 input double High_RSI= 65.0; // 極値を見つけるためのRSIの上側の水準
インプットパラメータ"bars"は、RSIインジケーターの値同様に、LowとHighの足の価格を含む配列にコピーされた要素の数を設定します。
double m_rsi[],m_high[],m_low[]; //配列の初期化 int h_high = CopyHigh(symbol, period_trade, 0, bars, m_high); //高値の足の配列 int h_low = CopyLow(symbol, period_trade, 0, bars, m_low); //安値の足の配列 if(CopyBuffer(h_rsi, 0, 0, bars, m_rsi)<bars) //RSIの値を配列に { Print("バッファのコピーに失敗!"); }
Arrays m_rsi[],m_high[] and m_low[] have reverse indexing order:
ArraySetAsSeries(m_rsi,true); ArraySetAsSeries(m_high,true); ArraySetAsSeries(m_low,true);
前述のように、強気トレンドでは、0から100までの値を持つRSIは、ほとんどの時間、>50の値を持つことになります。極小点が形成されるとき、RSIは極大点の形成期間と比較して、中心(50)から離れていない。したがって、インジケーターの1つの値がクロスしているとき、もう一つの値は中心に近いところにシフトする必要があります。ずれの大きさは、外部変数の値が与えられた入力パラメータ"distans"によって決定されます。
input float Distans=13.0; // RSIの偏差
"Ext_1"関数のインプットパラメータ"h_rsi"は、RSIハンドルの値を取得します。このハンドルはiRSI()関数の初期化の際に生成されます。:
h_RSI=iRSI(Trade_Symbol,Period_Trade,Period_RSI,PRICE_CLOSE); //RSIのハンドルを返す
変数Trade_Symbol とPeriod_Trade は、グローバルレベルで初期化されます。これには、現在通貨ペアとチャートの期間の情報を含まれます。変数Period_RSI は、RSIの期間の値を内包しています。:
input uchar Period_RSI =8; // RSIの期間
一度High・Lowの足の価格の配列を生成し、代入すると、最初の極値の探索を実際にすることができるようになります。最初の極値を決定し、即座に分析を中止するために、二つのbool型の変数が必要になります。:
bool ext_max = true; //止めるためのbool型変数 bool ext_min = true; //適切なタイミングで足を分析
ext_max= trueは、極大値の探索許可、ext_min=trueは、極小値の検索を許可します。(上側または下側の)水準のRSIインジケータの最初の交点で、bool変数の1つの値がfalseに変更されます。その無効にされたRSIの水準は、要求された足の数が分析され、最初の極値が求められたことを意味します。
最初の足を分析で、RSIの値がそのレベルの外にある場合、極値が発生する価格幅の形成がされていないことがありえます。その場合は、分析の余地はありません。そのような足の分析は除外します。下の図は、分析が行われていないときの価格帯を強調しました。(上側のレベルにRSIインジケータラインの位置):
図6. 不完全な価格幅のときには分析を中止します。
このような動作を実現するためには、bool型の別の変数を作成する必要があります。:
bool flag=false;
分析する足の最大値と最安値を決定するために、double型の変数を追加する必要があります。:
double min = 100000.0; //最大値と最小値を認識させるための変数 double max = 0.0; //...
最初の極値の探索用のループ処理は下記のとおりです。:
for(int i=0;i<bars;i++) //繰り返し処理 { double rsi = m_rsi[i]; //RSIの値を取得 double price_max = NormalizeDouble(m_high[i], digits); //高値 double price_min = NormalizeDouble(m_low[i], digits); //選択された足の安値 if(flag==false) //極端な探索を避ける条件 { if(rsi<=low||rsi>=high) //買われ過ぎ売られ過ぎのゾーンでの最初の足, continue; //次の足へ else flag = true; //それ以外の場合、分析に移行 } if(rsi<low) //RSIが下側で見つかった場合 { if(ext_min==true) //RSIが上側でクロスしなかった場合 { if(ext_max==true) //最大値の探索が無効にされていない場合 { ext_max=false; //極大値の探索を無効に if(distans>=0) high=high-distans; //上の水準を変更 } //次の足の探索を開始 if(price_min<min) //最初の足のインデックスを探索し、記録 { //安値を比較 min=price_min; index_bar=i; } } else break; /*極小値がすでに無効にされている場合、ループを離脱, これは極大値が見つかったことを意味します*/ } if(rsi>high) //さらに言えば、極大値を探すときのアルゴリズムは同じです。 { if(ext_max==true) { if(ext_min==true) { ext_min=false; if(distans>=0) low=low+distans; } if(price_max>max) { max=price_max; index_bar=i; } } else break; /*極大値の探索が無効の場合、ループを離脱, 極小値が見つかっていることを意味します。*/ } }
後のすべての極値を見つけるための一般的な関数Ext_2
この関数はExt_1と同じインプットパラメーターを受け取ります。さらに、3つの重要なパラメータがあります。:
- 極値の足のインデックスを保存する構造体への参照を含むパラメータ。極値の検索が開始されている足のインデックスから決定するために必要とされます。
- 極値の足のシリアルナンバーが見つかります。(2 から 4). どちらのラインから極値を決定するかということと同様に、構造体から想定の足のインデックスを選択することが必要です。
- ラインを決定するbool型のパラメータが配置されます。この情報なしでは、どちらのラインに足を配置するかを決定することは不可能です。
int Ext_2(double low, //RSIの下の水準 売られ過ぎ double high, //RSIの上の水準 買われ過ぎ int bars, //分析する足の数 不必要なデータを配列にコピーすることを防ぐ int h_rsi, //RSIのハンドル string symbol, //チャートシンボル st_Bars &bars_ext,//見つかった足のコードを含む構造体 char n_bar, //足の一般的な数(2,3 or 4) float distans, //1つのインジケーターからの偏差 bool first_ext,//最初の足のタイプ ENUM_TIMEFRAMES period_trade)//チャートの期間
グローバルレベルでは、4つの極値のインデックスを含む構造体を生成します。:
struct st_Bars //構造体の初期化 { int Bar_1; int Bar_2; int Bar_3; int Bar_4; }; st_Bars Bars_Ext; //構造体タイプの宣言
極値が位置づけられるインジケーターラインを決定するために、まず、bool型の2つの変数を生成します。:
bool high_level= false; //足のタイプを決定する変数 bool low_level = false; //...
極値の足の序数が2か4の場合、かつ、最初の極値の足がサポートラインにある場合、想定される足はレジスタンスラインになければなりません。したがって、RSIの値が上のレベル(上のパラメータ)よりも高い足を分析することが必要です。想定の極値の足の序数が3の場合、かつ、最初の極値の足がサポートラインにある場合、想定の足はこのライン上にあります。最初の極値の足がレジスタンスライン上にある場合、想定の足の位置はそれに応じて選択されます。
if(n_bar!=3) { if(first_ext==true)//最初のポイントが極大 { low_level=true;//これは最小になる* if(distans>=0) low=low+distans; //必要ならば、RSIの下の水準を変える } else //極小の場合 { high_level = true; if(distans>=0) high=high-distans; //必要ならば、RSIの上の水準を変える } } else { if(first_ext==false)//最初のポイントが極小の場合 { low_level=true;//このポイントは最小になります if(distans>=0) high=high-distans; //必要ならばRSIの上の水準を変える } else //極大の場合 { high_level = true; if(distans>=0) low=low+distans; //必要ならば、RSIの下の水準を変える } }
bool型のもう一つの変数は、想定の極値が見つかり足の分析をやめるタイミングを決定するのに必要です。
bool _start = false;
履歴上で分析対象の足のレンジが分かったとき、この変数の値はtrueに変わります。_start = trueかつ、 low_level = true でRSIが上のラインをクロスしたとき、high_level = trueでRSIが下のラインヲクロスしたとき、足の分析が終了します。
if(_start==true && ((low_level==true && rsi>=high) || (high_level==true && rsi<=low))) break; //2番目の極値が見つかりったときループを離脱し、RSIが反対側に到達
下記は極値の探索のループ処理:
for(int i=bar_1;i<bars;i++) //今ある足の分析 { rsi=m_rsi[i]; price_max = NormalizeDouble(m_high[i], digits); price_min = NormalizeDouble(m_low[i], digits); if(_start==true && ((low_level==true && rsi>=high) || (high_level==true && rsi<=low))) { break; //2番目の極値が見つかったらループ離脱、RSIが反対側に到達 } if(low_level==true) //極小値を探索する場合 { if(rsi<=low) { if(_start==false) _start=true; if(price_min<min) { min=price_min; index_bar=i; } } } else //極大値を探索する場合 { if(rsi>=high) { if(_start==false) _start=true; if(price_max>=max) { max=price_max; index_bar=i; } } } }
変数 Bar_1 は、前の極値の足のインデックスです。これはスイッチ文で計算されています。:
switch(n_bar) //前の足のインデックスを探索 { case 2: bar_1 = bars_ext.Bar_1; break; case 3: bar_1 = bars_ext.Bar_2; break; case 4: bar_1 = bars_ext.Bar_3; break; }
最初の極値の足があるインジケーターラインを見つけるためには、RSIの値とインデックスを取得するれば十分です。:
bool One_ext (st_Bars & bars_ext, // 最初の足のインデックスを取得するための構造体の変数 string symbol, //チャートシンボル int h_rsi, //インジケーターのハンドル double low, //RSIの売られ過ぎの水準をセット ENUM_TIMEFRAMES period_trade) //チャートの期間 { double m_rsi[]; //インジケーターのデータの初期化 ArraySetAsSeries(m_rsi,true); //インデックス化 CopyBuffer(h_rsi,0,0,bars_ext.Bar_1+1,m_rsi); //RSIで配列 double rsi=m_rsi[bars_ext.Bar_1]; //足のRSIの値を最初の極値で定義 if(rsi<=low) //値が下の水準よりも低いとき, return(false); //最初の極値が最小 else //それ以外, return(true); //極大値 }
結果の処理
これで、4つすべてのインデックスと対応する価格を知ることができます。(高値か安値)それぞれの足にあるインジケーターの値の配列を満たすために、レジスタンスラインとサポートラインに対応する2つのラインの方程式を取得する必要があります。良く知られている方程式です。: y = kx + b. 今回のケースの場合、"x"は足のインデックス、"y"は価格です。(サポートラインは足の安値 レジスタンスラインは足の高値).
"k"と "b"の係数の値を求めるためには、それぞれの2つの極値の足の値を置き換え、得られた方程式の形式を統合すればOKです。その結果、下記の方程式が得られます。:
K=(price_2-price_1)/(_bar2-_bar1); //係数K B=price_1-K*_bar1; //係数B
ただし、
double K,B;
"K" と "B"は方程式上の係数"k"と"b"に対応するグローバル変数です。;
int _bar1,_bar2;
これは、同じライン上の足のインデックスです。;
double price_1,price_2;
"K" と "B"を定義する必要がある場合、それぞれの足の安値です。 レジスタンスラインの"K" と "B" を決定する必要がある場合、サポートラインかそれぞれの足の高値です。
レジスタンスライン用のパラメータ "_line" がfalseの場合、"_line" が trueの場合、下記の関数はグローバル変数"K" と "B"をサポートラインにセットします。:
void Level(bool _line, //係数を見つけるための、レジスタンスラインとサポートラインを定義するパラメータ bool _first_ext, //最初の極値のタイプ st_Bars &bars_ext, //足のインデックスを含む構造体 string _symbol, //シンボル ENUM_TIMEFRAMES _period) //チャートの期間 { int bars=Bars_H; //分析した足の数 double m_high[],m_low[]; //配列の初期化 ArraySetAsSeries(m_high,true); //最初の要素から ArraySetAsSeries(m_low,true); //... int h_high = CopyHigh(_symbol, _period, 0, bars, m_high); //足の高値の配列を満たす int h_low = CopyLow(_symbol, _period, 0, bars, m_low); //足の安値の配列を満たす double price_1,price_2; int _bar1,_bar2; int digits=(int)SymbolInfoInteger(_symbol,SYMBOL_DIGITS);//現在のシンボルで小数点以下の桁数 if(_line==true) //レジスタンスラインが必要な場合 { if(_first_ext==true) //最初の極値が最大の場合 { price_1 = NormalizeDouble(m_high[bars_ext.Bar_1], digits); price_2 = NormalizeDouble(m_high[bars_ext.Bar_3], digits); _bar1 = bars_ext.Bar_1; _bar2 = bars_ext.Bar_3; } else //最小値 { price_1 = NormalizeDouble(m_high[bars_ext.Bar_2], digits); price_2 = NormalizeDouble(m_high[bars_ext.Bar_4], digits); _bar1 = bars_ext.Bar_2; _bar2 = bars_ext.Bar_4; } } else //サポートラインが必要な場合 { if(_first_ext==true) //最初の極値が最大の場合 { price_1 = NormalizeDouble(m_low[bars_ext.Bar_2], digits); price_2 = NormalizeDouble(m_low[bars_ext.Bar_4], digits); _bar1 = bars_ext.Bar_2; _bar2 = bars_ext.Bar_4; } else //最小の場合 { price_1 = NormalizeDouble(m_low[bars_ext.Bar_1], digits); price_2 = NormalizeDouble(m_low[bars_ext.Bar_3], digits); _bar1 = bars_ext.Bar_1; _bar2 = bars_ext.Bar_3; } } K=(price_2-price_1)/(_bar2-_bar1); //係数K B=price_1-K*_bar1; //係数B }
ラインの方程式は: y = kx + b 、ただし、株価が "y"軸、足のインデックスが "x"軸。"x"軸は1970年1月1日からの経過秒です。休日は"カオスな"結果になるので、足を使います。
"OnCalculate"関数から、"Level"関数を2回呼び出します。: 1回目はレジスタンスラインの配列を満たす前に、2回目はサポートラインの配列を満たす前に。:
for(int i=0;i<Bars_H;i++) { resistanceBuffer[i]=NormalizeDouble(K*i+B,Dig); } Level(false,First_Ext,Bars_Ext,Trade_Symbol,Period_Trade); //レジスタンスラインのKとBの係数を取得 for(int i=0;i<Bars_H;i++) { supportBuffer[i]=NormalizeDouble(K*i+B,Dig); }
サポートラインとレジスタンスラインを表示するインジケーターの例
下記は、すべての関数を使ったインジケーターの稼働とサポートライン・レジスタンスラインの描写の様子です。:
図7. インジケーターの実行結果
このインジケーターは、新しい足の形成後に、このような方法で構築されています。サポートラインとレジスタンスラインの配列は変更され、自動的に再描写されます。しかし、ラインの一方の角度計算し記録し、新しい足での値と比較すると、前述のように、トレンドの加速度を測ることができます。
このインジケーターの全体のコードはこの記事に添付されています。
結論
確かに、インジケーターのパラメーターなどをいじったり、設定する必要はないので、このようなラインを手動で描く方がより簡単ではあります。しかし、このインジケーターは自動売買システムの戦略の一部として使う場合には基本となります。インジケーターラインの配列データを受け取った後、角度を分析し、トレンドの方向を出すことが可能です。サポートラインやレジスタンスラインのブレイクと同様に、買いと売りのシグナルの優位性やプライスチャネル内のトレードを分析することが可能になります。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/1742




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