古典的な隠れたダイバージェンスを解釈する新しいアプローチ第2部

Alexander Lasygin | 13 11月, 2019

はじめに

第1部では、ダイバージェンスの解釈に対する非標準的なアプローチを検討しました。それに関連するグラフィカルな構造を分析し、ダイバージェンス自体、ダイバージェンスの認識の品質とその分類について簡単に触れましたが、この記事では、パターンに基づいて取引される取引のフィルタリングについては取り上げませんでした。しかし、私たちが当たり前だと思っていることは、必ずしもそれほど明確ではありません。古典的なダイバージェンスはまだ効率的なのでしょうか。市場が大きく変化したため、このアプローチはもはや時代遅れかもしれません。本稿では、古典的なバージョンとその非標準的な解釈をさらに詳しく見ていきます。この戦略の評決を下し、結果が肯定的であれば、その有効性の向上を試みます。

用語及び定義

主要部分に進む前に、この研究の基礎となった前史について少し言及し、その「非標準」の性質を説明したいと思います。私は、ダイバージェンスの原則に基づいて売買ロボットを作成しようとする志を同じくする人々のチームでテクニカルアナリストとして働いていました。私の仕事は、できるだけ多くの関連データを収集し、既存のテクニカル分析ツールを分析し、最適なバリアントを決定することでした。

また、シグナル形成後のイベントの発生の可能性を考慮する必要もありました。私の研究と分析はすべて時間と労力の無駄でした。望ましい結果は、CPUと人的資源を浪費するかわりに考えることで得ることができます。ただし、私の研究には肯定的な結果がありました。既存のものとは異なる指標が作成され、テクニカル分析を複雑にしていた概念が変更または除外されました。A、B、Cのようなクラスが排除され、パターンとしてのダイバージェンスはより単純化され、存在するかどうかにとどまります。

シグナルとしてのダイバージェンスは、新しい命を受けました。この作業の過程で、平均化、平滑化、再計算のいずれの形式も市場の行動とは無関係であることが明らかになりました。これは事実を私たちの知覚に適合させる試みです。ここでの主な目的は、巨大な研究論文を作成することではなく、このパターンが取引に適しているかどうかを確認することです。後でこれに戻ります。関連データ検索では結果が得られませんでした。基本的な情報を受け取るために、異なる著者が皆、同じソースを使用しているように見えました。

この原則に基づいた戦略の最も詳細な説明は、アレキサンダー・エルダーの著書「技術分析における最強のシグナル」で提供されています。ここでは、ダイバージェンスとトレンド反転が説明されています。この本を読んだ後、私にはさらに質問が増えました。著者は、指標はゼロラインを横切らなければならないという義務的な条件を設定しますが、「missing the right shoulder」章では、これがオプションの条件である瞬間について説明しています。

その瞬間、MetaStock端末には線形MACDがなく、代わりに、ターミナルサブウィンドウにはゼロバインディングなしの2つのMAが描画されていました。その結果、著者が説明した方法で使用することはできません。エルダーはMACDのバージョンを使用します。これはMetaTrader 4/5ターミナルでOsMAと名付けられていますが、本書ではMACDと呼ばれています。コンバージェンス(逆ダイバージェンス)の説明はありません。ここで、コンバージェンスという用語は、引き続き価格アクションと指標の間の相違を表します。さらに、エルダーは、バランスライン(ゼロの交差)を持たない他の指標を使用した分析を拒否しています。特に、ストキャスティクスが言及されています。

より深い分析のために、他の著者は、メインパターンをA、B、Cの3つのサブグループに分割しました。その発想は、ダイバージェンスが大きいほどシグナルが大きくなるため、コンバージェンスをまったく考慮すべきではないということです。この発想は本当に有効なのでしょうか。前の資料で、関連する分布を例として示しました。私がこのグラデーションに同意しなかった理由の説明は、第1部の範囲を超えていたため、すべてをそのままにすることにしました。

これらの用語のほとんどは使用されませんが、一部の用語は、発生していることの全体像を説明するためにのみ使用されます。 これを読んだ後、ダイバージェンスが事実として存在するという考えを持つかもしれませんが、ダイバージェンス-コンバージェンスの分布は前の記事で説明した追加のグラフィカルな構造のコンテキストでのみ考慮されます。ダイバージェンス自体は、条件付きで「停止」と「反転」に分けられます。分類に条件があるのは、シグナルは本質的に停止シグナルで、その後、確認シグナルが、市場が反転するかどうかを示すことができるためです。

いくつか例を考えてみましょう。

クラスAダイバージェンス

最強と考えられています。

弱気 — 新しい価格の高値は以前の高値よりも高く、新しい指標の高値は以前の高値よりも低くなっています。

強気 — 新しい価格の安値は以前の安値よりも低く、新しい指標の安値は以前の安値よりも高くなっています。


図1

このようなダイバージェンスは、強い価格変動(モメンタム)の後に観察されます。ほとんどの場合、そのようなモメンタムは新しいトレンドの出現のシグナルです。つまり、クラスAダイバージェンスは「強さ」によってこのルールを取り消し、市場行動の慣性を取り消し、一般的には、波動理論全体を取り消します。上の図の右半分は、パターンが正しく検出されているかどうかの疑いを引き起こす可能性があります。以下の図は疑いを引き起こさないようです。


図2

このような始まりは、2、3、またはそれ以上のダイバージェンスを引き起こす可能性があります。モメンタムが強いほど、トレンドは長く続くことができます。これは、ダイバージェンスが大きいほどシグナルが強いという考え方と矛盾します。

クラスBダイバージェンス

それほど重要でない市場シグナルです。

弱気 — チャートの高さは同じレベルですが、右のオシレータの高さは左のオシレータよりも低くなっています。

強気 — 価格の高値は同じレベルですが、右の指標レッグは左の指標レッグよりも高くなっています。

これは何かを連想させるでしょうか。これらは、古典的なローソク足パターン「ダブルトップ」と「ダブルボトム」で、ソースでは、「強い市場逆転パターン」として説明されています。したがって、これは停止パターンではなく、反転パターンで、主要な5つのパターンの1つです。


図3

最後のサブタイプです。

クラスCダイバージェンス

最も弱いと見なされ、このパターンは無視すべきだという意見があります。

弱気 — 新しい高値が価格チャートに形成され、指標の高値は同じレベルです。

強気 — 価格は新しい安値を形成し、オシレータの安値は等しいです。


図4

このような価格行動は通常、いわゆる「誤った内訳」またはマーケットメーカーの積極的な行動の間、強い抵抗と支持レベルで観察され、指標の低迷に関連しています。シグナルを明確なエントリポイントとして扱うことはできませんが、無視することはできません。

他にも多くの意見の相違や矛盾があるため、この相違をより詳細に調べることにしました。用語や概念をグローバルに変更することはありません。これは、それらに精通している人々や関連資料の学習を続ける人々を誤解させないためです。

指標を分析しましょう。

MACD

MACD指標は、株価分析のためにジェラルド・アッペルによって作成されたもので、トレーダーの間でとても人気があります。この人気は、その有効性が長年にわたってテストされており、その結果、多くの関連資料が利用可能であるという事実によるものです。「Moving Average Convergence/Divergence」(移動平均収束/発散、移動平均コンバージェンス/ダイバージェンス)という名前は、この目的のために特別に設計されたかのようであることを示唆しています。指標には「線形MACD」と「MACDヒストグラム」の2つがあります。 

線形MACD:

ここで

Pは通常、期間の終値に等しい価格ですが、他のオプション(始値、高値、安値、終値、中央値、標準価格など)も使用できます。

デフォルトで使用されるMACD設定は以下の通りです。

どちらのバージョンもMetaTrader 5にありますが、MACDとOsMAという異なる名前がついています。ターミナルのMACDは線形MACDであり、MACDヒストグラムはOsMAと呼ばれていることにご注意ください。

  

図5

両タイプについて考えてみましょう。

MetaTrader 5のMACDはトレンド指標として提示されるため、古典的なダイバージェンスはトレンドエンドを正確に反映する必要があります。しかし、これはそれほど単純ではありません。これは、ルールを解釈する異なる指標だけでなく、パターンのさまざまなタイプにも起因します。第1部では、ゼロ交差が一般的なトレンド終了の明確な兆候であると述べました。これは完全には正しくありません。出口がわずかにゼロであると、反転のより強いシグナルが得られるという別の意見があります。


図6

この場合、0の交差は必須条件です。特に、この意見はアレキサンダー・エルダーによって共有されていて、最もグローバルな意見の相違ではありません。両方のルールを使用できますが、特定の市場状況の場合、各ルールの適用はフレームワーク内で検討する必要があります。

ただし、主な問題はパターンの定義で発生します。オシレータはローソク足の終値に基づいているのに、新しい高値と安値を検索するのはなぜでしょうか。

  

図7 

  

図8

  

図9

どちらの方法が正しいのでしょうか。価格と指標値とではどちらが重要なのでしょうか。指標のもう1つの欠点は、計算期間が26〜12であるため、わずかな価格の変動に不適切になることです。古典的なダイバージェンスの意味によると、1対のフラクタルが指標値で検出され、価格変動と比較される必要がありますが、フラクタルは小さな価格変動では形成されません。明確にするために、標準バージョンを改善しましょう。移動方向に応じて、バーに異なる色を付けます。これは難しくはありません。標準コードを変更しましょう。まず

#property indicator_buffers 4

で4を5に変更し、

#property indicator_buffers 5

にして、

#property indicator_type1   DRAW_HISTOGRAM

#property indicator_type1   DRAW_COLOR_HISTOGRAM

そして

#property indicator_color1  Silver

#property indicator_color1  Green,Red,Gold

に変更します。また、あと1つのバッファ

double                   Color_buff[];


が変数に追加されて、初期化ブロックが次のようになります。

   SetIndexBuffer(0,ExtMacdBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,Color_buff,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(2,ExtSignalBuffer,INDICATOR_DATA);
   SetIndexBuffer(3,ExtFastMaBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(4,ExtSlowMaBuffer,INDICATOR_CALCULATIONS);

ここで 

   SetIndexBuffer(1,Color_buff,INDICATOR_COLOR_INDEX);


はインデックス1を持たなければならないため、最後にば追加できません。追加すれば機能しなくなります。

さて、フラクタルを識別するためには少なくとも3つのローソク足が必要です。したがって、計算バーの数に関連するブロックを適切に修正します。

if(prev_calculated==0)
      limit=2;
   else limit=prev_calculated-1;

メインブロックには2、3行を追加します。

//--- calculate MACD
   for(i=limit;i<rates_total && !IsStopped();i++)
     {
      ExtMacdBuffer[i]=ExtFastMaBuffer[i]-ExtSlowMaBuffer[i];
      //--- calculate Color Macd
      if(ExtMacdBuffer[i]>ExtMacdBuffer[i-1])
         Color_buff[i]=0.0; // set color Green
      else
         Color_buff[i]=1.0; // set color Red
     }
//---


最後に、MACD極値を決定するブロックを追加します。再描画を避けるため、これは現在のバーが閉じた後に行われます。 これを行うには、計算が1バー分シフトされます。

for(i=limit;i<rates_total-1 && !IsStopped();i++)
     {
      if((ExtMacdBuffer[i-1]<0 && ExtMacdBuffer[i]>ExtMacdBuffer[i-1] && ExtMacdBuffer[i-1]<ExtMacdBuffer[i-2]) || 
         (ExtMacdBuffer[i-1]>0 && ExtMacdBuffer[i]<ExtMacdBuffer[i-1] && ExtMacdBuffer[i-1]>ExtMacdBuffer[i-2]))
         Color_buff[i-1]=2.0; // set color Gold
     }

このバリアントは、MACDがゼロを上回る場合、UPフラクタルのみを識別することを意味します。 MACDがゼロを下回る場合、DNのみが検出されます。これは間違っています。さらに、フラクタルタイプ(UPまたはDN)がメイン指標戦がゼロに対してどのように配置されるかに依存しないバリアントを使用します。

パターンの存在におけるいくつかの瞬間の自動化は不可能ではないため、視覚的な観察のみが肯定的な結果をもたらします。

  

図10

この欠点を補う試みがExpert / Signal / SignalMACDクラスで行われました。ドキュメントには次のものが含まれます。


 図11

繰り返しますが、「オシレータの最初に分析された谷が前のものよりも浅く、対応する価格の谷が前のものよりも深い」という説明は、「鶏が先か、卵が先か」という質問に戻ります。価格アクションと指標値のどちらが先なのでしょうか。価格シリーズに基づいて形成される指標値は、価格シリーズよりもどのように重要になるのでしょうか。さらに、説明は特定の情報を提供しません。計算に使用するバーの数は、3、5、履歴全体のどれでしょうか。この方法は非標準のものに起因する可能性がありますが、典型的バージョンでの実装には利点よりも欠点が多くあります。ただし、これは完全に拒否すべきではありません。特定のケースでは、この指標のみが適用されます。

自動化バリアントの1つとして検討できるのはMACD + OsMAの同時使用です。OsMA指標はMACDと同様に改善されました。


図12

お分かりのように、OsMAは同じMACDですが、シグナルとメインのMACD線の差のヒストグラムが表示されます。OsMAはMACDよりも感度が高くなりますが、常に十分とは限らず、指標がシグナルを見逃す可能性があります。ただし、場合によっては感度が高すぎるため、追加の確認が必要です。

  

図13

2つの指標を使用する場合、どちらを先行(つまり補助的なもの)と見なすか、つまり、どちらの指標のダイバージェンスを必須と見なすべきか(もう一方はオプションと見なす)を決定する必要があります。 

また、指標パラメータを選択する機能に関連する別の欠点があると思います。RSI計算期間がライン振幅にのみ影響する場合、MACD、OsMA、Stochasticでは外観が変わります。「指標は株式市場用に作成されてそのパラメータは時足用に選択されましたが、市場の状況は変化しており、この可能性は必要です。」と言えるかもしれません。しかし、私に言わせれば、この可能性は適応ではなく、フィッティングに関連しています。

もちろん、初期状態では特定の銘柄とチャート期間のパラメータのセットが必要になる場合がありますが、指標が後で非効率になった場合は、すべてを一緒に使用するのをやめた方が良いでしょう。しかし、これは純粋に私の個人的な意見です。「過剰適合」の可能性の欠如は、第1部でAC(Accelerator/Decelerator)指標を使用する理由の1つでした。これが唯一の可能な指標ではありません。すべての指標には、それぞれ固有の利点があります。ACについて前述したすべてのルールは、他のすべての指標に当てはまります。上記は古典的ダイバージェンスの文脈で分析しましたが、これはコンバージェンスと隠されたダイバージェンスのルールにも適用できます。ご覧のとおり、すべての古典的なアイデアが明確なわけではありません。よって、このツールは従来の形で高品質のシグナルとして使用できるでしょうか。

この質問に答える前に、上記のタスクを解決するために伝統的に使用されている他の指標を見てみましょう。

ストキャスティクス

ストキャスティクスは、価格のモメンタムを割合で測定するテクニカル指標です。「ストキャスティクという用語は、ある期間にわたる価格帯に対する現在の終値の相違を指します。」この指標は、2007年3月にジョージ・レーンによって作成されたものです。

2つの線が含まれます。

ここで

定義には「ダイバージェンス」という言葉が含まれます。アイデアがMACDでは明確だとしても、正規化されたオシレータでは理解が少し難しくなります。 「正規化されたオシレータ」という概念は、厳密なフレームワークで値を変更するものとして定義できます。この場合、フレームワークは0〜100です。この機能は特定の条件を設定します。値のスケールでは、買われ過ぎ領域(80%)、売られ過ぎ領域(20%)、主要な動きの3つの領域が強調表示されています。計算仕様は、指標線が長時間極端な領域を離れないが、入りもしないという条件を作成します。


図14

2つの異なる価格帯を使用できることで、どちらを使用するかというMACDの疑問が解決されるように思えるかもしれません。ここで別の問題が発生します。図14から、終値に基づいたストキャスティクは、高値/安値に基づくものよりも頻繁に極値「100-0」を取ることがわかります。 これは、指標の計算式と関連しています。また、多くの山と谷も観察されます。


図15 

これらのケースには明確なルールはありません。その結果、ポイント100-100と92、31-92、22の間の相違は自動化が困難です。計算の典型的なバージョンでは、2つの最も近いフラクタルが使用されます。ここでの場合、これらは最も近いフラクタルではありません。ただし、「すべてのルールには例外があります」。したがって、デメリットをアドバンテージに変えることができます。計算期間に従って設定を変更することにより、M15チャートの変更をM5チャートに反映できます。


図16

このオプションの利点は、グローバル(拡張)マーケットセグメントでの発散の検出を簡単に自動化でき、より高いTFローソク足の終わりを待つ必要性に関連する遅延なしで早期にエントリシグナルを受信できることです。これらのセグメントは、図16-17に赤い線で示されています。場合によっては、これは非常に重要です。


図17

上記の図から、MTFシグナルに基づいて入力した場合、取引は負けとなり、代替手段によって収入を得られたことが明確にわかります。MACDでも同様のアプローチが有効です。


図18

シグナルの数が明らかに減少することとは別に、このソリューションでは収益性の高い取引の確率を大幅に高めることができるため、全体的な収益性が向上します。М5-М15の例を見てきましたが、M5-H1を使用したらどうなるのでしょうか。


図19

高速および低速ストキャスティクスの使用によって、問題の一部のみが解決されます。このような原則に基づいてEAを作成する場合、高速および低速のMACD(MACD + OsMA)を使用する場合と同じ問題があります。優先順位を付ける方法は何でしょうか。これは、発散指標を作成するときに、多数のストキャスティクスの線の切れ目をどのようにフィルタリングするかという一番の問題を解決しません。すべての線の切れ目を確認する余裕はありません。もしすればノイズが多くなりすぎるため、これを2つ、まれに3つのシーケンスに制限する必要があります。

シグナルフィルタリングの問題については後で説明します。ここで、相違を検索するときに遵守すべきルールに焦点を当てましょう。明確なNOを設定しない理由については、後で説明します。

1)論理的には、ダイバージェンス(コンバージェンス)を得る前に、価格が重要な値に到達する必要があることはわかっています。したがって、指標線もクリティカルレベルに達する必要があります。この場合、指標は買われ過ぎ/売られ過ぎゾーンに入る必要があります。この場合、市場で新しい高値/安値に到達することはオプションの条件です。この場合、古典的なダイバージェンスを検索するとき、現在のバーから左に2番目のポイントはこのゾーンにある必要があります。反対に、隠れた(逆)ダイバージェンスの場合、最初のポイントはクリティカルレベルにある必要があります。


図20

2)シグナルを検索する場合(手動またはアルゴリズムを使用)、図20の場合を除くシーケンスを使用して、最も近い極値で検索します。このようなシーケンスの最大数は3です。

図21

図15が左のピックが買われ過ぎゾーンにあるルール1に対応しているように見えますが、指標の点が3つ以上存在するとシグナルがキャンセルされます。

 

RSI 

RSIは、ここでの研究で使用できるあと1つの指標です。お気づきかもしれませんが、タスクはステップごとに難しくなります。

RSI (Relative Strength Index、相対強度指数)は、1978年6月にJ.ウェルズ・ワイルダーによって導入された指標です。

RSI=100-100/(1+U/D)

ここで 

上記の式を使用しますが、これは以下に示す元の式とは異なります。

また、0〜100の範囲で正規化されます。ただし、ストキャスティクスとは異なって線の平滑化オプションは含まれていないため、分析が複雑になります。 感度が高すぎると、線の切れ目が多く発生します。次の図からわかるように、指標は、連続した一方向の価格変動でのみ直接線形の動きを維持しますが、それ以外の場合、のこぎりのような線です。

  

図22

その結果、この場合、指標値をフィルタリングする必要性がさらに重要になります。次に、問題解決オプションの1つを見てみましょう。

価格シリーズと指標値のどちらがメインであるかという質問についてはすでに述べました。この場合、答えを見つけなければなりません。価格行動の分析に役立つツールは多くはありません。これらには、さまざまな種類のMA、フラクタル、およびジグザグが含まれます。

フラクタル(ビル・ウィリアムズ作)

標準バリアントには、5つのフラクタルバリアントが組み込まれています。ただし、このフラクタルはフィルタリングの問題を解決しません。それどころか、メイン指標とのシグナルの不一致により、ノイズが追加される場合があります。


図23

RSIと同様に、平坦な領域に多くの信号が生成されるため、フィルタリングする必要があります。別の欠点は、5本のバーの構造の形成の遅れです。遅延は少なくとも1つのローソク足に等しく、これは全く望ましくありません。

MAは平滑化に優れています。しかし、多くのバリエーションがあります。MAは、1) 平滑化オプション - SMA(単純平均)、EMA(指数平均)、SMMA(平滑平均)、LWMA(線形加重平均)、2) 使用価格 - 終値、始値、高値、安値、中央値((高+安)/ 2)、標準((高+安+終)/ 3)、加重((高+安+終+終)/ 4 )、3) 計算期間 - 1から∞までで異なります。これは、古典的なMA(移動平均)に関するものです。さらに、二重指数移動平均があります。標準のMetaTrader 5パッケージの外部にはさらに多くのタイプが存在します。ここでは「最適なバージョンを見つけるために、すべてのダイバージェンス検索アルゴリズムのすべての可能なオプションを分析する」というタスクは設定していません。 

ジグザグは、「 フィルタ変動に応じて振幅と期間が設定された、価格変動の極端な価格を判断するための指標 」です。

定義に基づいて、これが必要です。ここでも同じ問題が発生します。RSIは終値に基づいていますが、ジグザグは高値/安値を使用します。


図24

この欠点は、中央値((高+安)/ 2)に基づいてRSIを作成することで部分的に克服できます。


図25

図24からわかるように、指標フラクタルと価格フラクタルの位置の偏差は2バーを超えないため、ソフトウェア手段で簡単に補正できます。このケースでは、シグナルの形式のみに関心があり、その値には関心がないことに注意してください。つまり、基本的な指標はダイバージェンスを検出するためだけに使用され、個々の取引シグナルには使用されません。

したがって、ダイバージェンス固有の用途の設定で「再生」できます。RSI計算期間はシグナル形式に影響せず、振幅にのみ影響すること、ジグザグの設定は極値の位置を変更しないことを知っていると、驚くべき結果を達成できます。

ストキャスティクスに適用されるルールによると、「ダイバージェンスパターンの形成前に、指標値は買われ過ぎ/売られ過ぎの重要な値に到達する必要があります」。ここでの場合、これらは30未満および70を超える領域です。ここで、ZZパラメータを変更することにより、短期シグナルとそのグローバル値の両方を取得できます。これらのパラメータは相互に補正できるため、2+1(2つのフィルタ+ 1つの基本)の組み合わせにより、全体像を追跡できます。フィルタの数は2つに限定されず、3つ以上にすることもできます。さらに、目標レベルを考慮すると、シグナルをグループに分けることで、特定のシグナルを取引することで市場の動きのほとんどをキャッチできることがわかります。


図26

図26では、最初のシグナルのRSIは売られすぎ量きいに入りませんでした。計算期間を変更するだけで振幅を増やすことができます。この場合、RSIは適切な領域に表示されます。

CCI

コモディティチャネルインデックスはオシレータタイプに属し、1980年にドナルドランバートによって開発されました。  

CCIn=(1/0.015)*((TypicalPrice-SMA)/MedianDeviation)

この指標の利点の1つは、そのモメンタムの特性です。したがって、買われ過ぎ/売られ過ぎの市場状態だけでなく、最初の市場のモメンタムを判断することもできます。私たちの場合、この利点は欠点と見なすことができます。その古典的なバージョンは標準価格を使用して計算されるという事実にもかかわらず、線の形状は鋸歯状でRSIに似ています。したがって、RSIアプリケーションの仕様はこのCCIにも適用されます。価格シリーズは、タイプ(高/安/終値など)だけでなく、価格の極値検出によってもフィルタリングする必要があります。


図27

この動作のため、ダイバージェンスを検索するときに線の複数の切れ目を使用する場合はアルゴリズムを変更する必要があります。


図28

同様の状況は他の指標ではめったに発生しませんが、CCIでは非常に頻繁に発生します。

特定の動作のため、指標は、最初の記事で説明した原則に基づいた操作に最適なツールの1つと見なされます。その原則は次のとおりです。「最後の逆ダイバージェンス(最後の強気と弱気)から延長され、価格チャートに描かれた線は、価格支持/抵抗線(図29)またはオシレータウィンドウに描かれた古典的な指標では、指標線の支持/抵抗線として機能します(図30)。」


図29


図30

モメンタム 

モメンタムは変化の価格率を反映しています。この指標はRoC(変化率)とも呼ばれますが、それらの違いは、RoCのバランスラインが0である一方、モメンタムのバランスラインは100であるということです。この指標は、ジョン・マーフィーの著書「Technical Analysis of Futures Markets(先物市場のテクニカル分析)」で説明されています。

Momentum=Pn-Pn-1

ここでMomentumは、時間t(現在の期間)におけるn期間にわたるモメンタムです。

このバリアントは、資産価格からデータを提供するのであまり便利ではないため、式が補足されました。

標準のモメンタムは実際にはRoCですが、RoCは一般的なモメンタム-100です。指標計算の原理は、モメンタムの動きの評価にあるため、CCIとRSI同様、鋸歯状の線は問題となります。ここでは、この動きはさらに多くのシグナルを生成します。


図31

このような大量のシグナルをどう処理するかは明確ではありません。また、自動化されたバージョンは正しく動作しない可能性があります(図31を参照)。この指標に関する入手可能な情報によると、ダイバージェンスの識別に関連して使用されていません。計算期間によっては短期取引(期間6〜14)の要件を満たすことができて、20を超える期間ではトレンド指標として機能し、これを使用してトレンドエンドを明確に識別できるという意見があります。トレンドが3つの連続した運動量からなるという考えが正しいと仮定した場合(波動市場理論)、モメンタムの原理はトレンドの終わりを識別するのに本当に役立ちます。おそらく指標操作にはよりグローバルな分析が必要です。 

ADX

方向性運動指数(DMI)のアイデアは、1978年にウェルズ・ワイルダーが著書「New Concepts in Technical Trading Systems(テクニカル取引システムの新しい概念)」で提案しました。これが、この手段の開発の背後にある考え方でした。

ADXは、平均真の範囲(ATR)を考慮して、正の方向(+ DI)と負の方向(-DI)を持つ2つの他の指数に基づいて計算されます。

ADX=(MAn(+DI--DI)/(+DI+-DI))*100

ここで 

数式は簡略化された形式で表示されます。詳しい説明はこちらです。

指標には多くの線がありますが、メインのADX線はトレンドの方向を示していません。したがって、この指標はここでは適さないように思われるかもしれません。

  

図32

これは間違った仮定です。この指標はいくつかの方法で使用できます。1つ目は、価格の方向性と市場の活動との相違を定義することです。したがって、ADXが下落している間に価格が下落し続ける場合、これはダイバージェンスを示します。


図33

この方法はコレクションに追加できます。この方法の複雑さは、方向の特定に関係しています。解決策の1つは、価格系列の動きの初期評価を意味します。つまり 下降している谷または上昇している山のシーケンスを分析するということです。最も近い山が前の山を下回り最も近い谷が前の山を上回る場合、またはその逆の場合、いわゆる内部および外部バー(価格アクションに関連する用語)と呼ばれる場合、問題が発生する可能性があります。

  

図34

2番目の方法は、+DIおよび-DI線を使用することです。–DIの山は常に価格チャートの谷に対応することを忘れないでください。上昇トレンド(+DIが-DIを上回る)では、+DI線を使用して山を調べて古典的な弱気の発散を見つけるか、-DIの山を使用して隠れた強気のダイバージェンスを見つけます。下降トレンド(+DIが-DIを下回る)で、-DIの山を分析して強気の古典的なダイバージェンスを見つけ、+ DIの山を分析して弱気の隠れたダイバージェンスを見つけます。


図35

私の意見では最も効果的な3番目の方法は、上記の両方の方法を適用することです。このオプションは多くの問題を解決します。これにより、反転を待つことによる遅延なしで、ADX線でダイバージェンスを検出できます。シグナルは、追加の方法を使用せずに、一般的なトレンドに応じてタイプ別にフィルタリングする必要があります。

ここで、古典的なオシレータに関する部分を終えたいと思います。なぜAO、AC、TRIX、WPRおよびその他の同様の指標を考慮しなかったのでしょうか。

分析には元の計算式を持つ指標が選択されました。

WPR(10)は、ストキャスティクス(10.1.1(安/高))と同じですが、スケールが反転しています。ストキャスティクスは0〜100の範囲で機能する一方、WPRの範囲は100〜0です。


図36

Awesome Oscillator (AO)はMACD(5.35.1 Median)に似ています。唯一の違いは、AOはSMA(単純平均化)を使用して平滑化されるのに対して、MACDではEMA(指数平均化)を使用することです。下の図からわかるように、これはシグナル形式に大きな変化をもたらしません。


図37

AcceleratorはOsMA(5.34.5中央値)に似ていますが、MACDおよびAOに対してと同じ違いがあります。


図38

TRIXは移動平均に基づいており、MACDパラメータを選択することで同じ結果を得ることができます。

  

図39

 

ボリューム 

テクニカル分析を使用した戦略には様々な種類があります。別のグループには、ボリュームを使用する戦略が含まれますが、それは小さなグループです。私の意見では、外国為替市場のボリュームは、必要なほど使用されていません。外国為替市場には実際のボリュームはありませんが(ティックボリュームのみ)ボリュームに関しては個別の資料があります。次に、それらをダイバージェンスのコンテキストで考えてみましょう。

アルゴリズムでボリュームを使用する指標は非常に少なく、MetaTrader 5ターミナル標準パッケージで利用可能です。これらには、累積/分配(マーク・チャイキン)、マネーフローインデックス(式が類似しているためボリュームRSIと呼ばれる)、オンバランスボリューム(ジョセフ・グランビル)、マーケットファシリテーションインデックス(ビル・ウィリアムズ)およびボリュームが含まれます。アレキサンダー・エルダーのフォレックスインデックスもこのグループに属していますが、「オシレータ」セクションに含まれています。このタイプの方法は非常に少ないため、ボリュームの相違を分析するときに次のような画像に遭遇することがよくあります。

  

図40

上の図からわかるように、この方法は履歴データを使用して市場を分析する場合にはうまく機能しますが、自動化ツールの作成は困難です。この方法には多くの欠点があります。これには、異なるセッション中に取引されるボリュームの違いと関連する歪みが含まれます。アジアのセッションの量は、ヨーロッパおよびアメリカのセッションの量よりも少ないことがわかっています。スパイクは、トレンド開始時やトレーダーが取引を終了するときに発生します。後者の場合、ボリュームはさらに大きくなる可能性があります。

  

図41

ボリュームの急上昇はニュースリリースに伴う場合があります。

  

図42

このタスクは、ボリュームの代わりにバランスラインを持つ他の指標を使用することで部分的に解決できます。これは、一定期間にわたるボリュームのSMAである場合があります。これにより、マイナー値を除外できます。そのような指標の1つがBetterVolumeです。


図43

この問題を解決する別の方法は、価格帯とボリューム指標を組み合わせることです。新しい高(低)を形成するローソク足のボリュームを定義し、ボリュームを比較しましょう。アルゴリズムに従って古典的なバリアントを編集しましょう。

ヒストグラムは2色ではなく5色になります。

#property indicator_type1   DRAW_COLOR_HISTOGRAM
#property indicator_color1  Green,Red,Blue,Magenta,Gray


  1. Green - low[i]>low[i-1]およびhigh[i]>high[i-1]
  2. Red     - low[i]<low[i-1]およびhigh[i]<high[i-1]
  3. Blue   - 上向きの外部バー
  4. Magenta - 下向きの外部バー
  5. Gray - 上記以外 

メインの計算ブロックは、標準のボリューム指標と変わりません。さらに、CalculateVolume関数には、ヒストグラムバーの色付けが含まれています。

void CalculateVolume(const int nPosition,
                     const int nRatesCount,
                     const long &SrcBuffer[],
                     const double &h[],
                     const double &l[],
                     const double &o[],
                     const double &c[])
  {
   ExtVolumesBuffer[0]=(double)SrcBuffer[0];
   ExtColorsBuffer[0]=0.0;
//---
   for(int i=nPosition;i<nRatesCount && !IsStopped();i++)
     {
      //--- calculate indicator color
      ExtVolumesBuffer[i]=(double)SrcBuffer[i];
      ExtColorsBuffer[i]=4.0;
      //--- uptrend, UP bar ----
      if(h[i]>h[i-1] && l[i]>l[i-1]&& o[i]<c[i])ExtColorsBuffer[i]=0.0;
      //--- uptrend, DN bar ----
      if(h[i]>h[i-1] && l[i]>l[i-1]&& o[i]>c[i])ExtColorsBuffer[i]=3.0;
      //--- downtrend, DN bar ----
      if(h[i]<h[i-1] && l[i]<l[i-1]&& o[i]>c[i])ExtColorsBuffer[i]=1.0;
      //--- downtrend, UP bar ----
      if(h[i]<h[i-1] && l[i]<l[i-1]&& o[i]<c[i])ExtColorsBuffer[i]=2.0;
      //--- outside UP bar ----
      if(h[i]>h[i-1] && l[i]<l[i-1] && o[i]<c[i])ExtColorsBuffer[i]=2.0;
      //--- outside DN bar ----
      if(h[i]>h[i-1] && l[i]<l[i-1] && o[i]>c[i])ExtColorsBuffer[i]=3.0;
      //--- inside bar ----
      if(h[i]<h[i-1] && l[i]>l[i-1])ExtColorsBuffer[i]=4.0;
     }
//---
  }
//+------------------------------------------------------------------+


図44 

このバリアントでは分析が簡素化されますが、完全ではありません。計算原理のグローバルな変更まで、さらにいくつかのオプションは提供できますが、時には古い方法が最良の方法であることを忘れないでください。以前のアイデアは、普及していない限りは検討しません。そして、この指標を使用してダイバージェンスの検出を自動化するのに役立つものはないと思ってください。代わりに、人気のあるアイデアに注目しましょう。

マネーフローインデックス 

前述したように、計算式はRSIに似ています。

価格=(高値+安値l+終値)/3

MF=価格*ボリューム

MR=正のMF/負のMF

MFI=100-100/(1+MR)

私の意見では、売られ過ぎ/買われ過ぎの状態という概念は、計算期間中の価格変化の大きさを意味するのではなく、このプロセスに参加したプレーヤーの数を意味するため、買われすぎ/売られ過ぎ領域を識別するのに適しています 。これはまさにMFIが行うことです。その結果、因果関係がよりよく反映されます。ただし、同じ欠点もあります。


図45

  オンバランスボリューム

(ジョゼフ・グランビル)

現在の終値が前の終値よりも高い場合:

OBVn=OBVn-1-Volumen

現在の終値が前の終値よりも低い場合:

OBVn=OBVn-1-Volumen

現在の終値と前の終値が同じ場合:

OBVn=OBVn-1

ここで、

参照では、この指標に関する情報はほとんど提供されませんが、OBVの変更は価格の変更に先行するという重要なアイデアは提供されているので、価格の動きとボリュームのダイバージェンスを利用できます。


図46

上図のダイバージェンスの1つに疑問符が付いています。市場の動きは重要ではなく、主な要因は新しい日への移行ですが、アジア市場では大きなボラティリティは予想されません。後に、目標レベルはこのボラティリティが効果的であることを示します。

勢力指数(Force Index)

(アレキサンダー・エルダー)

Force Index=Volume*(CLOSEn-CLOSEn-1)

元の式は、ターミナルに実装されているものとは異なります。

Force Index=Volume*(MAn-MAn-1)

根本的な理由は明確ではありませんが、シグナルの形状に大きな変化はないため、ここでの目的に非常に適切です。


図47 

この指標によって生成される他のシグナルの側面とその違いは、本稿の範囲外です。

既に述べたように、この指標はオシレータのクラスに割り当てられています。しかし、アレクサンダー・エルダーは本で「市場でボリュームを測定するのに最適な方法だと思います」と書いており、 

さらに、このツールを使用してダイバージェンスを検索しています。


図48

エントリとターゲット

古典的なエントリルールは次のとおりです。

不一致が特定されたら、ローソク足の高値で買いストップ注文を出します。これは、強気ダイバージェンスのパターン形成の最後の注文となります。弱気ダイバージェンスの最後のローソク足の安値で売りストップ注文を設定します。


図49

このオプションは、最大限の利益を得るという点で最適と考えることができます。この方法では、「エンベロープ(26)」の上部境界で取引を始められます(偏差は市場のボラティリティに従って選択されます)。


図50

必要に応じて、ダイバージェンス形成ポイントに基づいて構築された等距離チャネルの境界でエントリします。3番目のポイントは、1番目と2番目のポイントの間の高(低)です。


図51

ストップロスは買いの安値より下または売りの高値より上に設定されます。ただし、この「理想的な」アプローチは、すべてのルールと追加の確認要件を満たす理想的なパターンにのみ適しています。それはまた、長い時間枠にも適しており、そこでは市場の状態をさらに分析し、適切なタイミングでエグジットできます。


図52

この変動するテイクプロフィットは、取引開始前に判断するのが困難です。レベルは時間とともに変化します。欠点の1つは、取引の可能な結果を計算するのが非常に困難であることです。そのような場合、より信頼性の高いバリアントを使用できます。トレンドラインを作成しましょう。取引はトレンドラインブレイクアウトの後に入力されます。これは、トレンド変更シグナルと追加の確認として機能します。ほとんどの場合、従来のバリアントレベルとほぼ同じですが、より信頼性が高くなります。


図53

適切な線の描画で最初の部分のルールを使用できます。指標によって作成された線は調整が必要な場合があります。

このような取引では、ターゲットは支持/抵抗レベルに設定されます。


図54

二重および三重の発散に関しては、最初のシグナル形成の終わりにターゲットを設定できます(多くの場合)。よりまれに、最初のダイバージェンス形成ポイント間またはその懇願でフラクタルを使用することが可能です。


図55

ストップレベルを設定することは常に必要でしょうか。もちろん、誰もが独自の取引スタイルと資金管理ルールを選択します。ストップレベルがまったくない、または非常に離れて設定された取引は、経験豊富なトレーダーのみに推奨されます。そのようなトレーダーは、関連するテクニカル分析と指標に自信があり、手に負えなくなる前にその場で取引を修正したり負け取引を手動決済するなど、行動を調整できる必要があります。

取引ツールの作成

ここでの目的は、既存のルールを批判することではなく、利用可能な情報を再分析して適切な結論を出すことです。すべての取引ツールの作成者が目指すのは、特定の望ましい結果を達成することです。この指標は通常、特定の市場向けに作成されますが、根底にある考え方があまり明確でない場合があります。多くの場合、シグナル解釈の詳細を理解しているのは作成者のみです。

トレーダーは他の条件下でこの指標を適用しようとするため、一般的な考え方と潜在的な利益が失われる可能性があります。これが、トレーダーが安定して負け取引をするロボットに頻繁に会う理由です。取引の方向を変えたらどうなるでしょうか。これは安定した利益になるでしょうか。

ここでの目標は似ています: 仮定してみることです。このアプローチに関連する結果の一部は、最初の部分で公開されているので、別の側面で実装する必要があります。短所はあるものの、特定の条件下では依然として他のツールでは達成できない良い結果が得られるツールを使用してみましょう。これはADX指標です。その欠点はよく知られています。二重平滑化による遅れです。メインラインと他のラインの方向が市場の動きの方向と一致しないため、指標を解釈するときに問題が発生します。著者が示したかったのは強度で方向ではありません。


図56


図57

このため、DI-は逆さまになっている一方で、DI+は大丈夫なようです。ここで、線の山は価格の谷と一致しています。


図58

J.ウェルズ・ワイルダーが放物線システムの枠組み内でこのような指標を作成した理由はわかりません。株式市場向けに作成したのだと推測できますが、そこでは取引は外国為替市場とは異なります。株式は、配当を受け取るため、または資本化の目的で、より長い期間保持されることがよくあります。

この特定の機能を使用してみましょう。最良の面を使用し、可能な限り効率的に使用する必要があります。その最大の利点は、正と負の成分を分離することにより、市場動向(市場の強さ)に応じて山と谷を検出できることです。このソリューションにより、下落する市場の売り手に対する買い手の圧力や成長する市場の売り手の圧力、参加者の減少によって全体的な活動が減少しているのかそれともトレーダーが何が起こっているかを分析するために一時休止することにしたのかなど、市場で何が起こっているのかを理解することもできます。さらに先へ進みます。メインの指標線の放物線運動に基づいて、ゼロバランスラインを備えた使い慣れた形のオシレータに簡単に変換できます。これは、メイン値から絶対値(ADX)への削減を削除することで実行できます。

         dTmp=100.0*MathAbs((ExtPDIBuffer[i]-ExtNDIBuffer[i])/dTmp);

からMathAbs関数を削除します。

その結果、指標は次のようになります。


図59


図60

上の図からわかるように、ADX(ここではADX_Oscと呼びます)は市場の方向性を示すのに優れており、それに基づいてグローバル規模でダイバージェンスを検索できます。線は引き続き少し遅れていますが、この欠点は、市場の予備的な反転シグナルによって補うことができます。これらは「DI-」および「DI+」に基づいて決定されます。


図61

DI-(赤線)と価格の違いがこのように特定される理由をよりよく理解するには、ADXに関連する部分をもう一度お読みください。それは図から見ることができます:下降トレンドでの買い手の圧力が始まり、それはさらなる保合につながり、指標のメインラインによる確認があります。しかし、買い注文を出すには、より深刻な理由が必要です。図60から、市場は下降を続けていることがわかります。

意思決定に使用できるのは、DI-およびDI+の「単方向」の線です。価格が同時に上昇および下降しているように見えるのに、なぜ「単方向」なのでしょうか。これは起こり得ないことはわかっています。これが転換です。このような瞬間は、いわゆる「内部バー」が表示されるときに発生します。

確認しましょう。価格アクション:「内部バー(IB)は、前のローソク足の範囲内にあるローソク足のセットです。ローソク足は、前のローソク足よりも高く、最も低く、最も高くなります。長い時間枠では、セットアップはしばしば 三角形で、内部バーは不確実性と市場の保合を示します。これは通常、トレンド市場で見られ、親ローソク足の崩壊後のトレンドの継続を示します。多くの場合、市場のトップ/ボトム、主要な支持/抵抗レベル、サイドウェイチャネルで発生します。」

ここでのケースはこの定義にはあまり適していません。おそらく覚えておいでだと思いますが、ここでは強度は特定しますが方向は特定しません。したがって、定義は次のようになります。「現在のバーの強気の強さは前のバーの強さよりも小さく、弱気の強さは前の強さよりも大きいです。バーの形状は無関係です。」


図62

ここでも、バーは市場の停止または反転を示すという主要なアイデアを保持しています。その品質を評価するとき、ADX_Osc線で表される主なトレンド方向(強度)を考慮に入れましょう。トレンドが発生する場合、ADX線の値は上昇トレンドの場合は前の値よりも高く、下降トレンドの場合は低くなります。これは、保合(ストップ価格)を示します。トレンドが弱まる場合、メインラインは上昇トレンド中に減少してから上昇します(ダイバージェンス)。その後市場の反転が予想されます。指標の作成に必要なのはそれだけです。

もちろん、ADXはもっと多くのことができます。しかし、ここでの仕事は、すべての可能性を活用することではありません。

先に進む前に、ちょっとした余談があります。少し前に、私の記事を書く申し出が断られました。ブログを始めることを勧められたのですが、私はすでに記事の出版に先立ってかなりの労力を費やしていました。記事には、私にとって不可欠と思われる抜粋のみが含まれていました。記事にプログラムコードを含める必要があることは誰も説明してくれませんでした。しかし、私は落胆しました。その後、私はまた記事を書いて、研究結果を共有したいと思いましたが、もう一度失敗しました。アイデアを簡単に提示したところ、モデレーターが満足してくれませんでした。今回は、結果に何が先行したのかを一つ残らず書くことにしました。 もちろん、本稿は詳細を完全に提供するものではありません。この研究の最終段階に進む前に、得られた結果に価値があると思えないかもしれない理由を簡単に述べます。

前回の記事では、グラフィカルな構成に基づいた指標で生じる問題について簡単に触れました。このようなツールは、適応モードでは実行できないため、さらに分析するのは困難です。視覚的にしか分析できず、非常に時間がかかります。指標のシグナルは逃しにくいため、そのコードをエキスパートアドバイザーコードに追加する必要があります。また、その線の正しい描画には問題があり、誤った市場エントリシグナルをもたらします。この問題は解決できますが、本稿の範囲外です。

おそらくMQL言語の開発者にこの問題について知らせる必要があるでしょう。グラフィカルオブジェクトをマシンコードライブラリとして作成できないのはなぜなのでしょう。(プロットまたはデータとして)渡す必要があるデータであるバッファーを、メインチャートウィンドウとそのサブウィンドウに個別に所属させることができないのはなぜなのでしょうか。おそらく誰かがこのトピックに関連する記事を書くか、私が自分でやりたいかもしれません。上記に基づいて、予備的な結果を要約しましょう。私の意見では、非標準的なアプローチに最も適した指標を選択しました。これは、主なタスクに対処できます。分析に基づいて、実装に最適であり、画面に過負荷をかけない動作モーメントを決定しました。主なタスクは取引の自動化ではなく、取引に指標を適用する機会であるため、指標のすべてのグラフィカルな構築を回避するわけではありません。 

ここでは特定の完全な概念を作成しているわけではありません。これは、さらなる作業の「テストの場」です。誰もが特定の目的の機能を実装するための基礎としてこのツールを使用できます。このため、グローバルシグナルに従来のソリューションを使用しながら、短期トレンドのみに「非標準アプローチ」を実装します。  

ADXの主要なコードへの大幅な変更はありませんが、オシレータとして実装するためにいくつかの変更を行います。このため、ADXをHandle経由で単に呼び出すことはできません。 

#property indicator_separate_window
#property indicator_buffers 8
#property indicator_plots   3
#property indicator_type1   DRAW_LINE
#property indicator_color1  LightSeaGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
#property indicator_type2   DRAW_LINE
#property indicator_color2  Green
#property indicator_style2  STYLE_DOT
#property indicator_width2  1
#property indicator_type3   DRAW_LINE
#property indicator_color3  Red
#property indicator_style3  STYLE_DOT
#property indicator_width3  1
#property indicator_label1  "ADX"
#property indicator_label2  "+DI"
#property indicator_label3  "-DI"
//--- 入力パラメータ
input int InpPeriodADX=14; // Period
input int extremum=100; // Extremum (<1 Div= OFF)
input int Gep=4; // Point to Gep
input int Bars_Calculated=300;
//--- グローバル変数
input bool   allLine=false;// All Line
int    ExtADXPeriod;
double PDI,NDI,pDI,nDI;
string short_name="";
int    wid=-1;
//---- buffers
double    ExtADXBuffer[];
double    ExtPDIBuffer[];
double    ExtNDIBuffer[];
double    ExtPDBuffer[];
double    ExtNDBuffer[];
double    ExtTmpBuffer[];
double    ExtUpBuffer[];
double    ExtDnBuffer[];

入力のいくつかには説明が必要です。

input int extremum=100; // Extremum (<1 Div= OFF)


これは指標線の極値の数であり、ダイバージェンスを検出するために確認されます。最小数は「1」で、それ未満だと計算は実行されません。後に最適な数を決定した後でグローバルパラメータにすることをお勧めします。

input bool   allLine=false;// All Line

このパラメータを使用すると、指標操作中に検出されて「extremum」パラメータで定義されたすべてのダイバージェンスの線を画面に表示できます。指標分析を簡素化し、上記のパラメータの値を決定するために特に設定します。


図63


図64

input int Gep=4; // Point to Gep

これは審美的な目的で使用されます。このパラメータによって決定される値の広がりを持つポイントは、1行として配置されます。この値を1.5〜2つのスプレッドとして決定しました。インデントには影響しません。オフセットが必要な場合は、この値を追加で設定する必要があります。ポイントについては後で説明します。OnDeinit関数を減らすために、指標名に等しいプレフィックスを持つすべてのデータを削除するコマンドを使用します。MetaTrader 5ターミナルは、メイン画面から多数のオブジェクトを削除する際に遅くなる場合があるので、これを避けるために、画面の強制再描画を追加しましょう。

//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ObjectsDeleteAll(0,short_name);
   ChartRedraw(0);
  }
//+------------------------------------------------------------------+

ターミナルが長時間接続されていなかった場合、サブウィンドウのグラフィカルオブジェクトは、価格/時間座標ではなく、最後の位置のピクセルでのバインディングを保持することに気付きました。したがって、最初の計算のバーの数を決定するブロックで、それらを削除するコマンドを追加しましょう。これに対してはより良い解決策があるかもしれませんが、私はこの問題を次のように解決しました。

   if(prev_calculated>1) start=prev_calculated-1;
   else
     {
      OnDeinit(9);
      start=1;
      ExtPDIBuffer[0]=0.0;
      ExtNDIBuffer[0]=0.0;
      ExtADXBuffer[0]=0.0;
     }


DI+およびDI-線の単方向の動きを決定するブロックが指標のメイン計算関数に追加されました。

//+------------------------------------------------------------------+
//|           Fast divergence calculation                            |
//+------------------------------------------------------------------+
   int bar=start;
   if(prev_calculated<2) bar=start+2;
   if(Bars_Calculated>0)bar=fmax(rates_total-Bars_Calculated,start);
//---
   for(int i=bar;i<rates_total-1 && !IsStopped();i++)
     {
      ExtUpBuffer[i-1]=EMPTY_VALUE;
      ExtDnBuffer[i-1]=EMPTY_VALUE;
      //---
      color clrUp=clrLime;
      color clrDn=clrDarkViolet;
      //---
      if((ExtPDIBuffer[i-1]<ExtPDIBuffer[i-2] && ExtNDIBuffer[i-1]<ExtNDIBuffer[i-2]) || 
         (ExtPDIBuffer[i-1]>ExtPDIBuffer[i-2] && ExtNDIBuffer[i-1]>ExtNDIBuffer[i-2]))
        {
         if(ExtPDIBuffer[i-1]>ExtNDIBuffer[i-1])
           {
            if(ExtADXBuffer[i-1]>ExtADXBuffer[i-2])
               ExtUpBuffer[i-1]=high[i-1];
            else
              {
               ExtUpBuffer[i-1]=EMPTY_VALUE;
               ExtDnBuffer[i-1]=low[i-1];
               clrDn=clrGold;
              }

            //---
            if(MathAbs(ExtUpBuffer[i-1]-ExtUpBuffer[i-2])<Gep*_Point)
               ExtUpBuffer[i-1]=ExtUpBuffer[i-2];
            if(MathAbs(ExtDnBuffer[i-1]-ExtDnBuffer[i-2])<Gep*_Point)
               ExtDnBuffer[i-1]=ExtDnBuffer[i-2];
            //---
           }
         if(ExtPDIBuffer[i-1]<ExtNDIBuffer[i-1])
           {
            if(ExtADXBuffer[i-1]<ExtADXBuffer[i-2])
               ExtDnBuffer[i-1]=low[i-1];
            else
              {
               ExtDnBuffer[i-1]=EMPTY_VALUE;
               ExtUpBuffer[i-1]=high[i-1];
               clrUp=clrBlue;
              }

            //---
            if(MathAbs(ExtDnBuffer[i-1]-ExtDnBuffer[i-2])<Gep*_Point)
               ExtDnBuffer[i-1]=ExtDnBuffer[i-2];
            if(MathAbs(ExtUpBuffer[i-1]-ExtUpBuffer[i-2])<Gep*_Point)
               ExtUpBuffer[i-1]=ExtUpBuffer[i-2];
            //---
           }
        }
      //---
      if(ExtUpBuffer[i-1]==EMPTY_VALUE)
         ExtUpBuffer[i-1]=ExtUpBuffer[i-2];
      if(ExtDnBuffer[i-1]==EMPTY_VALUE)
         ExtDnBuffer[i-1]=ExtDnBuffer[i-2];
      //---
      if(ExtUpBuffer[i-1]!=EMPTY_VALUE)
        {
         ArrowCreate(short_name+(string)time[i]+(string)Lime,time[i],ExtUpBuffer[i-1],ANCHOR_BOTTOM,clrUp);
         if(ExtUpBuffer[i-1]!=ExtUpBuffer[i-2])
            ArrowCreate(short_name+(string)time[i-1]+(string)Lime,time[i-1],ExtUpBuffer[i-1],ANCHOR_BOTTOM,clrUp);
        }
      else
         ArrowCreate(short_name+(string)time[i]+(string)Lime,time[i],ExtUpBuffer[i-2],ANCHOR_BOTTOM,clrUp);
      //---
      if(ExtDnBuffer[i-1]!=EMPTY_VALUE)
        {
         ArrowCreate(short_name+(string)time[i]+(string)Red,time[i],ExtDnBuffer[i-1],ANCHOR_TOP,clrDn);
         if(ExtDnBuffer[i-1]!=ExtDnBuffer[i-2])
            ArrowCreate(short_name+(string)time[i-1]+(string)Red,time[i-1],ExtDnBuffer[i-1],ANCHOR_TOP,clrDn);
        }
      else
         ArrowCreate(short_name+(string)time[i]+(string)Red,time[i],ExtDnBuffer[i-2],ANCHOR_TOP,clrDn);
     }

また、グローバルダイバージェンス計算関数を起動するためのモジュールがここに追加されました。

//+-------------------- Finding a discrepancy ----------------------+
   bar=start;
   if(bar>rates_total-2)bar=rates_total-2;
   if(Bars_Calculated>0)bar=fmax(rates_total-Bars_Calculated,bar);
   for(int i=bar;i<rates_total-2 && !IsStopped() && extremum>0;i++)
     {
      UP(i,ExtADXBuffer,high,time);
      DN(i,ExtADXBuffer,low,time);
     }

第1部の指標はMQL4から書き直されました。このバージョンは元々MQL5で書かれていたため、ダイバージェンスの検索が変更されました。

以下は弱気ダイバージェンスの検索関数です。

//+----------- Detecting UP divergences ------------------------------+
void UP(int l,const double &buf[],const double &high[],const datetime &time[])
  {
   if(Extremum(buf[l+1],buf[l],buf[l-1])<0)
     {
      int i=l;
      for(int j=0;j<extremum;j++)
        {
         int counted=LastPeak(i,buf);
         if(counted!=-1)
           {
            if(buf[l]<buf[counted] && high[l]>high[counted])
              {
               double k=fabs(buf[l]-buf[counted])/(l-counted);
               int z=1;
               bool yes=true;
               for(i=l-1;i>counted;z++,i--)
                     if(buf[i]>buf[l]+k*z){yes=false;break;}
               if(yes)
                 {
                  DrawPriceTrendLine(time[l],time[counted],high[l],high[counted],Red,STYLE_SOLID);
                  DrawIndicatorTrendLine(time[l],time[counted],buf[l],buf[counted],Red,STYLE_SOLID);
                  break;
                 }
              }

            if(buf[l]>buf[counted] && high[l]<high[counted])
              {
               double k=fabs(buf[l]-buf[counted])/(l-counted);
               int z=1;
               bool yes=true;
               for(i=l-1;i>counted;z++,i--)
                     if(buf[i]>buf[l]-k*z){yes=false;break;}
               if(yes)
                 {
                  DrawPriceTrendLine(time[l],time[counted],high[l],high[counted],Red,STYLE_DOT);
                  DrawIndicatorTrendLine(time[l],time[counted],buf[l],buf[counted],Red,STYLE_DOT);
                  break;
                 }
              }
           }
         i=counted;
        }
      //---
     }
  }

以下は強気ダイバージェンスの検索関数です。

//+----------- Detecting DN divergences ------------------------------+
void DN(int l,const double &buf[],const double &low[],const datetime &time[])
  {
   if(Extremum(buf[l+1],buf[l],buf[l-1])>0)
     {
      int i=l;
      //---
      for(int j=0;j<extremum;j++)
        {
         int counted=LastTrough(i,buf);
         if(counted!=-1)
           {
            if(buf[l]>buf[counted] && low[l]<low[counted])
              {
               double k=fabs(buf[l]-buf[counted])/(l-counted);
               int z=1;
               bool yes=true;
               for(i=l-1;i>counted;z++,i--)
                     if(buf[i]<buf[l]-k*z){yes=false;break;}
               if(yes)
                 {
                  DrawPriceTrendLine(time[l],time[counted],low[l],low[counted],Green,STYLE_SOLID);
                  DrawIndicatorTrendLine(time[l],time[counted],buf[l],buf[counted],Green,STYLE_SOLID);
                  break;
                 }
              }
            if(buf[l]<buf[counted] && low[l]>low[counted])
              {
               double k=fabs(buf[l]-buf[counted])/(l-counted);
               int z=1;
               bool yes=true;
               for(i=l-1;i>counted;z++,i--)
                     if(buf[i]<buf[l]+k*z){yes=false;break;}
               if(yes)
                 {
                  DrawPriceTrendLine(time[l],time[counted],low[l],low[counted],Green,STYLE_DOT);
                  DrawIndicatorTrendLine(time[l],time[counted],buf[l],buf[counted],Green,STYLE_DOT);
                  break;
                 }
              }
           }
         i=counted;
        }
      //---
     }
  }

主な違いは、追加のフィルタです。図20と図28の場合、シグナルは30%未満の正のトレンドがあることがわかりました。これが、それが削除された理由です。フィルタコードは強調表示されています。極値検出関数も変更されました。指標線の位置の正と負の値によるフィルタリングは除外されています。ここでの場合、これは無用であり、有害でさえあります。 線は現在のバーと前のバーで等しい値を取ることができるため、メイン定義がゼロに等しくなる可能性を提供します。 

検索ルールは、必要に応じて後で簡単に変更できます。

//+-- Search for extrema --------------------------------------------+
int Extremum(double a,double b,double c)
  {
   if((a-b)*(b-c)<=0)
     {
      if(c>b) return(1); //DN extremum
      if(c<b) return(-1);//UP extremum
     }
   return(0);
  }

左肩の検索はほとんど変更されていません。

//+----- Search for the second UP extremum --------------------------+
int LastPeak(int l,const double &buf[])
  {
   for(int i=l-2; i>4; i--)
     {
      int ext=Extremum(buf[i+1],buf[i],buf[i-1]);
      if(ext < 0)return (i);
     }
   return (-1);
  }
//+----- Search for the second DN extremum --------------------------+
int LastTrough(int l,const double &buf[])
  {
   for(int i=l-2; i>4; i--)
     {
      int ext=Extremum(buf[i+1],buf[i],buf[i-1]);
      if(ext > 0)return (i);

     }
   return (-1);
  }

次の関数は、前述のポイントを構築します。ポイントは短期偏差を示します。

//+-------------------- Creates an arrow -----------------------------+ 
bool ArrowCreate(string                  name,
                 datetime                time,
                 double                  price,
                 ENUM_ARROW_ANCHOR       anchor,
                 color                   clr)
  {
//--- reset the error value 
   ResetLastError();
//--- create an arrow 
   if(!ObjectCreate(0,name,OBJ_ARROW,0,time,price))
     {
      Print(__FUNCTION__,
            ": failed to create an arrow! Error code = ",GetLastError());
      return(false);
     }
   ObjectSetInteger(0,name,OBJPROP_ARROWCODE,167);
//--- set the binding type 
   ObjectSetInteger(0,name,OBJPROP_ANCHOR,anchor);
   ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
   ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID);
   ObjectSetInteger(0,name,OBJPROP_WIDTH,1);
   ObjectSetInteger(0,name,OBJPROP_BACK,false);
   ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
   ObjectSetInteger(0,name,OBJPROP_SELECTED,false);
   ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
//--- successful implementation 
   return(true);
  }
//+------------------------------------------------------------------+ 


メイン描画ブロックも変更され、すべてのダイバージェンスまたは「extremum」パラメータで指定された間隔の最後のダイバージェンス線のみを表示できるようになりました。

以下はメインチャートウィンドウ用です。

//+------ Creating objects on the price chart -----------------------+
void DrawPriceTrendLine(datetime T_0,datetime T_1,double P_0,double P_1,color color_0,int style)
  {
   string name_0=short_name+"Line_Sn"+ColorToString(color_0);
   string name_1="";
   if(allLine)
      name_1=short_name+DoubleToString(T_0,0);
   else
      name_1=short_name+DoubleToString(T_1,0);
//--- 
   ObjectDelete(0,name_1);
   drawLineS(name_1,T_0,T_1,P_0,P_1,color_0,style,0,true,false,0);
//+-----------+
   if(style==STYLE_DOT)
     {
      ObjectDelete(0,name_0);
      drawLineS(name_0,T_1,T_0,P_1,P_0,clrAqua,0,3,true,true,0);
     }
  }

こちらは指標ウィンドウ用です。

//+------ Creating objects in the indicator window ------------------+
void DrawIndicatorTrendLine(datetime T_0,datetime T_1,double P_0,double P_1,color color_0,int style)
  {

   int window=wid;
   string name_0=short_name+"Line_Pn"+ColorToString(color_0);
   string name_1="";
   if(allLine)
      name_1=short_name+DoubleToString(T_0+wid,0);
   else
      name_1=short_name+DoubleToString(T_1+wid,0);
//---
   ObjectDelete(0,name_1);
   drawLineS(name_1,T_0,T_1,P_0,P_1,color_0,style,0,false,false,window);
//---
   if(style==STYLE_SOLID)
     {
      ObjectDelete(0,name_0);
      drawLineS(name_0,T_1,T_0,P_1,P_0,clrMagenta,style,2,true,true,window);
     }
  }

同じ理由で、削除コマンドがトレンドライン構築関数からメインブロックに移動されました。

//+------------------------------------------------------------------+
void drawLineS(string name,datetime T_0,datetime T_1,double P_0,double P_1,color clr,
               int style,int width,bool back,bool ray,int window)
  {
   ObjectCreate(0,name,OBJ_TREND,window,T_0,P_0,T_1,P_1,0,0);
   ObjectSetInteger(0,name,OBJPROP_RAY_RIGHT,ray);
   ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
   ObjectSetInteger(0,name,OBJPROP_STYLE,style);
   ObjectSetInteger(0,name,OBJPROP_WIDTH,width);
   ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
   ObjectSetInteger(0,name,OBJPROP_BACK,back);
  }

指標は次のようになります。


図65

通常のダイバージェンス線に加えて、保合領域をマークし、売買取引のエントリポイントとして機能する多くのポイントがあります。これらのシグナルは、検出されたルール(DI +およびDI-の単方向移動)によって特定されます。緑色のポイントは買いのエントリポイントを示し、紫色のポイントは売りエントリを示します。緑色のボタンの背景に青色の点が表示されたり、紫色の背景に黄色の点が表示されたりすることは、トレンドの不確実性と変化の可能性を示しています。取引開始後、ポイントはストップレベルを追跡するレベルとして機能します。ポイントに基づいて保留中の注文を使用してエントリすることは望ましくないことに注意してください。まず、ポイントは短期的な市場動向を特定し、誤ったトリガーを引き起こす可能性があります。ローソク足がこのレベルの上(下)に閉じると、取引シグナルが発生します。 Gap変数は描画に使用されます。アルゴリズムは次のとおりです。売りシグナルの出現後、シグナルが形成されるバーの安値の下にポイントが表示されます。買いシグナルの場合、ポイントは高値の上に描画されます。高安値からのインデントは、アンカーポイントを決定するANCHOR_BOTTOMおよびANCHOR_TOP関数によって実装されます。その後、「+/-Gap」の距離内にあるすべてのシグナルが最初のポイントに基づいて作成されます。

このバージョンはさらに変更できます。 たとえば、メインラインの遅れを減らすことができます。最も簡単な解決策は、2番目の平滑化期間を減らして変数に移動することです。また、古典的なシグナル検出に関する部分を削除し、MACDに関して前述したアルゴリズムを追加することもできます。エントリレベルのみがチャートに描かれるので、不必要な描画を削除します。

これらのアイデアを確認するには、小さなロボットを作成します。 古典的なバリアントやメインラインの方向には興味がありません。 これにより、ターミナルから標準のADXを使用できます。フィルタは、ブレイクアウトローソク足が大きすぎる場合にのみ適用されます。ストップを設定できる反対の条件付きチャネルの線がない場合は、ストップロス距離を導入します。また、EAでは、高安値からの距離を設定する必要があります。 以下は、2016年1月1日から2019年6月1日までの期間のH1およびH4時間枠での主要通貨ペア(EUR/USD、GBP/USD、 USD/JPY)のテスト結果です。

EURUSD Н1


EURUSD Н4


GBPUSD H1


GBPUSD H4


JPYUSD H1


JPYUSD H4


もちろん結果はよくはありませんが、これは目標ではありません。それより重要なのは、肯定的な傾向があることです。

終わりに

よく知られているアイデアへの新しいアプローチとは何でしょうか。それは時間の無駄でしょうか。それとも進歩でしょうか。あなたが成功したトレーダーで、すでに優れた戦略を使っているとします。より高い結果を達成するために戦略を修正する必要があるのか、今の戦略のままでいるかは、自分で決めるべきです。私の研究の結果に触発されて、自分の戦略を別の視点で見たり、まったく新しいテクニカル分析ツールを作成したりする人がいるかもしれません。

私は独学に長けており、公開資料には常に批判的です。人気著者による特定のアイデアには固執せず、著者が提供した戦略のニュアンスについての長い説明をさまざまなフォーラムで読んでいます。そして常に利益最大化の概念の枠組みの中で最も効率的なソリューションを見つけようとします。この資料が読者の助けとなり、戦略を改善するために新しいアプローチを使用することを奨励することを願っています。この資料には、ダイバージェンスの研究中に行われた作業のほんの一部しか含まれていません。私の研究中に発生した問題や質問のいくつかは、非標準的なソリューションを必要としました。1つの記事ですべてを説明することは困難なので、他の非標準ソリューションを説明する資料をさらに公開することになるかもしれません。

追記: 公開された資料の改善や取引ロボットの作成のリクエストはお控えください。それには、フリーランスサービスを使用してください。私にとってプログラミングは得意というより必要です。開発を始めたのは、言語の可能性を学び、自分のアイデアを確認するためだけです。

#      名称         種類                           説明                      
1 ADX_Osc.mq5 Indicators  Divergence analyzing indicator. 
2 TestADX.mql5 Experts  An Expert Advisor for testing the ideas.