English Русский 中文 Español Deutsch Português
古典的な隠れたダイバージェンスを解釈する新しいアプローチ

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

MetaTrader 5トレーディングシステム | 21 11月 2017, 07:33
6 784 0
Alexander Lasygin
Alexander Lasygin

イントロダクション

トレーダーは、しばしば古典的なテクニカル分析メソッドを使用します。 しかし、それぞれに多くの使い方があり、それぞれが有用です。 この記事では、ダイバージェンスを検索して解釈するための非標準のメソッドを提案します。 このアプローチに基づきトレード戦略を作成します。

ダイバージェンス/コンバージェンスの定義

相場の動きは相場参加者がトレードする意志と資金を持っている限り続きます。 そして、遅かれ早かれ、すべての相場参加者が相場にいる瞬間があります。 このような状況はかなり頻繁に相場で発生する可能性があります。 トレンドの方向に応じて、買われ過ぎまたは売られ過ぎの相場状態と呼ばれています。

買われ過ぎの状態は、金融、株式、先物相場で発生する可能性があります。 資産を買いしたい人はすでに買っていることを示しているので、それ以上価格を移動する人はいません。

売られ過ぎの状態は逆の状況です。 資産を売りしたい人はすでにを売りしていることを示していますので、価格を下に移動させる人はもういません。

買われ過ぎ/売られ過ぎの状態はどこからも表示されません。 価格が波のような動きを形成することが知られています。 トレーダーは、インジケーターやオシレーターのチャートと価格チャートを比較することにより、価格の変化を追跡します。 インジケーターの動作が価格の移動方向と異なる場合、弱気相場ではコンバージェンスが形成され、強気相場ではダイバージェンスが形成されます。

ダイバージェンスの種類

研究者によって相場のダイバージェンスまたはコンバージェンスの見方は異なります。 ダイバージェンス/コンバージェンスの中でも古典的かつ隠れたものを考察します。

古典的なダイバージェンス

古典的なダイバージェンスは、インジケーターチャート上で価格の高値/安値の更新を比較することによって識別することができます。 価格チャートが別の新しい高値または安値を形成し、インジケーターチャートが同じようにならなかた場合、ダイバージェンスの兆候です。 相場は買われ過ぎ (売られ過ぎ) であるので、現在のトレンドの方向の取引を開けることは勧められません。

この古典的なダイバージェンスは、広く種々のリソースに記載されています。 ダイバージェンス特性に応じて、3つのサブクラスに分けることができます。

  • クラス A他のクラスよりも頻繁に発生。 価格の高値/安値が更新され、インジケータが反転を開始したとき、ダイバージェンスの兆候であり、今後逆転の可能性があります。
  • クラス Bクラス A に似ていますが、価格は極値を破ることができず、ダブルトップ/ダブルボトム反転パターンを形成しますが、インジケーターはその極値には達しない。
  • クラス C。 価格が高値または安値を更新し、インジケーターがダブルトップパターン (ダブルボトム) を形成します。

ダイバージェンス (コンバージェンス) は、異なるクラスの組み合わせです。したがって、より強力な反転モデルを作成しながら、連続で数回繰り返すことができます。 各クラスは、各ケースで個別に分析する必要があります。 どちらが強いか弱いかを言うことはできません。 その理由を後で説明します。

隠れたダイバージェンス

この種のダイバージェンスは、サブクラスに分けることもできます。

  • オシレーターが高値になり、価格が高値を下げることは下降トレンドを示します。
  • オシレーターが安値になり、価格が安値を上げることは上昇トレンドを示します。


上記の図では、明らかに上向き相場を見ることができますが、MACD は、価格表で確認されていない新しい低を形成しています。 この不一致は、隠れた強気のダイバージェンスの存在で、上昇を示しています。

ダイバージェンス/コンバージェンスを見つけるためのインジケーターとオシレーター。 仕組み

どのようなインジケーターがダイバージェンスとコンバージェンスを示すことができるでしょうか。 テクニカルインジケーターは、需要と供給のレベルを決定するだけでなく、勢いを追跡できるようにする必要があります。 オシレーター、ストキャスティクス、RSI、CCI 、MACD によるトレンドインジケーターなど、以下のインジケーターを使用することができます。 MACD は、移動平均のダイバージェンスとコンバージェンスとして解釈することができます. このインジケーターは、価格とそのモメンタムの動きの不一致を効率的に追跡します。 多くのトレーダーは、MACD を使用して、そのコンバージェンス/ダイバージェンスベースの決定を行います。

しかし、ダイバージェンスを操作するための上記のツールのいずれかを推奨することは間違っています。 すべてのトレーダーは、特定のトレード戦略に適合するインジケーターを選択し、価格表をオーバーロードすることなく効率的にタスクにする必要があります。 したがって、一般的な推奨は次のとおりです。インジケーターのリストをチェックし、それをテストし、そのうちの1つを選択し、他のファクターに注意を払って、シグナルを交換してください。

また、ダイバージェンスはインジケーターなしで容易に決定することができます。 まずはダイバージェンス形成の基本を理解しておくべきです。

モメンタムはダイバージェンスの形成に重要な役割を果たします。 強いインパルスの後の運動振幅の減少はダイバージェンス形成のシグナルです。


上の図はこの例を示しています。 新しい安値が形成されるとき、新しい波のサイズは、以前のものより小さいです。 この場合、新たなダイバージェンスを期待することができます。

RSI インジケータと同じ相場の部分を示す以下の例では、上記の仮定を確認できます。


ダイバージェンスは判断できますが、このメソッドはインジケーターを使用しなくては完了しません。 コンバージェンス/ダイバージェンス線が表示されません。 したがって、このパターンを識別するために最もよく使用されるインジケーターについて考えてみましょう。

RSI オシレーター

RSI オシレーターは、ぞれの買われ過ぎゾーン >-100 および < + 100 でゾーニングしています。 ゾーンに出現するすべてのシグナルは強いと考えられ、ダイバージェンスのシグナルはさらに強くなると考えられています。

このメソッドの不利な点は、インジケーターが価格変動に非常に敏感であるという事実です。 これより、このインジケータを使用して天井とトラフを識別することが困難になります。 価格表を分析する必要があります。 これはシグナル検出の遅延につながります。

ストキャスティクスオシレーター

オシレーターには、次の標準パラメータが使用されます。

  • %K 期間: 5
  • %D 期間: 3
  • スローイング: 3

RSI と同様に、ストキャスティクスオシレーターは買われ過ぎと売られ過ぎのゾーンがあります。 ゾーン内でダイバージェンスまたはコンバージェンスが大幅にポジティブなトレードを増加させます。

ストキャスティクスの不利な点はダイバージェンスの余りに頻繁な出現、すなわち多くのダマシシグナルです。 すべてのシグナルは変更可能のアラートとして解釈されるため、相場参入ポイントを決定するための追加テクニカルを使用する必要があります。

MACD オシレーター

MACD はまた、ダイバージェンスを決定するのに役立つ興味深いオシレーターです。 このインジケーターは、標準パラメータで使用します。

  • Fast EMA: 12
  • Slow EMA: 26
  • MACD SMA: 9


MACD を使用してダイバージェンスを決定するためのルールには次のものがあります。オシレーターはゼロレベルをクロスさせてはならない。 以下のスクリーンショットは、この場合ダイバージェンスが明らかではないことを示します。収益性が高いトレードをする可能性は低いです。

以前のインジケーターとは異なり、これはシグナル生成が少ないです。 しかしトレンドインジケーターであり、従って相場の全体的な変更について知らせることができます。 それらの利点にもかかわらず、相場参入は、価格行動分析やローソク足パターンによって確認する必要があります。

ボリュームインジケーター

ボリュームはまた別の重要な特徴です。 最も強い逆転シグナルの1つは価格およびボリュームのダイバージェンス (またはコンバージェンス) です。 この考え方は、次のとおりです。

新しいボリュームが相場に流入する限り、上向きの動きは続く。 高いブレイクアウトで、ボリュームの減少が見れます。これは買い手が相場に参入するのを止めているということを表します。 価格が買われ過ぎであり、下に移動する可能性があると結論付けることができます。 以下の図に、説明した状況を示します。

この文脈では、OBVが最も興味深いインジケーターでしょう。 この隠れたダイバージェンスに基づいて、良い相場参入シグナルを探します。

OBV の古典的なダイバージェンスに関しては、転移だけを示します。


ダイバージェンス/コンバージェンスを決定するためのルール。 ダイバージェンスのトレードメソッド

トレーダーらは、しばしばコンバージェンス/ダイバージェンスし、このパターンに基づいてトレードを実行しようとします。

  • トレンドは必須です。ダイバージェンスは平坦では動作しません。
  • ダイバージェンスに加えて、価格アクションや日本のロウソク足を使用してエントリを確認する必要があります。
  • 100% のシグナルを期待しないでください。 エラーの可能性は常にあります。 したがって、トレードの操作を実行する場合は、一般的なトレードルールを遵守する必要があります。
  • ニュースインジケーターを使用して構築されたロウソク足に基づいてダイバージェンスを決定しないでください。 ニュースリリースではボラティリティが高いため、このようなロウソク足はしばしば偽のシグナルを生成します。
  • ダイバージェンスは明示的である必要があります。 だけでなく、他の相場の参加者にも、シグナルが表示されていることを確認する必要があります。 この場合に限って、正しい判断を下す可能性は高まるかもしれません。
  • 最も近い天井とトラフを分析します。 状況がより明確になります。 MACD などのトレンドインジケーターを使用する場合、ゼロラインの交点がシグナルを弱めたり、キャンセルしたりすることもあります。

新しいアプローチ

これまでダイバージェンスパターンと構築の共通のルールを考えてきました。 ここからトレードでダイバージェンスの非標準的な使用を見ていきます。 標準ルールを適用せず、さらに非典型的なインジケーターを使用します。

古典的なビルウィリアムズアクセラレータオシレーターに基づいて実験を行います。 この選択は偶然ではありません。 変化の前にインジケーターの方向が変化しますが、方向は価格変更の前に変わります。 AO は、明らかな利点を提供する早期確認シグナルです。 以前より頻繁にダイバージェンスシグナルを受信することができます。 通常、このソリューションは、ノイズの増加につながるが、場合によって、より多くの相場参入シグナルと以前のシグナルを減らします。

すでにダイバージェンスの構築の共通のルールを考えています。 このダイバージェンス使用のバリアントは非標準です。 一般的なルールは、エントリポイントを決定する異例のメソッドを使用しながら、観察します。

このツールの主な目的は、ダイバージェンスを見つけることなので、その変数には1つだけのパラメータ-ダイバージェンスを決定するために使用される足の数が含まれます。

#property indicator_separate_window
//----インジケーターの計算と描画に1つのバッファが使用されます。
#property indicator_buffers 2
//----1 つだけのグラフィカルな構造は使用される
#propertyindicator_plots1
//----インジケーターは線として描画されます。
----インジケーターは線として描画されます。
//---- 青はインジケーターラインを表します。
#property indicator_color1 Green,Red
//----
#property indicator_width1 2
//----インジケーターラインは連続的なカーブです。
#property indicator_style1 STYLE_SOLID
//----インジケーターラベルの表示
#property indicator_label1 「AC_Div」
//+------------------------------------------------------------------+
input int Bars_Calculated=1000;
//+------------------------------------------------------------------+
string shortname="";
double AC_buff[];
double Color_buff[];
int wid;
int Handle_AC;
//---
#defineDATA_LIMIT 37

インジケーターは、マルチカラーヒストグラムのプリセットパラメータで初期化されます。

//+------------------------------------------------------------------+
//カスタムインジケーター初期化関数                                       |
//+------------------------------------------------------------------+
int()
 {
//----動的配列をインジケーターバッファとして設定する
 SetIndexBuffer(0,AC_buff,INDICATOR_DATA);
 SetIndexBuffer(1,Color_buff,INDICATOR_COLOR_INDEX);
//----インジケーターの描画を開始するポジションを設定します。
 PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,DATA_LIMIT);
//----インジケーターの短い名前の変数の初期化
 shortname="Accelerator_Divergence";
//----別のサブとツールチップに表示する名前を作成する
 IndicatorSetString(INDICATOR_SHORTNAME,shortname);
//----インジケーターの値を表示する精度を定義する
 IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//----空のインジケーター値の描画を無効にする
 PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
 PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);
//---アクセルインジケーターのハンドルを形成する
 Handle_AC=iAC(NULL,0);
//---チャートサブのインデックスを見つける
 wid=ChartWindowFind(0,shortname);
//---
 return(INIT_SUCCEEDED);
 }

メインインジケーターの計算コードは、2つの部分で構成されます。

最初の部分は、基本的なインジケータです。

//----ローカル変数の宣言 
 int limit,bar,pos;
//----足の数が計算に十分であるかどうか確認
 if(rates_total<DATA_LIMIT)
 return(0);
 int barsCalculated=MathMin(Bars_Calculated,rates_total);
//+-------配列のインデックスの方向を設定する-------------------------------
 ArraySetAsSeries(close,true);
 ArraySetAsSeries(AC_buff,true);
 ArraySetAsSeries(low,true);
 ArraySetAsSeries(high,true);
 ArraySetAsSeries(Color_buff,true);
 ArraySetAsSeries(time,true);
//+---計算に必要な足の数を決定する--------+
 limit=rates_total-DATA_LIMIT-1;
 if(prev_calculated>0) limit=rates_total-prev_calculated;
 pos=limit;
 if(pos>barsCalculated)pos=limit;
 int to_copy;
 if(prev_calculated>rates_total || prev_calculated<0) to_copy=rates_total;
 else
 {
 to_copy=rates_total-prev_calculated;
 if(prev_calculated>0) to_copy++;
 }
//---
 if(IsStopped()) return(0); //ストップフラグのチェック
//+ の-----------------------------------------------------------・---
 if(CopyBuffer(Handle_AC,0,0,to_copy,AC_buff)<=0)
 {
 Print("getting Accelerator Handle is failed! Error",GetLastError());
 return(0);
 }
//±-----------------------------------------------------------------+
 for(bar=limit; bar>=0 && !IsStopped(); bar--)
 {
 Color_buff[bar]=0.0;
 if(AC_buff[bar]<AC_buff[bar+1])Color_buff[bar] =1.0;
 if(AC_buff[bar]>AC_buff[bar+1])Color_buff[bar] =0.0;
 }

2番目の部分に不一致の検索があります。

//ダイバージェンス--------------------------------------------------------------------
 int bars=barsCalculated;
 for(bar=pos; bar>=0 && !IsStopped(); bar--)
 {
 int l=bar+2;
 if(Extremum(AC_buff[l+1],AC_buff[l],AC_buff[l-1])<0)
 {
 int i=l;
 int counted=LastPeak(l,bars,AC_buff);
 if(counted!=-1)
 {
 if(AC_buff[i]<AC_buff[counted] && high[i]>high[counted])
 {
 DrawPriceTrendLine(time[i],time[counted],high[i],high[counted],Red,STYLE_SOLID);
 DrawIndicatorTrendLine(time[i],time[counted],AC_buff[i],AC_buff[counted],Red,STYLE_SOLID);
 }

 if(AC_buff[i]>AC_buff[counted] && high[i]<high[counted])
 {
 DrawPriceTrendLine(time[i],time[counted],high[i],high[counted],Red,STYLE_DOT);
 DrawIndicatorTrendLine(time[i],time[counted],AC_buff[i],AC_buff[counted],Red,STYLE_DOT);
 }
 }
 }
//+----------- Detecting DN divergences ------------------------------+
 if(Extremum(AC_buff[l+1],AC_buff[l],AC_buff[l-1])>0)
 {
 int i=l;
 int counted=LastTrough(l,bars,AC_buff);
 if(counted!=-1)
 {
 if(AC_buff[i]>AC_buff[counted] && low[i]<low[counted])
 {
 DrawPriceTrendLine(time[i],time[counted],low[i],low[counted],Green,STYLE_SOLID);
 DrawIndicatorTrendLine(time[i],time[counted],AC_buff[i],AC_buff[counted],Green,STYLE_SOLID);
 }
 if(AC_buff[i]<AC_buff[counted] && low[i]>low[counted])
 {
 DrawPriceTrendLine(time[i],time[counted],low[i],low[counted],Green,STYLE_DOT);
 DrawIndicatorTrendLine(time[i],time[counted],AC_buff[i],AC_buff[counted],Green,STYLE_DOT);
 }
 }
 }
 }

コードのボリュームを減らすために、グラフィカルな構造と高/低検索関数は別々に提供されています。

//+-----2 番目の極値を検索---------------------------+
int LastPeak(int l,int bar,double &buf[]) 
 {
 for(int i=l+5; i<bar-2; i++)
 if(Extremum(buf[i+1],buf[i],buf[i-1])<0)return (i);
 return (-1);
 }
//+-----2 番目の DN 極値の検索----------------------------+
int LastTrough(int l,int bar,double &buf[])
 {
 for(int i=l+5; i<bar-2; i++)
 if(Extremum(buf[i+1],buf[i],buf[i-1])> 0)return (i);
 return (-1);
 }
//+--極値を検索する------------------------------------------------------------
int Extremum(double a,double b,double c)
 {
 if((a-b)*(b-c)<0)
 {
 if(c>b && b<0) return(1); //DN 極値
 if(c<b && b>0) return(-1);//アップ極値
 }
 return(0);
 }
//+------価格チャートにオブジェクトを作成する-----------------------------+
void DrawPriceTrendLine(datetime T_0,
 datetimeT_1、
 double P_0,
 double P_1,
 color color_0,
 int style)
 {
 string name_2=shortname+DoubleToString(T_0,0);
 string name_0;
 name_0=shortname+"Line_Sn"+ColorToString(color_0);
//--- 
 if(ObjectFind(0,name_2)<0)
 drawLineS(name_2,T_0,T_1,P_0,P_1,color_0,style,0,true,false,0);
//+-----------+
 if(style==STYLE_DOT)
 drawLineS(name_0,T_1,T_0,P_1,P_0,clrAqua,0,3,true,true,0);
 }
//+-------インジケーターウィンドウでオブジェクトを作成する--------------------------------
ボイドDrawIndicatorTrendLine (datetime T_0、
 datetimeT_1、
 double P_0,
 double P_1,
 color color_0,
 int style)
 {
 string name_1,name_0;
 int window= wid;
 name_1 = shortname+DoubleToString(T_0+wid,0);
 if(ObjectFind(0,name_1)<0)
 drawLineS(name_1,T_0,T_1,P_0,P_1,color_0,style,0,false,false,window);
//---
 if(style==STYLE_SOLID)
 {
 name_0=shortname+"Line_Pn"+ColorToString(color_0);
 drawLineS(name_0,T_1,T_0,P_1,P_0,clrMagenta,style,2,true,true,window);
 }
 }
//+------------------------------------------------------------------+
void drawLineS(string name,
 datetime t0,
 datetime t1,
 double p0,
 double p1,
 color clr,
 int style,
 int width,
 bool back,
 bool ray,
 int window)
 {
 ObjectDelete(0,name);
 ObjectCreate(0,name,OBJ_TREND,window,t0,p0,t1,p1,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);
 }
//+------------------------------------------------------------------+


視覚解析の利便性のため、古典的なダイバージェンスの実線を使用し、隠れたダイバージェンスの点線を使います。 赤い色は弱気のダイバージェンスに使用され、緑は強気ダイバージェンスに使用されます。 太い線は、古典的なダイバージェンスインジケーターウィンドウで、価格チャートの最後の隠れた強気と弱気のダイバージェンスを示しています。 さらに、可視化ルールについて説明します。 インジケーターは次のようになります。

戦略の基本原則

価格チャートとインジケーターの分析は、価格チャートの逆ダイバージェンスの延長線とインジケーターチャート上の古典的なダイバージェンスのトレンドサポートとレジスタンスレベルになることを示しています。 ラインの確信したブレイクアウトは、さらに短期的および長期的な相場行動を特徴付けます。

非表示のダイバージェンスによって形成される、価格チャートにあるサポートラインのブレイクアウトの例:


次の例では、ヒストグラムの足はインジケーターウィンドウの古典的な分岐線を区切ります。

ブレイクアウト後、ラインが頻繁に変更されます。 すなわち、壊れたレジスタンスレベルは抵抗に変わる:

この特徴をベースにします。


トレーディング原則

保留中およびマーケットオーダーの両方をトレードすることができます。 期間とトレード時間は重要ではありません。 主なルールは、ラインのブレイクアウトです。 予約オーダーをするとき、ヒストグラムの足が形成されている上に(ローソク足の高値 (安値)のブレイク) に配置します。 ロウソク足は、ブレイクアウト方向にする必要があります。 言い換えれば、ラインが上向きにブレイクしている場合、閉じる必要があり、その逆もまた然りです。 

下の図は、隠れたダイバージェンスがブレイクしている上の価格チャートを示しています。その後ロングポジションを開くためのシグナルがあります。 インジケーターウィンドウでは、古典的なダイバージェンスがブレイクしているので、後でショートポジションを開くためのシグナルがあります。


次の図は別の状況を示しています: インジケーターウィンドウの古典的なダイバージェンス線がブレイクしたときに買いシグナルが形成されます。 このシグナルは後で確認されます。

下記はまた別の興味深い例です。 2つのシグナルが同時に1つのロウソク足に表示されます: 1 つの買いシグナルと1つの売りシグナルです。 この場合、オシレーターの値を確認します。 しかし、オシレーターを無視する場合でも、必要なオーダーだけがトリガされます。 さらに、別の売りシグナルがあります。 ボリュームを増加させるため、利益を増やすことができます。


古典的な売りシグナル:

下図は、売りシグナル (オシレーターによって後でキャンセルされる) と2つの買いシグナルを示しています。


ストップロスはローカルの極値の下に設定されます。 テイクプロフィットは、サポート/レジスタンスレベルで設定されます。 サポート/レジスタンスレベルは、カウンタートレンドトレード中にラインに設定することができます。 しかし、この場合、相場状況が劇的に変更しますので、注意してください。テイクプロフィットを調整する必要があります。

より低いタイムフレーム (M1-М15) では、価格は頻繁にシグナルを激化させます。 したがって、相場が十分にアクティブでない場合は、価格がロウソク足の高値または安値を破るまで、待機する必要があります。 もちろん、ダイバージェンスの古典的な解釈も有効です。 オシレーターは、他の戦略のように重要ではありませんが、主にグラフィカルな構造に使用されます。しかし、トレードでオシレーターの動作を考慮に入れることをお勧めします。 AO インジケーターは、さまざまな戦略で使用されます。 AO とこのアプローチの組み合わせは、このような戦略の有効性を大幅に向上させることができます。

戦略の実行可能性をテストするために、予約オーダーを使用してEAを作成しましょう。 主な問題点は、EAの内部ではインジケーターをコールできないことです。 この場合、インジケーターはインジケーターウィンドウに何も描画しません。 グラフィカルな構造を必要とするため、インジケーターコード部分を EA コードに挿入します。

input double InpLots =0.1;           //ロット
input int InpTakeProfit =150;        //テイクプロフィット(ピップ)
input int InpStopLoss =60;           //ストップロス (ピップ)
input int InpTrailingStop =25;       //トレーリングストップレベル (ピップ)
input int InpOffset =5;              //価格からの間隔 (ピップ)
input int InpDellOorder =30;         //オーダーの取り外しの間隔 (ピップ)
//---
int ExtTimeOut=10;                   //トレードオペレーション間の時間間隔 (秒単位)
int barsCalculated=1000;
datetime t=0;
datetime time[];


ロット、テイク、StopLoss、TrailingStop などの従来の変数に加えて、オフセットと DellOorder が追加されました。 最初の1つは、オーダーとブレイクアウトのローソク足の高低の間の距離 (pip) を設定します。 オーダーがまだトリガされておらず、価格が DellOorder (pip) の距離で反対方向に移動した場合は、オーダーを削除する必要があります。

このEAはオリジナルではないので、主なポイントについてのみ説明します。 トレードフィルタを使用しませんが、わずかに元のコードを変更します。

//+------------------------------------------------------------------+
//基本計算 |
//+------------------------------------------------------------------+
 for(int bar=1; bar>0 && !IsStopped() && t!=time[0]; bar--)
 {
 int l=bar+1;
 int p1=0,p2=0;
 //ダイバージェンス--------------------------------------------------------------------
 if(Extremum(m_buff_ind[l+1],m_buff_ind[l],m_buff_ind[l-1])<0)
 {
 int i=l;
 int counted=LastPeak(l,bars,m_buff_ind);
 if(counted!=-1)
 {
 if(m_buff_ind[i]<m_buff_ind[counted] && high[i]>high[counted] && !d1)
 { drawLine("Buy_1",time[i],time[counted],m_buff_ind[i],m_buff_ind[counted],Red,1); d1=true;}
 //---
 if(m_buff_ind[i]>m_buff_ind[counted] && high[i]<high[counted] && !d2)
 {
 p1=ArrayMaximum(high,i-1,5);p2=ArrayMaximum(high,counted-2,5);
 drawLine("Buy_2",time[p1],time[p2],high[p1],high[p2],Red,0);d2=true;
 }
 }
 }
 //+----------- Detecting DN divergences ------------------------------+
 if(Extremum(m_buff_ind[l+1],m_buff_ind[l],m_buff_ind[l-1])>0)
 {
 int i=l;
 int counted=LastTrough(l,bars,m_buff_ind);
 if(counted!=-1)
 {
 if(m_buff_ind[i]>m_buff_ind[counted] && low[i]<low[counted] && !d3)
 { drawLine("Sell_1",time[i],time[counted],m_buff_ind[i],m_buff_ind[counted],Green,1);d3=true;}
 //---
 if(m_buff_ind[i]<m_buff_ind[counted] && low[i]>low[counted] && !d4)
 {
 p1=ArrayMinimum(low,i-1,5);p2=ArrayMinimum(low,counted-2,5);
 drawLine("Sell_2",time[p1],time[p2],low[p1],low[p2],Green,0);d4=true;
 }
 }
 }
 if(d1 && d2 && d3 && d4)break;
 t=time[0];
 }
//---
 }

インジケーターの極値は必ずしも価格チャート上の極値ではないことを理解しています。 したがって、チャート上で関連する歪みを修正するために、2つの関数 ArrayMinimum と ArrayMaximum (強調表示) を追加しました。 この関数は、インジケーター極値が形成されている価格チャートの一部で高低を識別することができます。 また、ゼロラインと関連するダマシシグナルの周りの、インジケーターの軽微な変動を排除するために、高値/安値を決定する式を変更しました。 インジケーターの値は、共通の可能性 (正または負) を考慮します。

//+--極値を検索する------------------------------------------------------------
int Extremum(double a,double b,double c)
 {
 if(((a-b)*(b-c)<0) && ((a>0 && b>0 && c>0) || (a<0 && b<0 && c<0)))
 {
 if(c>b && b<0) return(1); //DN 極値
 if(c<b && b>0) return(-1);//アップ極値
 }
 return(0);
 }
//+------

また、ObjectGetValueByTime 関数を使用して、特定の時間座標での線の値を決定します。 この関数は何度も使用されます。 便宜上、別途追加されます。

//+------------------------------------------------------------------+
//指定したオブジェクトの指定した時間の価格値を返します。                    |
//+------------------------------------------------------------------+
double CSampleExpert::ValueByTime(string label,int i)
 {
 double p=0.0;
//---
 p=ObjectGetValueByTime(0,label,time[i],0);
 return(p);
 }
//+------------------------------------------------------------------+

既に述べたように、トレードフィルタを使用しません。 戦略の有効性を評価したいが、重装備のトレーディングロボットを作成することを目指していません。 したがって、シグナルのモジュールは非常に簡単です。 ラインが希望の方向にブレイクしているかどうかを決定します。

//+------------------------------------------------------------------+
//ショートポジションを開くための条件を確認する                             |
//+------------------------------------------------------------------+
boolCSampleExpert:: ShortOpened (void)
 {
 bool res=false;
//---
 double pp1=EMPTY_VALUE,pp2=EMPTY_VALUE,pp3=EMPTY_VALUE,
 pp4=EMPTY_VALUE,pp5=EMPTY_VALUE,pp6=EMPTY_VALUE;
//---
 if(ObjectFind(0,"Sell_2")!=-1)
 {
 pp1=ValueByTime("Sell_2",1);
 pp2=ValueByTime("Sell_2",2);
 pp3=ValueByTime("Sell_2",3);
 }
 if(ObjectFind(0,"Sell_1")!=-1)
 {
 pp4=ValueByTime("Sell_1",1);
 pp5=ValueByTime("Sell_1",2);
 pp6=ValueByTime("Sell_1",3);
 }
//---ショートポジションの可能性を確認する (売り) 
 if((pp1!=EMPTY_VALUE && close[1]<pp1 && close[2]>pp2&&close[0]<close[1])||
 (pp4!=EMPTY_VALUE && m_ind_1>m_ind_0 && ((m_ind_1<pp4 && m_ind_2>pp5) ||(m_ind_2<pp5 && m_ind_3>pp6))))
 {
 //---いずれにせよ、決済する必要があります
 res=true;
 }
//---結果
 return(res);
 }
//+------------------------------------------------------------------+


上記の部分は、ショートポジションをエントリーするためのブロックを示しています。 ロングエントリは似ています。

シグナルを受信した後 (ラインブレイクアウト), InpOffset の距離で適切なオーダーを設定します。 このローソク足がブレイクアウトのものであれば、このローソク足でオーダーがまっすぐに配置されます。 

//+------------------------------------------------------------------+
//| Opening a sellstop position                                      |
//+------------------------------------------------------------------+
boolCSampleExpert:: OpenSellStop (void)
 {
 bool res=false;
//---最も近いロウソク足の中で最も低い安値を見つける
 int i=ArrayMinimum(low,0,3);
//---
 if(ShortOpened())
 {
 double offset=InpOffset;                          //オーダー、ピップを置くためのローソク足からの距離
 double limit_price=m_symbol.Bid();
 double price=low[i]-offset*m_adjusted_point;;
 double tp =price-m_take_profit;
 double sl =price+m_stop_losse;
 //---口座残高を確認する
 if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_SELL_STOP,InpLots,price)<0.0)
 printf("We do not have money. Free margin = %f",m_account.FreeMargin());
 else
 {
 //---ポジションを開く
 if(m_trade.OrderOpen(Symbol(),ORDER_TYPE_SELL_STOP,InpLots,limit_price,price,sl,tp))
 {res=true; printf("Position by %s to be opened",Symbol());}
 else
 {
 printf("Error occurred while opening position SELL STOP %s : '%s'",Symbol(),m_trade.ResultComment());
 printf("Open parameters: price=%f,TP=%f",price,tp);
 }
 }
 }
//---結果
 return(res);
 }
//+------------------------------------------------------------------+

オーダーがトリガされず、価格が InpDellOorder より大きい距離で反対方向に移動した場合は、オーダーを削除する必要があります。

//+------------------------------------------------------------------+
//不要なオーダーの削除                                                  |
//+------------------------------------------------------------------+
bool CSampleExpert::DelOrder(ulong ticket,string type)
 {
 bool res=false;
 if(m_trade.OrderDelete(ticket))
 printf("Position by %s to be opened",Symbol());
 else
 {
 res=true;//オーダーが削除されていないことを示すフラグの設定
 printf("Error occurred while deleting the order"+type+" %s : '%s'",Symbol(),m_trade.ResultComment());
 }
 return(res);
 }
//+------------------------------------------------------------------+

主な目標、すなわち、戦略の評価を取り戻すことができます。 グラフィカル構造に取り組んでいる戦略の評価の難しさは、視覚モードでのみ評価することができるということです。 自動モードでの最適化はできません。 これは時間のかかるプロセスです。 したがって、2017の初めから始まる GBPUSD H1 のEAを実行してみましょう。 デフォルトの設定を使用してみましょう。

ここに結果があります:




このメソッドは、客観的に見ることはできません。 しかし、得られた結果は、戦略が良い可能性を持っていることを示しています。 長期的には、さらに改善した後、戦略を変えることができます。


結論

このアプローチでは、他のツールを使用することができ、完全に実現可能な戦略を作成することを可能にしました。 この戦略の短所は、インジケーターラインの不正確な構造を手動で修正する必要性があります。 これにより、戦略を自動化し分析することが困難になります。 それもかかわらず、この研究では、古典的な戦略以外にも有用な方法の存在を証明しました。

この記事で使用されるプログラム:

# Name Type  Description 
1 Accelerator_Div Indicator

アクセラレータインジケーターに基づく明示的および非表示のダイバージェンス/コンバージェンスを決定するインジケーター

2 TestExpert EA

ストラテジーテストのEA

MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/3686

添付されたファイル |
MQL5.zip (10.12 KB)
取引戦略におけるファジー論理 取引戦略におけるファジー論理
本稿では、ファジーライブラリを使用して、ファジー論理を適用した簡単な取引システムの構築例を検討します。ファジー論理、遺伝的アルゴリズムおよびニューラルネットワークを組み合わせることによりシステムを改良するための変形が提案されます。
バランスグラフを使用した戦略の最適化と、結果の「バランス+最大シャープレシオ」基準との比較 バランスグラフを使用した戦略の最適化と、結果の「バランス+最大シャープレシオ」基準との比較
本稿では、バランスグラフ分析に基づいたカスタム取引戦略最適化基準をさらにもう1つ考察します。線形回帰は、ALGLIBライブラリの関数を使用して計算されます。
ミニマーケットエミュレータまたは手動ストラテジーテスター ミニマーケットエミュレータまたは手動ストラテジーテスター
ミニマーケットエミュレータは、端末での作業の部分的なエミュレーション用に設計された指標で、市場分析と取引の「手動」戦略をテストするために使用することができるでしょう。
適応型相場の実用的評価法 適応型相場の実用的評価法
この記事で提案するトレーディングシステムは、株価を分析するための数学的ツールです。 ディジタルフィルタリングと離散時系列のスペクトル推定を適用します。 戦略の理論的側面について説明し、テストEAを作成します。