トレンドの長さは?

Alexander Fedosov | 26 5月, 2017


内容


はじめに

異なる期間における市場条件の特定は、為替取引の基本原則です。トレーダーの成功は、価格予測の正確さにかかっています。このトピックについてはすでに多数の記事が書かれており(例: MQL5でトレンドを見つけるいくつかの方法 )指標とエキスパートアドバイザーを使ってトレンド相場を特定する方法が説明されています。私が以前に書いた「 Comparative Analysis of 10 Trend Strategies(10のトレンド戦略の比較分析)(英文)」もまたトレンドに専念し、トレンドフォロー戦略が策定されテストされています。本稿では、トレンドを特定するためのいくつかの方法を選択し、フラットに対したトレンドの持続時間のを目指しています。一般的には、トレンドとフラットの比率は30〜70%と言われています。これを確認します。


タスクの定義

研究のためのタスクと条件を特定しましょう。

  1. 後の量的および質的分析のためにトレンド相場とフラット相場を特定する方法の選択。これには、両方の市況を示すシステムだけが必要です。理想的には、トレンドの力や横向きトレンドの明確な定義などの品質指標を組み込む必要があります。
  2. さまざまな期間および通貨、株式、または先物市場などの異なる単一商品市場または複数商品市場での比率の特定と評価。
  3. ユーザーによる固有の条件で独立した研究を可能にする有用なツールの開発。
  4. 異なる条件で得られたデータに基づいた比較分析と相関の検索。

実装

1. トレンド特定法の選択

1.1. 古典的なトレンド力指標であるADXを使って研究を始めましょう。トレンド領域やフラット領域を見積もるにはTrendLevelのレベルを使用します。トレンドは、メインラインがこのレベルを上回った場合に存在するとしましょう。図1は、この方法を用いてトレンド領域フラット領域を特定する例を示します。市況は、所与のサンプルでADX値がTrendLevelより高いローソク足の数について計算されます。

図1 ADXを使用したトレンド/フラット領域の特定

1.2. 次に、ボリンジャー指標を1つのみ選択して表示される色数を2(赤と緑)に減らしてトレンドパワーと方向インディケータを考えてみましょう。図2は、特定の色でローソク足がマークされており、強い市場トレンドをはっきりと示しています。

図2 ボリンジャーバンドを使用したトレンド/フラット領域の特定

1.3. 3番目に、Percentage of Trendを考慮します。これは、2番目の期間を削除し、トレンドのカラー表示を追加することによっても変更されています。図3にはこの指標を適用した結果が示されています。

 

図3 Percentage of Trendを使用したトレンド/フラット領域の特定

1.4. トレンド/フラット領域を特定するあと一つの方法はRSIFilterです。計算を簡単にするため、RSI指標はヒストグラムとして表示され、事前に設定された買われ過ぎ/売られ過ぎ領域に入る指標値を示す縦の列が表示されます。ここでは、元の指標も変更されています。フラットな状態は表示されず、この市場条件でのヒストグラムの高さ値のバッファはゼロになります。これは、トレンドをより簡単に特定するために行われます(この場合、バッファ値は1に等しい)。図4は指標の例を示します。

図4  RSIFilterを使用したトレンド/フラット領域の特定

1.5. 最後に、「MQL5でトレンドを見つけるいくつかの方法」稿からの、ZigZagTrendDetector指標を使用してトレンド/フラット状態を識別する方法を検討します。この場合は変更はありません。その実装は図5に示されています。

図5 ZigZagTrendDetectorを使用したトレンド/フラット領域の特定

2. 市場条件を計算するためのツールの開発と実装結果の表示

トレンド/フラット領域を特定する各方法の結果は、いくつかの時間枠を要約した表として表示されます。表現を分かりやすくするためにグラフィカルインタフェースの記事シリーズに基づいてEasyAndFastGUIライブラリを使用しました。結果を視覚化するためには、特別なCTrendCountUI クラスが開発されました。より良い表現のために、 図6は、すべての計算を記録するために使用された元のテンプレートを示します。

 

図6 テスト結果の計算を表示するテンプレート

スクリーンショットで見ることができるように、最初の列はトレンドを計算する方法を示し、最初の行は複数時間枠オプションの計算を示します。スペースを節約して読みやすさを保つために、ここでは上に示したテンプレートを設定して視覚化する関数だけを表示し、インターフェイスの完全な実装は除外します。

//+------------------------------------------------------------------+
//| 情報パネルの出力と設定                |
//+------------------------------------------------------------------+
void SetInfoPanel()
  {
//---

   UI.CreateMainPanel("Trend Counter");
   UI.CreateStatusBar(1,25);
   UI.m_status_bar.ValueToItem(0,"Enabled on "+Symbol());
   UI.CreateCanvasTable();
//---

   UI.m_canvas_table.SetValue(0,0,"Value");
   UI.m_canvas_table.SetValue(0,1,"ADX");
   UI.m_canvas_table.SetValue(0,2,"BB");
   UI.m_canvas_table.SetValue(0,3,"PoT");
   UI.m_canvas_table.SetValue(0,4,"RSI");
   UI.m_canvas_table.SetValue(0,5,"ZZ");
//---

   UI.m_canvas_table.SetValue(1,0,"M1");
   UI.m_canvas_table.SetValue(2,0,"M5");
   UI.m_canvas_table.SetValue(3,0,"M15");
   UI.m_canvas_table.SetValue(4,0,"M30");
   UI.m_canvas_table.SetValue(5,0,"H1");
   UI.m_canvas_table.SetValue(6,0,"H4");
   UI.m_canvas_table.SetValue(7,0,"H6");
   UI.m_canvas_table.SetValue(8,0,"D1");
   UI.m_canvas_table.SetValue(9,0,"W1");

   UI.m_canvas_table.UpdateTable(true);
   UI.CreateLabel("Working...");
  }

次のステップは、上記の計算法のアルゴリズムを作成することです。実装オプションのほとんどは類似しているため、それらのうちの1つだけを分析します。計算に没頭しましょう。

最初に記述した方法(ADX)のGetADXCount()関数から始めます。

//+------------------------------------------------------------------+
//| ADXを指標して市場条件を計算する関数         |
//+------------------------------------------------------------------+
bool GetADXCount()
  {
//--- ブロック1
   double adx[],result[],count;
   int to_copy,bars;
   int tf_size=ArraySize(Ind_Timeframe);
   ArrayResize(Ind_Handle,tf_size);
   ArrayResize(result,tf_size);
   ArrayInitialize(adx,0.0);
   ArrayInitialize(result,0.0);
   ArraySetAsSeries(adx,true);
//---

   for(int i=0;i<tf_size;i++)
     {
      count=0;
      Ind_Handle[i]=iADX(Symbol(),Ind_Timeframe[i],InpInd_ADXPeriod);
      if(Ind_Handle[i]==INVALID_HANDLE)
        {
         Print(" Failed to get the indicator handle");
         return(false);
        }
      //--- ブロック2

      bars=Bars(Symbol(),Ind_Timeframe[i]);
      to_copy=(bars<NumCandles)?bars:NumCandles;
      //---

      if(CopyBuffer(Ind_Handle[i],0,0,to_copy,adx)<=0)
         return(false);
      //--- ブロック3

      for(int j=0;j<to_copy;j++)
        {
         if(adx[j]>TrendLevel)
            count++;
        }
      result[i]=(count/to_copy)*100;
      IndicatorRelease(Ind_Handle[i]);
     }
//--- ブロック4

   for(int i=1;i<=tf_size;i++)
      UI.m_canvas_table.SetValue(i,1,DoubleToString(result[i-1],2));
   UI.m_canvas_table.UpdateTable(true);
   return(true);
  }

上記のコードブロックを考えてみましょう。

  • ブロック1:変数と配列の初期化とテストに使用される時間枠数への削減。
  • ブロック2:テストして百分率の結果を取得するための特定の数のローソク足のサンプル。長めの時間枠や履歴が少ない製品では、サンプルに十分なバーがないことがあるので、履歴の深さを特定し、必要に応じて、要求されるデータ量を調整する必要があります。
  • ブロック3:ADX指標の場合、現在のバーの値がTrendLevelを上回ったときにカウンタをインクリメントします。 
  • ブロック4:SetInfoPanel() 関数で以前に用意された表にテスト結果を追加します。

その後、ブロック3(カウントの条件)のみが変更されます。

GetColorBBCount()関数

for(int j=0;j<to_copy;j++)
        {
         if(bb[j])
            count++;
        }
result[i]=(count/to_copy)*100;

選択された指標バッファの非ゼロ値は、サンプル中の現在のローソク足がトレンドに属することを意味します。さもなければこれはフラット期間です。

GetPoTCount() 関数

Percentage of Trend'指標のパラメータは次のとおりです。

//--- Percentage of Trendパラメータ

input int                  InpPeriodPoT=20;
input double               UpTrendLevel=0.8;
input double               DnTrendLevel=0.2;

UpTrendLevelおよびDnTrendLevelレベルを超える指標値はトレンドの存在を示します。したがって、計算は次のようになります。

 for(int j=0;j<to_copy;j++)
        {
         if(pot[j]>=UpTrendLevel || pot[j]<=DnTrendLevel)
            count++;
        }
 result[i]=(count/to_copy)*100;

GetRSICount() 関数

関数はヒストグラムで表されるため、1はトレンドの存在を示し、0はその不在を示します。この条件はGetColorBBCount()と同じです。

 for(int j=0;j<to_copy;j++)
        {
         if(rsi[j])
            count++;
        }
 result[i]=(count/to_copy)*100;

GetZZCount() 関数

1つ前の関数と類似する、指標の同じヒストグラム形式。

 for(int j=0;j<to_copy;j++)
        {
         if(zz[j])
            count++;
        }
 result[i]=(count/to_copy)*100;

GetAverage()関数

すべてのメソッドと時間枠の全体的な結果を計算します。

//+------------------------------------------------------------------+
//| すべてのデータの平均値を計算する関数        |
//+------------------------------------------------------------------+
string GetAverage(double &arr[])
  {
   double sum=0.0;
   int size=ArraySize(arr);
   for(int i=0;i<size;i++)
      sum+=arr[i];
   sum/=size;
   return(DoubleToString(sum,2));
  }
//+------------------------------------------------------------------+

その結果、データの計算と出力は次のように簡潔に表現されます。

//+------------------------------------------------------------------+
//| エキスパート初期化関数                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   SetInfoPanel();
   if(GetADXCount() && 
      GetColorBBCount() && 
      GetPoTCount() && 
      GetRSICount() && 
      GetZZCount()
      )
      UI.m_label1.LabelText("Done. Result for "+IntegerToString(NumCandles)+" bars. Average Trend Time - "+GetAverage(avr_result)+"%");
   else
     {
      UI.m_label1.LabelText("Error");
     }
//---
   return(INIT_SUCCEEDED);
  }


テスト

研究条件の範囲を最大限にするために、テストではさまざまな手段を使用することが決められました。

  • 通貨ペア - EURUSD、USDCHF、USDJPY、GBPUSD
  • 先物(GOLD-6.17)
  • 株式市場(#MCD)

すべての時間枠で、2,000バーのサンプルでテストが行われます。テストパラメータはすべての銘柄で同じです。

//+------------------------------------------------------------------+
//| エキスパート入力パラメータ                                          |
//+------------------------------------------------------------------+

input int                  NumCandles=2000;              // 分析するローソク足の数
//---- ADXパラメータ
input string               com1="";                      //---- ADXパラメータ
input int                  InpInd_ADXPeriod=14;          //ADX期間
input double               TrendLevel=20.0;
//--- ColorBBCandlesパラメータ
input string               com2="";                      //---- ColorBBCandlesパラメータ
input int                  BandsPeriod=20;               // BB平均化期間
input double               BandsDeviation=1.0;           // 偏差
input ENUM_MA_METHOD       MA_Method_=MODE_SMA;          // 指標平均化手法
input Applied_price_       IPC=PRICE_CLOSE_;             // 価格定数
//--- Percentage of Trendパラメータ
input string               com3="";                      //---- Percentage of Trendパラメータ
input int                  InpPeriodPoT=20;
input double               UpTrendLevel=0.7;
input double               DnTrendLevel=0.3;
//--- RSIFilterパラメータ
input string               com4="";                      //---- RSIFilterパラメータ
input uint                 RSIPeriod=10;                 // 指標期間
input ENUM_APPLIED_PRICE   RSIPrice=PRICE_CLOSE;         // 価格
input uint                 HighLevel=60;                 // 買われ過ぎレベル
input uint                 LowLevel=40;                  // 売られ過ぎレベル
//--- ZigZagTrendDetectorパラメータ
input string               com5="";                      //---- ZigZagTrendDetectorパラメータ
input int                  ExtDepth=5;
input int                  ExtDeviation= 5;
input int                  ExtBackstep = 3;


1. 通貨ペアのテスト

4つの通貨ペアをテストした結果、支配的な平均値はトレンド状態の時間の60%に相当することが示されました。同時に、異なる方法および時間枠を使用することによる有意差はみられませんでした。

図7 4通貨ペアのテスト結果

2. 先物のテスト

先物をテストした結果、より長い時間枠では全体的な傾向から逸脱した値が抑止されることが示されました。これは、2,000バーのサンプルシリーズが設定されていたにかかわらず、D1とW1には十分な履歴がないために計算が利用可能な最大履歴に基づいているからです。 

図7 先物GOLD-6.17のテスト結果

3. 株式のテスト

ここでもまた、上記の銘柄にすでに見られる一般的な傾向があります。

 

図8 #MCD株式のテスト結果

テスト中に、選ばれた2,000本のローソク足サンプルの妥当性について考え始めました。平均トレンド値はサンプルシリーズのさまざまな範囲で保持されるのでしょうか?ここには、トレンド/フラットの比率が時間とともにどのように変化するかという、研究にとってもう一つの興味深い問題があります。この比率変化の動態を研究することによって、トレンド、期間、頻度などの特徴の変化を理解することが可能になります。そこで、各トレンド特定手法のサンプル値と平均トレンド値の依存関係を調べることにしました。これによって、上記の質問に対する回答が得られます。スピアマンの順位相関係数を使って依存関係を検索します。 

ここで興味深いのは、テストのバーの数(X)と平均トレンド時間(%)(Y)の2つの数の相関関係です。それぞれのXYに対して、ランクが割り当てられます。得られたランクに基づいて、式を使用して、その差dと係数を計算します。

ここで、nは測定されたXYの対の数です。係数の値は-1から1の範囲にあります。正の値は調査された値の直接的な依存性、負の値は逆依存性を意味します。ゼロ値は、依存関係がないことを示します。

たとえば、EURUSD通貨ペアでADXトレンドを特定する方法の1つをもっとよくみてみましょう。計算は他の方法でも同様に行われ、結果は分かりやすいように表に追加されます。ここでは、トレンド時間の平均値の測定は、テストのために予め選択されたバー(100、200、300、500、1,000、1,500、2,000)の数を用い、n = 7です。以下の表は、係数を計算するために値の測定結果、それらのレンジ、レンジの差、および二乗レンジを示します。

Rx X Y Ry D(Rx-Ry) D2
1  100 75.78 1 0 0
2  200 77.72 2 0 0
3  300 79.04 3 0 0
4  500 79.77 5 -1 1
5  1,000 79.49 4 -1 1
6  1,500 81.32 6 0 0
 2,000 81.44 7 0 0

これらの値を式に挿入することにより、係数ρ=1-(6*2)/(7*(49-1)=0.96が得られます。

次に、図8に示された重要な係数値の表で得られた値を確認します。 このテストではn = 7で、トレンドの平均値とバーの選択されたトレンドサンプルの値との間には強い正比例の依存があると結論づけることができます。

図8 スピアマンの順位相関係数の重要な値

次に、選択したEURUSD通貨ペアのすべてのトレンド特定法のスピアマン係数を計算し、その結果を表に表示します。

トレンド特定方法 スピアマン係数値
 ADX 0.96
 ColorBBCount 0.89
 Percentage of Trend 0.68
 RSIフィルタ -0.68
 ZigZagTrendDetector -0.07 

結果は何を表すのでしょうか?最初の3つのトレンド特定法では、平均トレンド値が履歴の深さに直接依存する一方、RSIフィルタは逆の依存関係を示しました。ZigZag指標は最終結果がサンプルシリーズのサイズに依存しないことを示しました。テストに関わる他の計測器の係数を計算し、その結果を表にまとめましょう。 

トレンド特定方法 EURUSD USDCHF USDJPY GBPUSD GOLD-6.17 #MCD
 ADX 0.96 -0.61 -0.75 0.96 -0.86 0.93
 ColorBBCount 0.89 0.46 -0.11 -0.14 -0.64 0.79
 Percentage of Trend 0.68 0.93 0.11 0.29 0.89 1
 RSIフィルタ -0.68 1 0.04 0.79 -1 0.89
 ZigZagTrendDetector -0.07 0 0.96 0.96 0.36 0.32

得られた結果に基づき、各取引商品について以下の結論を導き出すことができます。

  • EURUSD:5つのトレンド分析手法のうちの3つでは強い相関関係があります。トレンド相場の割合は履歴が深いほど大きくなります。
  • USDCHF:以前の製品と同様:トレンド相場の割合は以前は今よりも高いものでした。
  • USDJPY:ここでは、サンプルサイズの変更と最終値との間には関係がありません。この市場の動きとダイナミクスの本質はあまり変わっていません。
  • GPBUSD:5つの手法のうち4つの手法では、トレンドとサンプルサイズの比率に直接比例する依存関係があります。また、このペアでは、過去のトレンド相場の割合が今日よりも高いとの結論がでています。
  • GOLD-6.17:サンプルの大きさには依存しないことが観察されました。
  • #MCD:依存は5つすべての場合に存在します(これらのうちの4つに顕著です)。これはまた、過去の強くて長いトレンドを示しています。履歴が今日に近ければ近いほど、選ばれた市場での強いトレンドの持続時間と発生率は低下します。

得られた結果の信頼性を検証するために、長期間にわたり、そして長い履歴期間にわたり、テストされた製品のチャートを検討してみましょう。これは、トレンドの動きの性質が変化しているかどうかを知ることになります。調査のために、週足を検討し、トレンドとフラットの特徴的なセグメントを特定してみましょう。

1. EURUSD

以下の図を考慮してください。1995年から現在までのEURUSD通貨ペアが示されています。 

EURUSD週足チャート、1995-2017

ここでは、3つの領域が市場の特徴を表しています。

  • 第1領域は、若干の相場の戻しを伴う長期的な下降トレンドを示しています。トレンドの持続時間と強さにご注意ください。
  • 第2領域の動きは第1領域とほぼ反対ですが、トレンドと期間は同様です。お分かりのように、この二つの動きは1995年から2007年の間に起こりました。
  • 3番目と4番目のマークされた領域ではトレンドの強さと持続時間は大きく減少しています。履歴的規模では、最近のトレンドは横向きの動きに似ています。

これらの所見は、選択されたトレンド特定法に対するスピアマンの順位相関係数の計算が、変化するトレンド/フラット比率の現在の特徴を確実に示すことを示唆しています。


2. USDJPY

この銘柄の相関係数の計算は、変化の性質への依存もトレンドと時間との間の相関も示しませんでした。図10は、1995年の初めから顕著な強い上向きの動きがあり、振幅がはるかに小さく著しく短いトレンドが続いたことを明確に示しています。図の2番目の部分(下降トレンドに続いた上昇トレンド)には、数ヶ月間続く頻繁な平らな動きがあります。 


図10 USDJPY週足チャート1995-2017

したがって、この場合スピアマンの順位相関係数は、期間と傾向/均衡比率との間の依存関係が正しくないことを正しく表しています。


3. #MCD

株では5つのトレンド特定法のすべてで相関が観察されました。図11は、過去には、株価は大幅に下落したり平らな状態が長引いたりすることなく上昇していたことを示します。 また、最近のトレンド/フラット領域のどのような動きがどのような比率で支配的であったかが明確に確認できます

図11 #MCD株式、2003-2017

したがって、スピアマンの順位相関係数の計算は完全に正当化され、トレンド/フラット比率のフラットに向かった強い変化が特徴付けられます。研究された市場の一般的なトレンドは、動きの面でもこの動きの性質の面でも市場が変化することを示しています。それらは、不安定になり、よりダイナミックになり、予測しにくくなります。これは、本稿で得られた結果によって証明することができます。トレンド/フラット比率は横方向の動きにシフトしました。 以前にはトレンドは今日よりも目に見えて顕著でした。


終わりに

テストの表現向上のために、テストされたすべての製品の合計値が表として示されています。

テストされた銘柄 トレンド時間の平均値(%)
 EURUSD  62.54
 USDCHF  62.27
 USDJPY  63.05
 GBPUSD  60.68
 GOLD-6.17  59.55
 #MCD  59.71

テスト結果を要約した表に基づくと、所定のテスト条件では、トレンド相場の平均市場価値は約60%ですが、過去から現在までの時間スケールではトレンド/フラット比率はフラットに向かい初期に仮定された 30:70に徐々に近づいていると結論づけることができます。

結果は何を表すのでしょうか?

  • 市場はよりダイナミックであり、トレンド/フラットフェーズ変動はますます頻繁に発生します。
  • 長いトレンド期間はより短い変動に変化し、 動きの特徴は以前よりもはっきりしなくなります。
  • したがって、市場の動態、動向および相はより複雑になります。

終わりに

添付されたアーカイブには、リストされたすべてのファイルが含まれています。ファイルは、適切なフォルダにあります。正しい操作のためには、MQL5フォルダを端末のルートフォルダに保存するだけです。

以下は本稿で使用されているプログラムです。

#
 名称
種類
説明
1
TrendCount.mq5 エキスパート
 テストツール 
2
TrendCountUI.mqh ライブラリ  ユーザーインターフェイスクラス
3 ColorBBCandles.mq5 指標  トレンドの力と方向の指標(ボリンジャーバンドに基づく)
4 percentageoftrend.mq5 指標  トレンド/フラット状態を計算する指標
5 rsifilter.mq5 指標  事前に設定された買われ過ぎ/売られ過ぎレベルを持つRSI指標(ヒストグラム)
6 ZigZagTrendDetector.mq5  指標   ZigZagを使用してトレンドを特定するための指標


トレンドの長さは?
本稿では、フラット(不活発な市場)に対したトレンドの期間を特定することを目的としたいくつかのトレンド識別法を紹介します。理論的には、トレンドとフラットの比率は30〜70%と考えられます。これを確認していきます。

内容


はじめに

異なる期間における市場条件の特定は、為替取引の基本原則です。トレーダーの成功は、価格予測の正確さにかかっています。このトピックについてはすでに多数の記事が書かれており(例: MQL5でトレンドを見つけるいくつかの方法 )指標とエキスパートアドバイザーを使ってトレンド相場を特定する方法が説明されています。私が以前に書いた「 Comparative Analysis of 10 Trend Strategies(10のトレンド戦略の比較分析)(英文)」もまたトレンドに専念し、トレンドフォロー戦略が策定されテストされています。本稿では、トレンドを特定するためのいくつかの方法を選択し、フラットに対したトレンドの持続時間のを目指しています。一般的には、トレンドとフラットの比率は30〜70%と言われています。これを確認します。


タスクの定義

研究のためのタスクと条件を特定しましょう。

  1. 後の量的および質的分析のためにトレンド相場とフラット相場を特定する方法の選択。これには、両方の市況を示すシステムだけが必要です。理想的には、トレンドの力や横向きトレンドの明確な定義などの品質指標を組み込む必要があります。
  2. さまざまな期間および通貨、株式、または先物市場などの異なる単一商品市場または複数商品市場での比率の特定と評価。
  3. ユーザーによる固有の条件で独立した研究を可能にする有用なツールの開発。
  4. 異なる条件で得られたデータに基づいた比較分析と相関の検索。

実装

1. トレンド特定法の選択

1.1. 古典的なトレンド力指標であるADXを使って研究を始めましょう。トレンド領域やフラット領域を見積もるにはTrendLevelのレベルを使用します。トレンドは、メインラインがこのレベルを上回った場合に存在するとしましょう。図1は、この方法を用いてトレンド領域フラット領域を特定する例を示します。市況は、所与のサンプルでADX値がTrendLevelより高いローソク足の数について計算されます。

図1 ADXを使用したトレンド/フラット領域の特定

1.2. 次に、ボリンジャー指標を1つのみ選択して表示される色数を2(赤と緑)に減らしてトレンドパワーと方向インディケータを考えてみましょう。図2は、特定の色でローソク足がマークされており、強い市場トレンドをはっきりと示しています。

図2 ボリンジャーバンドを使用したトレンド/フラット領域の特定

1.3. 3番目に、Percentage of Trendを考慮します。これは、2番目の期間を削除し、トレンドのカラー表示を追加することによっても変更されています。図3にはこの指標を適用した結果が示されています。

 

図3 Percentage of Trendを使用したトレンド/フラット領域の特定

1.4. トレンド/フラット領域を特定するあと一つの方法はRSIFilterです。計算を簡単にするため、RSI指標はヒストグラムとして表示され、事前に設定された買われ過ぎ/売られ過ぎ領域に入る指標値を示す縦の列が表示されます。ここでは、元の指標も変更されています。フラットな状態は表示されず、この市場条件でのヒストグラムの高さ値のバッファはゼロになります。これは、トレンドをより簡単に特定するために行われます(この場合、バッファ値は1に等しい)。図4は指標の例を示します。

図4  RSIFilterを使用したトレンド/フラット領域の特定

1.5. 最後に、「MQL5でトレンドを見つけるいくつかの方法」稿からの、ZigZagTrendDetector指標を使用してトレンド/フラット状態を識別する方法を検討します。この場合は変更はありません。その実装は図5に示されています。

図5 ZigZagTrendDetectorを使用したトレンド/フラット領域の特定

2. 市場条件を計算するためのツールの開発と実装結果の表示

トレンド/フラット領域を特定する各方法の結果は、いくつかの時間枠を要約した表として表示されます。表現を分かりやすくするためにグラフィカルインタフェースの記事シリーズに基づいてEasyAndFastGUIライブラリを使用しました。結果を視覚化するためには、特別なCTrendCountUI クラスが開発されました。より良い表現のために、 図6は、すべての計算を記録するために使用された元のテンプレートを示します。

 

図6 テスト結果の計算を表示するテンプレート

スクリーンショットで見ることができるように、最初の列はトレンドを計算する方法を示し、最初の行は複数時間枠オプションの計算を示します。スペースを節約して読みやすさを保つために、ここでは上に示したテンプレートを設定して視覚化する関数だけを表示し、インターフェイスの完全な実装は除外します。

//+------------------------------------------------------------------+
//| 情報パネルの出力と設定                |
//+------------------------------------------------------------------+
void SetInfoPanel()
  {
//---

   UI.CreateMainPanel("Trend Counter");
   UI.CreateStatusBar(1,25);
   UI.m_status_bar.ValueToItem(0,"Enabled on "+Symbol());
   UI.CreateCanvasTable();
//---

   UI.m_canvas_table.SetValue(0,0,"Value");
   UI.m_canvas_table.SetValue(0,1,"ADX");
   UI.m_canvas_table.SetValue(0,2,"BB");
   UI.m_canvas_table.SetValue(0,3,"PoT");
   UI.m_canvas_table.SetValue(0,4,"RSI");
   UI.m_canvas_table.SetValue(0,5,"ZZ");
//---

   UI.m_canvas_table.SetValue(1,0,"M1");
   UI.m_canvas_table.SetValue(2,0,"M5");
   UI.m_canvas_table.SetValue(3,0,"M15");
   UI.m_canvas_table.SetValue(4,0,"M30");
   UI.m_canvas_table.SetValue(5,0,"H1");
   UI.m_canvas_table.SetValue(6,0,"H4");
   UI.m_canvas_table.SetValue(7,0,"H6");
   UI.m_canvas_table.SetValue(8,0,"D1");
   UI.m_canvas_table.SetValue(9,0,"W1");

   UI.m_canvas_table.UpdateTable(true);
   UI.CreateLabel("Working...");
  }

次のステップは、上記の計算法のアルゴリズムを作成することです。実装オプションのほとんどは類似しているため、それらのうちの1つだけを分析します。計算に没頭しましょう。

最初に記述した方法(ADX)のGetADXCount()関数から始めます。

//+------------------------------------------------------------------+
//| ADXを指標して市場条件を計算する関数         |
//+------------------------------------------------------------------+
bool GetADXCount()
  {
//--- ブロック1
   double adx[],result[],count;
   int to_copy,bars;
   int tf_size=ArraySize(Ind_Timeframe);
   ArrayResize(Ind_Handle,tf_size);
   ArrayResize(result,tf_size);
   ArrayInitialize(adx,0.0);
   ArrayInitialize(result,0.0);
   ArraySetAsSeries(adx,true);
//---

   for(int i=0;i<tf_size;i++)
     {
      count=0;
      Ind_Handle[i]=iADX(Symbol(),Ind_Timeframe[i],InpInd_ADXPeriod);
      if(Ind_Handle[i]==INVALID_HANDLE)
        {
         Print(" Failed to get the indicator handle");
         return(false);
        }
      //--- ブロック2

      bars=Bars(Symbol(),Ind_Timeframe[i]);
      to_copy=(bars<NumCandles)?bars:NumCandles;
      //---

      if(CopyBuffer(Ind_Handle[i],0,0,to_copy,adx)<=0)
         return(false);
      //--- ブロック3

      for(int j=0;j<to_copy;j++)
        {
         if(adx[j]>TrendLevel)
            count++;
        }
      result[i]=(count/to_copy)*100;
      IndicatorRelease(Ind_Handle[i]);
     }
//--- ブロック4

   for(int i=1;i<=tf_size;i++)
      UI.m_canvas_table.SetValue(i,1,DoubleToString(result[i-1],2));
   UI.m_canvas_table.UpdateTable(true);
   return(true);
  }

上記のコードブロックを考えてみましょう。

  • ブロック1:変数と配列の初期化とテストに使用される時間枠数への削減。
  • ブロック2:テストして百分率の結果を取得するための特定の数のローソク足のサンプル。長めの時間枠や履歴が少ない製品では、サンプルに十分なバーがないことがあるので、履歴の深さを特定し、必要に応じて、要求されるデータ量を調整する必要があります。
  • ブロック3:ADX指標の場合、現在のバーの値がTrendLevelを上回ったときにカウンタをインクリメントします。 
  • ブロック4:SetInfoPanel() 関数で以前に用意された表にテスト結果を追加します。

その後、ブロック3(カウントの条件)のみが変更されます。

GetColorBBCount()関数

for(int j=0;j<to_copy;j++)
        {
         if(bb[j])
            count++;
        }
result[i]=(count/to_copy)*100;

選択された指標バッファの非ゼロ値は、サンプル中の現在のローソク足がトレンドに属することを意味します。さもなければこれはフラット期間です。

GetPoTCount() 関数

Percentage of Trend'指標のパラメータは次のとおりです。

//--- Percentage of Trendパラメータ

input int                  InpPeriodPoT=20;
input double               UpTrendLevel=0.8;
input double               DnTrendLevel=0.2;

UpTrendLevelおよびDnTrendLevelレベルを超える指標値はトレンドの存在を示します。したがって、計算は次のようになります。

 for(int j=0;j<to_copy;j++)
        {
         if(pot[j]>=UpTrendLevel || pot[j]<=DnTrendLevel)
            count++;
        }
 result[i]=(count/to_copy)*100;

GetRSICount() 関数

関数はヒストグラムで表されるため、1はトレンドの存在を示し、0はその不在を示します。この条件はGetColorBBCount()と同じです。

 for(int j=0;j<to_copy;j++)
        {
         if(rsi[j])
            count++;
        }
 result[i]=(count/to_copy)*100;

GetZZCount() 関数

1つ前の関数と類似する、指標の同じヒストグラム形式。

 for(int j=0;j<to_copy;j++)
        {
         if(zz[j])
            count++;
        }
 result[i]=(count/to_copy)*100;

GetAverage()関数

すべてのメソッドと時間枠の全体的な結果を計算します。

//+------------------------------------------------------------------+
//| すべてのデータの平均値を計算する関数        |
//+------------------------------------------------------------------+
string GetAverage(double &arr[])
  {
   double sum=0.0;
   int size=ArraySize(arr);
   for(int i=0;i<size;i++)
      sum+=arr[i];
   sum/=size;
   return(DoubleToString(sum,2));
  }
//+------------------------------------------------------------------+

その結果、データの計算と出力は次のように簡潔に表現されます。

//+------------------------------------------------------------------+
//| エキスパート初期化関数                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   SetInfoPanel();
   if(GetADXCount() && 
      GetColorBBCount() && 
      GetPoTCount() && 
      GetRSICount() && 
      GetZZCount()
      )
      UI.m_label1.LabelText("Done. Result for "+IntegerToString(NumCandles)+" bars. Average Trend Time - "+GetAverage(avr_result)+"%");
   else
     {
      UI.m_label1.LabelText("Error");
     }
//---
   return(INIT_SUCCEEDED);
  }


テスト

研究条件の範囲を最大限にするために、テストではさまざまな手段を使用することが決められました。

  • 通貨ペア - EURUSD、USDCHF、USDJPY、GBPUSD
  • 先物(GOLD-6.17)
  • 株式市場(#MCD)

すべての時間枠で、2,000バーのサンプルでテストが行われます。テストパラメータはすべての銘柄で同じです。

//+------------------------------------------------------------------+
//| エキスパート入力パラメータ                                          |
//+------------------------------------------------------------------+

input int                  NumCandles=2000;              // 分析するローソク足の数
//---- ADXパラメータ
input string               com1="";                      //---- ADXパラメータ
input int                  InpInd_ADXPeriod=14;          //ADX期間
input double               TrendLevel=20.0;
//--- ColorBBCandlesパラメータ
input string               com2="";                      //---- ColorBBCandlesパラメータ
input int                  BandsPeriod=20;               // BB平均化期間
input double               BandsDeviation=1.0;           // 偏差
input ENUM_MA_METHOD       MA_Method_=MODE_SMA;          // 指標平均化手法
input Applied_price_       IPC=PRICE_CLOSE_;             // 価格定数
//--- Percentage of Trendパラメータ
input string               com3="";                      //---- Percentage of Trendパラメータ
input int                  InpPeriodPoT=20;
input double               UpTrendLevel=0.7;
input double               DnTrendLevel=0.3;
//--- RSIFilterパラメータ
input string               com4="";                      //---- RSIFilterパラメータ
input uint                 RSIPeriod=10;                 // 指標期間
input ENUM_APPLIED_PRICE   RSIPrice=PRICE_CLOSE;         // 価格
input uint                 HighLevel=60;                 // 買われ過ぎレベル
input uint                 LowLevel=40;                  // 売られ過ぎレベル
//--- ZigZagTrendDetectorパラメータ
input string               com5="";                      //---- ZigZagTrendDetectorパラメータ
input int                  ExtDepth=5;
input int                  ExtDeviation= 5;
input int                  ExtBackstep = 3;


1. 通貨ペアのテスト

4つの通貨ペアをテストした結果、支配的な平均値はトレンド状態の時間の60%に相当することが示されました。同時に、異なる方法および時間枠を使用することによる有意差はみられませんでした。

図7 4通貨ペアのテスト結果

2. 先物のテスト

先物をテストした結果、より長い時間枠では全体的な傾向から逸脱した値が抑止されることが示されました。これは、2,000バーのサンプルシリーズが設定されていたにかかわらず、D1とW1には十分な履歴がないために計算が利用可能な最大履歴に基づいているからです。 

図7 先物GOLD-6.17のテスト結果

3. 株式のテスト

ここでもまた、上記の銘柄にすでに見られる一般的な傾向があります。

 

図8 #MCD株式のテスト結果

テスト中に、選ばれた2,000本のローソク足サンプルの妥当性について考え始めました。平均トレンド値はサンプルシリーズのさまざまな範囲で保持されるのでしょうか?ここには、トレンド/フラットの比率が時間とともにどのように変化するかという、研究にとってもう一つの興味深い問題があります。この比率変化の動態を研究することによって、トレンド、期間、頻度などの特徴の変化を理解することが可能になります。そこで、各トレンド特定手法のサンプル値と平均トレンド値の依存関係を調べることにしました。これによって、上記の質問に対する回答が得られます。スピアマンの順位相関係数を使って依存関係を検索します。 

ここで興味深いのは、テストのバーの数(X)と平均トレンド時間(%)(Y)の2つの数の相関関係です。それぞれのXYに対して、ランクが割り当てられます。得られたランクに基づいて、式を使用して、その差dと係数を計算します。

ここで、nは測定されたXYの対の数です。係数の値は-1から1の範囲にあります。正の値は調査された値の直接的な依存性、負の値は逆依存性を意味します。ゼロ値は、依存関係がないことを示します。

たとえば、EURUSD通貨ペアでADXトレンドを特定する方法の1つをもっとよくみてみましょう。計算は他の方法でも同様に行われ、結果は分かりやすいように表に追加されます。ここでは、トレンド時間の平均値の測定は、テストのために予め選択されたバー(100、200、300、500、1,000、1,500、2,000)の数を用い、n = 7です。以下の表は、係数を計算するために値の測定結果、それらのレンジ、レンジの差、および二乗レンジを示します。

Rx X Y Ry D(Rx-Ry) D2
1  100 75.78 1 0 0
2  200 77.72 2 0 0
3  300 79.04 3 0 0
4  500 79.77 5 -1 1
5  1,000 79.49 4 -1 1
6  1,500 81.32 6 0 0
 2,000 81.44 7 0 0

これらの値を式に挿入することにより、係数ρ=1-(6*2)/(7*(49-1)=0.96が得られます。

次に、図8に示された重要な係数値の表で得られた値を確認します。 このテストではn = 7で、トレンドの平均値とバーの選択されたトレンドサンプルの値との間には強い正比例の依存があると結論づけることができます。

図8 スピアマンの順位相関係数の重要な値

次に、選択したEURUSD通貨ペアのすべてのトレンド特定法のスピアマン係数を計算し、その結果を表に表示します。

トレンド特定方法 スピアマン係数値
 ADX 0.96
 ColorBBCount 0.89
 Percentage of Trend 0.68
 RSIフィルタ -0.68
 ZigZagTrendDetector -0.07 

結果は何を表すのでしょうか?最初の3つのトレンド特定法では、平均トレンド値が履歴の深さに直接依存する一方、RSIフィルタは逆の依存関係を示しました。ZigZag指標は最終結果がサンプルシリーズのサイズに依存しないことを示しました。テストに関わる他の計測器の係数を計算し、その結果を表にまとめましょう。 

トレンド特定方法 EURUSD USDCHF USDJPY GBPUSD GOLD-6.17 #MCD
 ADX 0.96 -0.61 -0.75 0.96 -0.86 0.93
 ColorBBCount 0.89 0.46 -0.11 -0.14 -0.64 0.79
 Percentage of Trend 0.68 0.93 0.11 0.29 0.89 1
 RSIフィルタ -0.68 1 0.04 0.79 -1 0.89
 ZigZagTrendDetector -0.07 0 0.96 0.96 0.36 0.32

得られた結果に基づき、各取引商品について以下の結論を導き出すことができます。

  • EURUSD:5つのトレンド分析手法のうちの3つでは強い相関関係があります。トレンド相場の割合は履歴が深いほど大きくなります。
  • USDCHF:以前の製品と同様:トレンド相場の割合は以前は今よりも高いものでした。
  • USDJPY:ここでは、サンプルサイズの変更と最終値との間には関係がありません。この市場の動きとダイナミクスの本質はあまり変わっていません。
  • GPBUSD:5つの手法のうち4つの手法では、トレンドとサンプルサイズの比率に直接比例する依存関係があります。また、このペアでは、過去のトレンド相場の割合が今日よりも高いとの結論がでています。
  • GOLD-6.17:サンプルの大きさには依存しないことが観察されました。
  • #MCD:依存は5つすべての場合に存在します(これらのうちの4つに顕著です)。これはまた、過去の強くて長いトレンドを示しています。履歴が今日に近ければ近いほど、選ばれた市場での強いトレンドの持続時間と発生率は低下します。

得られた結果の信頼性を検証するために、長期間にわたり、そして長い履歴期間にわたり、テストされた製品のチャートを検討してみましょう。これは、トレンドの動きの性質が変化しているかどうかを知ることになります。調査のために、週足を検討し、トレンドとフラットの特徴的なセグメントを特定してみましょう。

1. EURUSD

以下の図を考慮してください。1995年から現在までのEURUSD通貨ペアが示されています。 

EURUSD週足チャート、1995-2017

ここでは、3つの領域が市場の特徴を表しています。

  • 第1領域は、若干の相場の戻しを伴う長期的な下降トレンドを示しています。トレンドの持続時間と強さにご注意ください。
  • 第2領域の動きは第1領域とほぼ反対ですが、トレンドと期間は同様です。お分かりのように、この二つの動きは1995年から2007年の間に起こりました。
  • 3番目と4番目のマークされた領域ではトレンドの強さと持続時間は大きく減少しています。履歴的規模では、最近のトレンドは横向きの動きに似ています。

これらの所見は、選択されたトレンド特定法に対するスピアマンの順位相関係数の計算が、変化するトレンド/フラット比率の現在の特徴を確実に示すことを示唆しています。


2. USDJPY

この銘柄の相関係数の計算は、変化の性質への依存もトレンドと時間との間の相関も示しませんでした。図10は、1995年の初めから顕著な強い上向きの動きがあり、振幅がはるかに小さく著しく短いトレンドが続いたことを明確に示しています。図の2番目の部分(下降トレンドに続いた上昇トレンド)には、数ヶ月間続く頻繁な平らな動きがあります。 


図10 USDJPY週足チャート1995-2017

したがって、この場合スピアマンの順位相関係数は、期間と傾向/均衡比率との間の依存関係が正しくないことを正しく表しています。


3. #MCD

株では5つのトレンド特定法のすべてで相関が観察されました。図11は、過去には、株価は大幅に下落したり平らな状態が長引いたりすることなく上昇していたことを示します。 また、最近のトレンド/フラット領域のどのような動きがどのような比率で支配的であったかが明確に確認できます

図11 #MCD株式、2003-2017

したがって、スピアマンの順位相関係数の計算は完全に正当化され、トレンド/フラット比率のフラットに向かった強い変化が特徴付けられます。研究された市場の一般的なトレンドは、動きの面でもこの動きの性質の面でも市場が変化することを示しています。それらは、不安定になり、よりダイナミックになり、予測しにくくなります。これは、本稿で得られた結果によって証明することができます。トレンド/フラット比率は横方向の動きにシフトしました。 以前にはトレンドは今日よりも目に見えて顕著でした。


終わりに

テストの表現向上のために、テストされたすべての製品の合計値が表として示されています。

テストされた銘柄 トレンド時間の平均値(%)
 EURUSD  62.54
 USDCHF  62.27
 USDJPY  63.05
 GBPUSD  60.68
 GOLD-6.17  59.55
 #MCD  59.71

テスト結果を要約した表に基づくと、所定のテスト条件では、トレンド相場の平均市場価値は約60%ですが、過去から現在までの時間スケールではトレンド/フラット比率はフラットに向かい初期に仮定された 30:70に徐々に近づいていると結論づけることができます。

結果は何を表すのでしょうか?

  • 市場はよりダイナミックであり、トレンド/フラットフェーズ変動はますます頻繁に発生します。
  • 長いトレンド期間はより短い変動に変化し、 動きの特徴は以前よりもはっきりしなくなります。
  • したがって、市場の動態、動向および相はより複雑になります。

終わりに

添付されたアーカイブには、リストされたすべてのファイルが含まれています。ファイルは、適切なフォルダにあります。正しい操作のためには、MQL5フォルダを端末のルートフォルダに保存するだけです。

以下は本稿で使用されているプログラムです。

#
 名称
種類
説明
1
TrendCount.mq5 エキスパート
 テストツール 
2
TrendCountUI.mqh ライブラリ  ユーザーインターフェイスクラス
3 ColorBBCandles.mq5 指標  トレンドの力と方向の指標(ボリンジャーバンドに基づく)
4 percentageoftrend.mq5 指標  トレンド/フラット状態を計算する指標
5 rsifilter.mq5 指標  事前に設定された買われ過ぎ/売られ過ぎレベルを持つRSI指標(ヒストグラム)
6 ZigZagTrendDetector.mq5  指標   ZigZagを使用してトレンドを特定するための指標