通貨ペアバスケットをトレードするときに発生するパターンのテスト パート2

Andrei Novichkov | 8 1月, 2018


イントロダクション

通貨ペアバスケットをトレードするときに発生するパターンをテストします。 前回の記事では、買われ過ぎ/売られ過ぎレベルの画期的なパターンを調べました。 このレベルのブレークスルーは、複合WPR インジケーターを使用して検討しました。 これは、オシレーターに基づいて他の組み合わせのインジケーターに拡張することができます。 ここでは結果が同じようになると仮定します。

実施したテスト結果は、売られ過ぎ/買わレベルの場所の評価でした。 買われ過ぎレベルは、60から 70% の値の範囲で、売られ過ぎのレベルは、-60% から-70% に変化します。 このパターン操作をテストすると、すべての通貨ペアバスケットで H4 に収益性が示されました。 D1 は、トレード数が少なくなりました。 H1 は大きな損失を被りました。

この記事では、移動平均 (MA) を結合されたインジケーターのチャートに適用し、トレードで使用します。 両方の標準的なテクニカル分析と独自のメソッドに頼ります。

研究ツール

メインツールは、20の期間とよく知られているWPR です。 МАを10のピリオドで実行します。 グローバルなプロセスを監視するつもりはないので、このような短い期間を選択しています。言い換えれば、ローカルトレンドに関心があるということになります。 したがって、長い期間は考慮しません。

前の記事と同じように、タイムフレーム H1、H4、および D1 を調べてみましょう。 最初のパターンの結果は印象に残るものでした。 したがって、同様に同じ期間に次のいずれかを考慮するのが妥当でしょう。 そして、もちろん、蓄積されたデータは、他のタイムフレームや通貨バスケットの研究に使用することができることを忘れないようにしましょう。

基本的な用語と原則はここにあります。

研究パターン

このパターンは、古典的なテクニカル分析からよく知られています。 これについてはすでに説明しているので、トレード通貨バスケットの主な関数を復習しましょう。

  • トレーダーは、統一インジケーターチャートが移動平均を越えると、エントリーシグナルを受け取ります。

ここには2つのシグナルがあります:

  • 買いシグナル - МАチャートが統一されたインジケーターを上向きに横切るとき。
  • 売りシグナル - МАチャートが統一されたインジケーターを下方に横切るとき。
  • トレーダーは、シグナルを受信し、通貨バスケットをもとに相場に参入します。
  • エントリーとは反対のシグナルを受信したとき、決済をします。

その上、移動平均からのシグナルは遅れることに留意してください。

普通の通貨ペアのチャートに MA を適用する際、高速移動平均には多くのエントリシグナルがあります。 同様にこの場合に十分なシグナルがあるでしょう。 これを確認するために、 testWPR&MA.mq5に下記を添付しました。

//+------------------------------------------------------------------+
//|                                                      testWPR.mq5 |
//|                                        MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#propertyindicator_separate_window
#propertyindicator_minimum -100
#propertyindicator_maximum100


#defineLG 7

#propertyindicator_buffers2
#propertyindicator_plots 2

input int WPR       = 20; //期間 WPR
input int maperiod  = 10; //期間 MA
input color   clr   = clrGreen;
input color   clrMA = clrMagenta;

string pair[]={"EURUSD","GBPUSD","AUDUSD","NZDUSD","USDCAD","USDCHF","USDJPY"};
bool bDirect[]={false,false,false,false,true,true,true};

int h[LG];
double ind[],ma[];

int iUp,iDw;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int()
  {
//---インジケーターバッファのマッピング
   for(int i=0; i<LG; i++)
     {
      h[i]=iWPR(pair[i],0,WPR);
     }

   IndicatorSetString(INDICATOR_SHORTNAME,"testWPRusd");
   IndicatorSetInteger(INDICATOR_DIGITS,2);
   IndicatorSetInteger(INDICATOR_LEVELS,2);
   IndicatorSetInteger(INDICATOR_LEVELSTYLE,0,STYLE_SOLID);
   IndicatorSetInteger(INDICATOR_LEVELSTYLE,1,STYLE_SOLID);
   IndicatorSetInteger(INDICATOR_LEVELCOLOR,0,clrRed);
   IndicatorSetInteger(INDICATOR_LEVELCOLOR,1,clrRed);
   IndicatorSetInteger(INDICATOR_LEVELWIDTH,0,1);
   IndicatorSetInteger(INDICATOR_LEVELWIDTH,1,1);
   IndicatorSetDouble(INDICATOR_LEVELVALUE,0,-60);
   IndicatorSetDouble(INDICATOR_LEVELVALUE,1,60);

   ArraySetAsSeries(ind,true);
   SetIndexBuffer(0,ind);
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_SOLID);
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,2);
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,clr);
   PlotIndexSetString(0,PLOT_LABEL,"_tstWPRusd_");

   ArraySetAsSeries(ma,true);
   SetIndexBuffer(1,ma);
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE);
   PlotIndexSetInteger(1,PLOT_LINE_STYLE,STYLE_SOLID);
   PlotIndexSetInteger(1,PLOT_LINE_WIDTH,1);
   PlotIndexSetInteger(1,PLOT_LINE_COLOR,clrMA);
   PlotIndexSetString(1,PLOT_LABEL,"Middle_Basket_line_MA");

   iUp=iDw=0;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double GetValue(int shift)
  {
   double dBuf[1];
   double res=0.0;
   for(int i=0; i<LG; i++)
     {
      CopyBuffer(h[i],0,shift,1,dBuf);
      if(bDirect[i]==true)
         res+=dBuf[0];
      else
         res+=-(dBuf[0]+100);
     }//end for (int i = 0; i < iCount; i++)      
   res=res/LG;
   return (NormalizeDouble((res + 50) * 2, _Digits) );
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   if(prev_calculated==0 || rates_total>prev_calculated+1)
     {
      int rt=rates_total-WPR;
      for(int i=1; i<rt; i++)
        {
         ind[i]=GetValue(i);
        }
      rt-=maperiod;
      for(int i=1; i<rt; i++)
        {
         ma[i]=GetMA(ind,i,maperiod,_Digits);
        }
      rt--;
      for(int i=1; i<rt; i++)
        {
         if(ind[i] > ma[i] && ind[i+1] < ma[i+1]) {iUp++; continue;}
         if(ind[i] < ma[i] && ind[i+1] > ma[i+1]) {iDw++; continue;}
        }
      PrintFormat("BUY count: %d SELL count: %d",iUp,iDw);
     }
   else
     {
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

void OnDeinit(const int reason)
  {
   for(int i=0; i<LG; i++)
     {
      if(h[i]!=INVALID_HANDLE) IndicatorRelease(h[i]);
     }
   string text;
   switch(reason)
     {
      case REASON_PROGRAM:
         text="Indicator terminated its operation by calling the ExpertRemove() function";break;
      case REASON_INITFAILED:
         text="This value means that OnInit() handler "+__FILE__+" has returned a nonzero value";break;
      case REASON_CLOSE:
         text="Terminal has been closed"; break;
      case REASON_ACCOUNT:
         text="Account was changed";break;
      case REASON_CHARTCHANGE:
         text="Symbol or timeframe was changed";break;
      case REASON_CHARTCLOSE:
         text="Chart was closed";break;
      case REASON_PARAMETERS:
         text="Input-parameter was changed";break;
      case REASON_RECOMPILE:
         text="Program "+__FILE__+" was recompiled";break;
      case REASON_REMOVE:
         text="Program "+__FILE__+" was removed from chart";break;
      case REASON_TEMPLATE:
         text="New template was applied to chart";break;
      default:text="Another reason";
     }
   PrintFormat("%s",text);
  }
//+------------------------------------------------------------------+

double GetMA(const double &arr[],int index,int period,int digit) 
  {
   double m=0;
   for(int j=0; j<period; j++) m+=arr[index+j];
   m/=period;
   return (NormalizeDouble(m,digit));
  }
//+------------------------------------------------------------------+

このインジケーターは、履歴全体の中で、統一インジケーターが移動平均を越える回数をカウントします。 EURUSD にインジケータを配置し、テスト期間の USD バスケットのデータを取得してみましょう:

  受信シグナル
H1 H4 D1
Buy Sell Buy Sell Buy Sell
EURUSD 8992 8992 2448 2449 550 551
History depth 2005.09.08 2004.10.11 2000.02.28

ここには十分なシグナルがあることがわかります。 この状況は、他の通貨バスケットに似ていると仮定し、チェックする必要がないものとします。

以下のスクリーンショットは、インジケータ操作を示しています。

潜在的なシグナルがすぐ目につきます。 明らかに、多くのダマシがありますが、それについて考えるのは早すぎます。 青色で買いシグナルをペイントし、赤で売りシグナルを色づけします。

操作ロジックは次のとおりです。

  • エントリーシグナルを取得します。 反対側のシグナルを取得した後に決済します。 反対方向にエントリーします。 適切なシグナルを受信して、このシーケンスを繰り返します。

任意の追加のフィルターがない場合には、このメソッドは相場でコンスタントになります。 ほとんどの場合、この種のフィルターが必要になりますが、後でこの問題について検討します。 一方で、スクリーンショットのシグナルの質の差は明らかです:

  • ポイント7および ポイント8 (青) でシグナルをクリア
  • ポイント5(赤)の良いシグナル;
  • ポイント2、ポイント3およびポイント4で別に指示されたシグナルのクラスタ (赤)。

"悪いシグナル" と "良いシグナル"を区別するためのルールを紹介しましょう。 次の2つの画像では、正確に "良い" シグナルを明らかにすることができます。

探している "良い" パターン (シグナル)
「悪い」シグナルパターン





USD の結合 WPR チャートは緑で表示され、赤線は移動平均を表し、垂直の青色の線はパターンの罫線を示します。

Delta1と Delta2 の距離の値は、エントリパターンの 5% 未満であるべきではないと仮定します。

もかかわらず、同様に、右に画像のような "悪い" パターンがあります。 これは決済シグナルになりません。 代わりに、トレンド変化または減速を警告します。 したがって、相場を決済するか、または (まさにやろうとしている) を選別するために使用することができます。

テストの開始

さらなるタスクについては、以下の添付の testEAbasket mq5 ファイルに記載されている EA が必要です。

//+------------------------------------------------------------------+
//|                                                 testEAbasket.mq5 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include<Trade\\Trade.mqh>

#defineLG 7

enum BSTATE 
  {
   BCLOSE = 0,
   BBUY   = 1,
   BSELL  = 2
  };
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
input int wpr = 20;
input int ma  = 10;
input double lt = 0.01; //lot

string pair[]={"EURUSD","GBPUSD","AUDUSD","NZDUSD","USDCAD","USDCHF","USDJPY"};
bool bDirect[]={false,false,false,false,true,true,true};

int h;
ulong  Ticket[LG];

double m[1],ml;
double w[1],wl;

BSTATE g_state;

double g_dMinSize = 5.0;

int()
  {
   h = iCustom(NULL,0,"testWPR&MA",wpr,ma);
   if (h == INVALID_HANDLE) {
      Print("Error while creating testWPReur");
      return (INIT_FAILED);
   }
   
   g_state = BCLOSE;
   
   EventSetTimer(1);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   IndicatorRelease(h);
   EventKillTimer();
      
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   if(IsNewCandle()) 
     {
         wl = w[0];
         CopyBuffer(h,0,1,1,w);
         ml = m[0];
         CopyBuffer(h,1,1,1,m);
         if ( w[0] > m[0] && wl < ml) {
            if (g_state != BCLOSE) CloseAllPos();
            if ( w[0] - m[0] >= g_dMinSize && ml - wl >= g_dMinSize) {
               EnterBuy(lt);
               g_state = BBUY;
            }   
         }     
         if ( w[0] < m[0] && wl > ml) {
            if (g_state != BCLOSE) CloseAllPos();
            if ( m[0] - w[0] >= g_dMinSize && wl - ml >= g_dMinSize) {
               EnterSell(lt);
               g_state = BSELL;
            }   
         }            
     }      
  }
//+------------------------------------------------------------------+
  
void CloseAllPos() 
  {

   CTrade Trade;
   Trade.LogLevel(LOG_LEVEL_NO);

   for(int i=0; i<LG; i++) 
     {

      Trade.PositionClose(Ticket[i]);
     }

     g_state = BCLOSE;

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void EnterBuy(double lot) 
  {

   CTrade Trade;
   Trade.LogLevel(LOG_LEVEL_NO);

   for(int i=0; i<LG; i++) 
     {
      if(bDirect[i]) 
        { //send buy
         Trade.Buy(lot,pair[i]);
         Ticket[i]=Trade.ResultDeal();
        }
      else 
        { //send sell
         Trade.Sell(lot,pair[i]);
         Ticket[i]=Trade.ResultDeal();
        }
     }
     g_state = BBUY;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void EnterSell(double lot) 
  {

   CTrade Trade;
   Trade.LogLevel(LOG_LEVEL_NO);

   for(int i=0; i<LG; i++) 
     {
      if(bDirect[i]) 
        { //send sell
         Trade.Sell(lot,pair[i]);
         Ticket[i]=Trade.ResultDeal();
        }
      else 
        { //send buy
         Trade.Buy(lot,pair[i]);
         Ticket[i]=Trade.ResultDeal();
        }
     }
     g_state = BSELL;
  }
  
bool IsNewCandle() 
  {

   static int candle=-1;

   int t1=0;
   switch(_Period)
     {
      case PERIOD_H1:  t1 = Hour();   break;
      case PERIOD_H4:  t1 = Hour4();  break;
      case PERIOD_D1:  t1 = Day();    break;
     }
   if(t1 != candle) {candle=t1; return(true);}
   return (false);
  }
int Hour4(){return((int)Hour()/4);}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Day()
  {
   MqlDateTime tm;
   TimeCurrent(tm);
   return(tm.day);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Hour()
  {
   MqlDateTime tm;
   TimeCurrent(tm);
   return(tm.hour);
  }  

H1、H4、D1 のタイムフレームについて、昨年のデータのストラテジーテスターでテストしてみましょう。 米ドル通貨ペアバスケットを分析します。

分析結果は、標準レポートの形式で添付された testEAbasket .zip アーカイブにあります。 すぐにテスト結果が否定的であると見ることができます。 既存の設定では、EA はすべての3つのタイムフレームで不採算です。 否定的ではありますが、しかし予想された結果です。 以前のように、多数の利益を得ることができると仮定することは困難です。 次の状況は、結果にも影響します。

  • 移動平均パターンは、常に (定義によって) 遅れています。
  • 標準的なテクニカル分析では、相場に参入する決定は、単一の高速移動平均の動作に基づいていません。
  • EA は、パターンの "品質" に基づいてシグナルの最小の並べ替えを提供しています。 これは明らかに十分ではなく、特にパターンの "品質" の基準は不正確である可能性があります。

しかし、否定的な結果にもかかわらず、希望が残っています。 記事の最初のパートでは、問題のパターンが H4 でうまく機能していました。 今のパターンは、H1 で比較的よい結果になっています。 結果は否定的だが、利益もあります。 収益性の低下はそれほど急ではありません。

EA とその設定が少し変更された場合、良い見通しを持っていると仮定することが可能です。 バランスがテスト中に利益になっていることがわかります。 多くのトレードがありましたが、曲線には否定的な連続の結果を示す非常に深い谷があります。 しかし、ポジティブなシーケンスも存在しています。 EA のコードを変更することで、この時間枠のパターンの収益性を高めることができます。

パターンフォームの修正

まず頭に浮かぶのは、パターン形式 (Delta1 と Delta2 パラメータ) を変更することです。 当初は 5% を選んだ。 変更した方がいいでしょうか。 値が小さいほど、EA は相場に参入しやすくなります。 値が大きいほど、「トレンド変化インパルス」の増加と同様に、「より強い」パターンを作るエントリの量が減少します。

増やす必要も減らす必要もないと考えています。 これは最適であることを意味している訳ではありません。 しかし、この段階でを最適化を開始する場合、一定の期間と通貨ペアでうまく動作する値を得ることができるかもしれません。 つまり、得られた値が普遍的であることを確認することはできません。

しかし、この方向に別の一歩を踏み出すことは理にかなっていると思います。 最大値を設定することで、Delta1と Delta2 の値を「上」から制限する必要があります。 これは、論理的に正当化されます。なぜなら、あまりに「大きい」パターンがそれより大きな動きになる代りに、レンジまたはトレンドの逆転を引き起こす薄いサイズによって動きを完全に抑えることができるためです。 また、"大きな" パターンでは、既存のトレンドの方向に相場に参入するための悪い場所である、結合された WPR の範囲の反対側の境界線の近くで決済することがあります。

したがって、最大Delta1と Delta2 値を 10% に設定してみましょう。 この場合、パターン「サイズ」は Delta1 + Delta2 = 20% です。 それほど大きくもありません。 EA に次の変更を行う必要があります:

1. グローバル変数を追加

double g_dMaxSize = 10.0;

2. タイマイベント処理関数を変更

void OnTimer()
  {
   if(IsNewCandle())
     {
      wl=w[0];
      CopyBuffer(h,0,1,1,w);
      ml=m[0];
      CopyBuffer(h,1,1,1,m);
      double d1 = MathAbs(w[0] - m[0]);
      double d2 = MathAbs(ml - wl);
      if(w[0]>m[0] && wl<ml) 
        {
         if(g_state!=BCLOSE) CloseAllPos();
         if(d1 >= g_dMinSize && d2 >= g_dMinSize &&
            d1 <= g_dMaxSize && d2 <= g_dMaxSize) 
           {
            EnterBuy(lt);
            g_state=BBUY;
           }
        }
      if(w[0]<m[0] && wl>ml) 
        {
         if(g_state!=BCLOSE) CloseAllPos();
         if(d1 >= g_dMinSize && d2 >= g_dMinSize &&
            d1 <= g_dMaxSize && d2 <= g_dMaxSize) 
           {
            EnterSell(lt);
            g_state=BSELL;
           }
        }
     }
  }


変更した EA を使用して、H1 のテストを続けてみましょう。 この結果は、添付の testEAbasket1 .zip アーカイブで確認できます。 チャートを次に示します。


変更によりポジティブになりました。 結果自体はまだネガティブですが、損失はだいぶ減っています。 損失を作るトレンドが不安定になり、横ばいになりました。 深いドローダウンがあります。 もちろん、このテストは、最終的な結論としては不十分ですが、Delta1と Delta2 の最大値によってフィルタを適用することが有益であると判明しました。 この変更内容を EAのコードに実装してみましょう。

Delta1と Delta2 に得られた値は変更しません。 繰り返しますが、これは値が最適であるという意味ではありません。 しかし、それらのことを念頭に置いて、他のタイムフレームやバスケットに転送する必要があります。

2番目のフィルタ

次のステップは明白です:

  • 複合WPR (同様に他のオシレーター) チャートは、その境界線に近づくと、トレンドの方向に相場をエントリーします。

これは、標準のテクニカルインジケーターを使用するためのよく知られたルールであり、同様に複合インジケーターに拡張することができます。 以前の記事では、トレンドの反転、減速またはレンジが可能であることを指摘しました。 EAの2番目のフィルタに考慮事項を実装する必要があります。

結合WPR は-100% から + 100% に変化します。 数値を直接頼ることはできませんが、境界に近づくので到達することはありません。 代わりに、売られ過ぎ/買われ過ぎのボーダーがあります。 前の記事で、境界線の突破を調べ、その方法を知っています。 それを使いましょう。

より正確に定義する必要があります。

  • トレーダーは、結合WPR チャートが買われ過ぎ境界を上向きに通過した場合に、通貨バスケットで買いをしません。
  • トレーダーは、結合WPRチャートが売られ過ぎのボーダーにタッチもしくはブレイクしている場合、売りしません。

売られ過ぎが60%-70%で設定されているとき、買われ過ぎは60-70%になります。 新しいフィルタでは、下限の境界値 (60% および-60%) を使用します。 結合WPR カーブがフィルターボーダーの下に位置していると仮定しましょう。 つまり、「本格的な」移動平均クロスパターンを検索するつもりはありません。 代わりに、標準のテクニカル分析で適用されるフィルターを用います。

  • 移動平均とインジケーターチャートの相対ポジションを「高い-低い」タイプで検討します。

これを達成するために、相場参入条件を扱うコードブロックを変更してみましょう:

       w [0] > m [0] & & wl< ml) 
        {
         if(g_state!=BCLOSE) CloseAllPos();
         if(d1 >= g_dMinSize && d2 >= g_dMinSize &&
            d1 <= g_dMaxSize && d2 <= g_dMaxSize && w[0] < 60) 
           {
            EnterBuy(lt);
            g_state=BBUY;
           }
        }
      if(w[0]<m[0] && wl>ml) 
        {
         if(g_state!=BCLOSE) CloseAllPos();
         if(d1 >= g_dMinSize && d2 >= g_dMinSize &&
            d1 <= g_dMaxSize && d2 <= g_dMaxSize && w[0] > -60) 
           {
            EnterSell(lt);
            g_state=BSELL;
           }
        }


前に選択した時間間隔と H1 期間のEAをテストしてみましょう。 ここに、結果があります:


添付のtestEAbasket2 ファイル内の完全なアーカイブがあります。 この結果は、わずかに優れているもの、以前のものと大差ありません。

考えられる理由は何でしょうか。 おそらく、買われ過ぎ/売られ過ぎのレベルの不正確な配置、またはフィルタリングされたトレード、またはその両方が不足しているためだと考えられます。

得られた結果は適用したフィルターが無用であることを意味するでしょうか。 そんなことはありません。 明確な結論は、すべてのバスケットにフィルタを適用した後にのみ可能です。(すべての選択された時間枠と有意に1年以上の期間.) したがって、このフィルタは EA のコードに残しておきますが、その関連性は疑わしいものです。

パターンを使用したタスクの完了

米ドルバスケットパターンに関する計画を満たしました。 最終的な EA のバージョンは、添付の testEAbasketFinal.mq5 ファイルにあります。 実施されたテストに基づく主な結論は次の通りです。

  • このパターンは、相場参入シグナルとして使用することはできません。

残りのバスケットのテストを実施する価値はあるでしょうか。 非常に高い確率で、結果は予測可能です。

他の通貨でのテストを実施しないことを主な考慮事項は、単一のМАのブレイクに基づくパターンが標準的なテクニカル分析を含む実際のトレードで本格的な相場参入シグナルとして使用されていないことです。 そこで、移動平均をフィルタとしてクロスする WPR チャートのパターンを使用します。 買われ過ぎ/売られ過ぎのレベルをブレイクする結合インジケーターは主要なシグナルとして適用するべきです。 今回の目標は、このようなフィルタが収益性にどのように影響するかを調べることです。

パターンをフィルタとして使用

最初の問題を定義してみましょう。

  • 結合WPR チャートは、売られ過ぎのレベルを上向きにブレイクします。 このブレイクスルーはロウソク足の終わりに残っています。 トレーダーは、移動平均が「下」の場合にのみバスケットで買いします。
  • バスケットを売りするためには、前の点で記述されているものと反対であるべきです。
  • 0% ゾーンに到達する結合WPRチャートは、相場を決済するために使用されます。

ご覧の通り、この "lite" バージョン ("高い-低い" フィルタ) は、"本格的な" パターンの代わりに再び使用します。 このフィルタは、移動平均の相対ポジションと結合WPR チャートに適用されます。

テストを目的として testEAbasket.mq5 EA を変更してみましょう。 買われ過ぎ/売られ過ぎのレベルとフィルタとしてパターンを適用する条件を記述するためのソースデータを追加する必要があります:

input int SELLPROFIT =   0;
input int SELL1LIMIT =  70;
input int SELL2FROM  =  60;
input int SELL2TO    =  50;

input int BUYPROFIT  =   0;
input int BUY1LIMIT  = -70;
input int BUY2FROM   = -60;
input int BUY2TO     = -50;

//..................................................................

//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   if(IsNewCandle())
     {
      wl=w[0];
      CopyBuffer(h,0,1,1,w);
      ml=m[0];
      CopyBuffer(h,1,1,1,m);

      if(g_state==BBUY && (w[0]>=BUYPROFIT))
        {
         CloseAllPos();
        }
      if(g_state==BSELL && (w[0]<=SELLPROFIT))
        {
         CloseAllPos();
        }
      if(g_state==BCLOSE && w[0]>=BUY2FROM && w[0]<=BUY2TO && wl<=BUY1LIMIT && w[0] > m[0])
        {
            EnterBuy(lt);
            return;        
        }
        
       
      if(g_state==BCLOSE && w[0]<=SELL2FROM && w[0]>=SELL2TO && wl>=SELL1LIMIT && w[0] < m[0])
        {
            EnterSell(lt);
            return;        
        }
    }
  }

testEAbasket1.mq5 ファイルに完全なコードがあります。

テストには H1 タイムフレームを使用します。 マイナスの結果となるトレードが大量に検出されました。 この結果は、前の記事に記載されています。 ここではテストを繰り返しません。

この記事のパターンを使用して、年間間隔のフィルタとしてテストを実施します。 結果は次のとおりです。

フィルターとしてこの記事からパターンを適用すると、ポジティブな結果をもたらしました。 明確な利益増加トレンドを有するかなり滑らかな曲線を得ています。 残念ながら、これに適したトレードはそう多くはありません。 EA をより大きなタイムフレームに適用する場合、この数はさらに減少します。

添付のTester_EURUSD_Filter.zip アーカイブの完全なテストレポートがあります。

結論

特定のバスケットの通貨のオシレーターに基づいて、インジケーターの組み合わせから生じるパターンのテストが終わりました。 基本的に結合WPR を使用しましたが、今回の結果は RSI およびストキャスティクスに拡張することができます。

しかし、まだ実際にはパターンを適用することはできないと認めざるを得ません。 蓄積された統計量は明らかに十分ではありません。 パターンパラメータ自体に加えて、テスト時間間隔にも適用されます。 MA期間を変更すると、むしろ物議を醸しだすでしょう。

しかし同時に、興味深い結果を得ています。

  1. 売られ過ぎ/買われ過ぎのレベルの場所とそれを使用することの見通しについては評価に値します。
  2. また、移動平均をクロスする複合インジケーターチャートの適用性も確認できました。
  3. これまでの2点からなるパターンの共同の適用を評価しました。

言い換えれば、このメソッドを実践に取り入れる第一歩を踏み出しました。

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

 # Name
Type
 Description
1 testWPR&MA.mq5 Indicator
結合インジケーターチャートが移動平均とクロスする回数を確認。
2
testEAbasket.mq5 EA
テストのEA。
 3
testEAbasket.zip Archive testEABasket.mq5 のUSD バスケットを使用した標準 html レポート
 4 testEAbasket1.zip Archive USD バスケットと最初のフィルターを使用した testEABasket.mq5 EA 操作に関する標準の html レポート。
 5
testEAbasket2.zip EA 米ドルバスケットと2つのフィルタを使用した testEABasket.mq5 EA の操作に関する標準の html レポート。
 6 testEAbasketFinal.mq5 EA
testEAbasket.mq5 の最終版EA.
 7 testEAbasket1.mq5
EA テストのEA。
 8 Tester_EURUSD_Filter.zip Archive testEAbasket1.mq5 EA のテストに関するレポートのアーカイブ。