English Русский 中文 Español Deutsch Português
レンジやトレンド相場を例にストラテジーテスターを使ったインジケーターの最適化

レンジやトレンド相場を例にストラテジーテスターを使ったインジケーターの最適化

MetaTrader 4 | 12 9月 2016, 12:29
3 398 0
Carl Schreiber
Carl Schreiber

問題

最適化するために、あまりにも多くのパラメータがあります。

あまりにも多くの組み合わせが存在するインジケーターを利用したEAは、その最適化のために多くの時間が必要になります。EAの最適化を開始する前に、組み合わせの量を削減することができたらどうでしょう?つまり、EAをコーディングする前に、擬似EAをコーディングします。大きな問題を分割し、それらを個別に解決します。この擬似EAは取引しません. 例として、ADXがレンジとトレンド相場を区別することができるかどうかを確認し、いくつかの追加情報を取得します。

相場がレンジであるかどうかを判定する、EAの短期売買手法を想像してみてください。大きい時間枠でADXを使用する必要があります - 1時間足。ADXの取引EAは(トレードに)5つのインジケーターを内包するかもしれませありません。それぞれが4つのパラメータを持っている可能性があり、それぞれが小さなステップをとれば2000の異なる値になるかもしれません。合計で、2000 *5*4=40,000になります。それでは、ADXを追加してみましょう。ADXパラメータの各組み合わせについて、理論的には、40.000回計算する必要があります。

この例では、ADX期間(PER)を設定し、その価格(PRC)およびリミット(LIM)は、レンジ相場によって最初のトレンドを定義します。PER期間2、..、90(ステップ1を=>89の異なる値)は、価格に選択することができます。合計で、89*7*87=54201の組み合わせがあります。ストラテジーテスターのセットアップは、次のとおりです。

図01 StratTester - セットアップパラメータ

図02 StratTester-セットアップEAオプション

図03 StratTester-セットアップオプション

図04 StratTesterセットアップの最適化

最適化を繰り返す場合は、\tester\cache\内のキャッシュファイルを削除することを忘れないでください。OnTester()は、このような場合には実行されないようにしないと、CSVファイルでの最適化をもたらし、ストラテジーテスターの最適化グラフを見つけることができます。

もちろん、通常、ストラテジーテスターによる最適化にこのような範囲を使うでしょうが、第二の範囲を拡大するために、意味のない結果を見つける必要があります。擬似EAは、テストに54201の組み合わせで一つのインジケーターを内包します。(全ティック使用する必要はありません)遺伝的アルゴリズムモードのスイッチをオフにし、すべての組み合わせを計算させることができます。

Adxのの組み合わせの数を削減することができなかった場合、54201の組み合わせで取引します。ただし、他の変数を40,000と乗算しなければならないときは、2168040000組み合わせとなり、 - 非常に多くのパターンを行うためには、遺伝的最適化を使用する必要があります。

Adxの「パラメータの範囲を劇的に縮小することはできませんが- それは必要とされています!レンジ相場の検出が少し遅れトレンド相場であっても、ADXがレンジとトレンド相場の区別が可能であるか確認できるようにADXをより理解します。さらに、レンジとトレンド相場の範囲にストップロスとEAの決済をするためのアイデアを得る可能性があります。ADXの期間はPER:PER: 11..20 (Step 1=> 10), PRC: 0,6 (Step 6=>2) and LIM: 17,..,23 (Step 1=> 7) からテストします。 - 合計で140の組み合わせがあります。2168040000の代わりに、468万の組み合わせを有することを意味します。遺伝的アルゴリズムでは、~10.000を実行しますが、より多くの値がテストされます!

完全に利用可能な組み合わせの関係に応じて変化し、実際のパスを行われます。悪い結果は小さく、良い結果は、次のセットアップが選択されます。


アイデア

擬似EAを構築します。3つの重要な機能を有しています。OnTick()はインジケータをチェックして市場の状態を判断し、OnTester() はCSVファイルへの最終結果を書き、calcOptVal()はストラテジーテスターと遺伝的アルゴリズムにOnTester(によって返される値OptVal)を計算します。最適化パスの最後に呼び出されるOnTester()関数は、特定の値を返し、最適化が終了した後に、CSVファイルに新しい行を追加します。


擬似EA、最初のアプローチ


戻り値を計算するための基準を決定する必要があります。 OptVal。実際の相場の高低を判断し、「FlatRange」から「TrndRange」を分ける必要があります。
double   TrndRangHL,       //高値の合計 - トレンド相場の安値
         TrndNum,          // トレンド相場の数
         FlatRangHL,       // 高値の合計 - レンジ相場の最安値
         FlatNum,          //レンジ相場の数
         RangesRaw,        // レンジ相場の範囲で割ったトレンド相場
         //...

double calcOptVal() // 最初のアプローチ!!
   {
      FlatRange    = FlatRangHL / FlatNum;
      TrndRange    = TrndRangHL / TrndNum;
      RangesRaw    = FlatRange>0 ? TrndRange/FlatRange : 0.0; 
      return(RangesRaw);
   }
...
double OnTester() 
   {
      OptVal = calcOptVal();
      return( OptVal );
   }

上記の設定で最適化を実行する場合は、 OptVal= RangesRawは、次のようにグラフが見えます。:

図05 TesterGraph

トップダウンOnTester結果による最適化の結果は、以下を参照してください。

図06テスターのベスト値

ばかばかしいほどの高い関係です!CSVファイルを見れば、レンジ相場の平均の長さは1バーとスイッチ量(レンジ相場の数+トレンド相場の数)で、小さすぎるということがわかります。(Adxのの価格の正確な数は、CSVファイルに書かれているPRC=1994719249の代わりに0,..,6の数字は、気にしないでください!)。

この結果は、極端な状況を排除するためにより多くの条件を追加することが必要であることを意味します。


擬似EAの改善

まず、最小の長さや相場のレンジやトレンドの足の最小値を追加します。

      FlatBarsAvg  = FlatBars/FlatNum; //レンジ相場の足の合計/レンジ相場の数
      TrndBarsAvg  = TrndBars/TrndNum; //トレンド相場の足の合計/トレンド相場の数
      BrRaw        = fmin(FlatBarsAvg,TrndBarsAvg);

次に、レンジとトレンドの間のスイッチの最小値を指定します。

      SwitchesRaw= TrndNum+ FlatNum。//トレンドとレンジ相場の数

次の問題に直面します!0から100,000.0をに生の範囲を範囲、BrRaw0~0.5及び~8000に0から切り替えます(=Bars()) - 理論的には、すべての新しい足のスイッチを持っています。

3つの基準を均等にする必要があります!atan(..)アークタンジェント:必要な機能を使用します!sqrt()やlog()以外、負の値で問題ありません。例えば、RangesRaw、ATAN(100,000)とATAN(20)との差ではほぼ0になり、他の要因の結果は、ほぼ等しく重み付けされています。ATAN()が制限値を超えることはありません。さらにatan()は、ハードリミット(X>のリミット)重みはすべて平等に大きなリミット値と、再びリミットに近い最高の値を検索しますが、探しているものではありません。後に表示されます!

atan()がどのように動作するかを確認することができます。( これを使用):

図07 ATAN関数

青バージョン(のみ)+1と-1の間に制限。
赤い線(およびその関数)は、x = 0のx軸の切片を移動する方法を示しています。
緑色の線は、勾配を変更する方法を示しています。違いが徐々に小さくなって、極限に近づいて、atan()を制御します。

ここで必要としないことはリミットにatan()バージョンのアプローチを変更することです。しかし、もし例えば、第1*atan(..)から2* atan(..)とするにはリミットが移動します。

1*atanを設定することにより、上限と下限を切り替えます。関数が、-1より大きいのxについて近づいています。

擬似EAの準備ができました。一緒に入れてみましょう。


擬似EA、最終バージョン

擬似EAは取引しません!新しい足のタイミングでiADX(..)を呼び出します。「コントロールポイント」か「全ティック」を必要としません。始値のみの最速のモデルを使用することができます。ADXの前の2足で相場の状態を計算:

extern int                 PER   = 22;             // Adxのの期間
extern ENUM_APPLIED_PRICE  PRC   = PRICE_TYPICAL;  // Adxの価格
extern double              LIM   = 14.0;           //Adxのメール行の制限

extern string            fName   = "";             //\テスター\ファイル、""=>なし、CSVファイル内のファイル名!


//+------------------------------------------------------------------+
//|グローバル変数の定義|
//+------------------------------------------------------------------+
double   OptVal,           //この値はOnTester(によって返されます)、その値を見つけることができます。
         TrndHi,           // 実際のトレンド相場の最高値
         TrndLo,           //実際のトレンド相場の最低値
         TrndBeg,          //トレンド相場のはじめの価格
         TrndRangHL,       //最高値の合計 - トレンド相場の最低
         TrndRangCl,       //最後の終値 - トレンド相場の第1の終わり(左ではなく)
         TrndNum,          //トレンド相場の数
         TrndBars=0.0,     //トレンド相場の足の数
         TrndBarsAvg=0.0,  // トレンド相場の平均の足
         FlatBarsAvg=0.0,  //レンジ相場の平均の足
         FlatHi,           // 実際のレンジ相場の高値
         FlatLo,           // 実際のレンジ相場の最低値
         FlatBeg,          // レンジ相場の先頭価格
         FlatRangHL,       //最高値の合計 レンジ相場の最低値
         FlatRangCl,       //最後のクローズ - レンジ相場の最初のクローズ(左ではなく)
         FlatNum,          //レンジ相場の数
         
FlatBars=0.0,     // レンジ相場の足の数
         FlatRange,        //  tmpののFlatRangHL/ FlatNum
         TrndRange,        //  tmpののTrndRangHL/ TrndNum
         SwitchesRaw,      //切り替え
         SwitchesAtan,     // スイッチの数のATAN
         BrRaw,            //レンジやトレンド、相場の時間(より優れている方)
         BrAtan,           //BrRawa のアタン
         RangesRaw,        //レンジ相場の範囲で割ったトレンド相場(より大きな、より良い方)
         RangesAtan;       // (TrndRange/FlatRange)のAtan

enum __Mkt //相場の3状態
 {
   UNDEF,  
   FLAT,
   TREND
 };
__Mkt MARKET = UNDEF;      //相場の状態

string iName;              //インジケータの名前
double main1,main2;        //Adxののメインラインの値


//+------------------------------------------------------------------+
//|OnTickはインディを計算、相場の状態を判断します| 
//+------------------------------------------------------------------+
void OnTick() 
 {
 //---
   static datetime tNewBar=0;
   if ( tNewBar < Time[0] ) 
    {
      tNewBar = Time[0];
      main1 = iADX(_Symbol,_Period,PER,PRC,  MODE_MAIN, 1); // ADX
      main2 = iADX(_Symbol,_Period,PER,PRC,  MODE_MAIN, 2); // ADX)
      iName = "ADX";

      //VARを設定。適切な相場の状態を定義
      if ( MARKET == UNDEF ) 
       { 
         if      ( main1 < LIM ) main2 = LIM+10.0*_Point; // 相場がレンジ
         else if ( main1 > LIM ) main2 = LIM-10.0*_Point; //相場がトレンド
         FlatHi  = High[0];
         FlatLo  = Low[0];
         FlatBeg = Close[2];//
         TrndHi  = High[0];
         TrndLo  = Low[0];
         TrndBeg = Close[2];//
       }
      
      //レンジ相場に参入しますか?
      if ( MARKET != FLAT && main2>LIM && main1<LIM)  // ADX
       {
         //トレンド相場を確定
         TrndRangCl += fabs(Close[2] - TrndBeg)/_Point;
         TrndRangHL += fabs(TrndHi - TrndLo)/_Point;
                  
         //更新する値
         OptVal = calcOptVal();

         //新しいレンジ相場を設定
         MARKET  = FLAT;
         FlatHi  = High[0];
         FlatLo  = Low[0];
         FlatBeg = Close[1];//
         ++FlatNum;
         if ( IsVisualMode() )
          {
            if (!drawArrow("Flat "+TimeToStr(Time[0]), Time[0], Open[0]-(High[1]-Low[1]), 243, clrDarkBlue) ) // 39:candle market sleeps
               Print("Error drawError ",__LINE__," ",_LastError);
          }
       } 
      else if ( MARKET == TREND )   // 現在のトレンド相場を更新
       {
         TrndHi = fmax(TrndHi,High[0]); 
         TrndLo = fmin(TrndLo,Low[0]); 
         TrndBars++;
       }
      
      //トレンド相場に参入しますか?
      if ( MARKET != TREND && main2<LIM && main1>LIM) 
       { 
         //レンジ相場を確定
         FlatRangCl += fabs(Close[2] - FlatBeg)/_Point;
         FlatRangHL += fabs(FlatHi - FlatLo)/_Point;
         
         //更新する値
         OptVal = calcOptVal();

         //新しいトレンド相場を設定
         MARKET  = TREND;
         TrndHi  = High[0];
         TrndLo  = Low[0];
         TrndBeg = Close[1];//
         ++TrndNum;
         TrndBars++;
         if ( IsVisualMode() )
          {
            if(!drawArrow("Trend "+TimeToStr(Time[0]), Time[0], Open[0]-(High[1]-Low[1]), 244, clrRed)) // 119:kl Diamond
               Print("Error drawError ",__LINE__," ",_LastError);
          }
       } 
      else if ( MARKET == FLAT  ) //現在のレンジ相場を更新
       {
         FlatHi = fmax(FlatHi,High[0]);
         FlatLo = fmin(FlatLo,Low[0]); 
         FlatBars++; 
       }
      
    }
   if ( IsVisualMode() )  //  VisualModeは、実際の状況を示します
    {
      string lne = StringFormat("%s  PER: %i    PRC: %s    LIM: %.2f\nMarket  #   BarsAvg  RangeAvg"+
                                "\nFlat:    %03.f    %06.2f         %.1f\nTrend: %03.f    %06.2f         %.1f   =>  %.2f",
                                 iName,PER,EnumToString(PRC),LIM,FlatNum,FlatBarsAvg,FlatRange,
                                 TrndNum,TrndBarsAvg,TrndRange,(FlatRange>Point?TrndRange/FlatRange:0.0)
      );
      Comment(TimeToString(tNewBar),"  ",EnumToString(MARKET),"  Adx: ",DoubleToString(main1,3),
              "  Adx-Lim:",DoubleToString(main1-LIM,3),"\n",lne);
    }
 }

ADXがクロスする場合は、 LIM以前の相場の状態を確定し、新しいものを用意します。擬似EAはポイントですべての引用の違いを計算します!

そのために何が必要か、見てみましょう。OnTester()の番号が必要です。ストラテジーテスターのオプティマイザは、より良い大きい計算します。OnTester()によって返される値( OptVal)がレンジとトレンド相場の区別が良くなる場合、増やす必要があります!

OptValを計算するために三つの変数を決定しました。2のために合理的な最小値を設定することができます。

  1. RangesRaw= TrndRage/ FlatRangeを1より大きくする必要があります!トレンド相場はレンジな相場よりも高い範囲を指定する必要があります。TrndRageとFlatRangeは、実際の相場の最も低い値として定義されています。x=1でのx軸切片を設定してみましょう。
  2. BrRawは、3つの大きい足(=3時間)でなければなりません。BrRaw=fmin(FlatBarsAvg、TrndBarsAvg).FlatBarsAvgとTrndBarsAvgは、各相場の平均数です。これが境界でa.m.の値を防止する必要があります。x=3で、この切片のx軸を設定してみましょう。
  3. SwitchesRaw. 8000以上の足で最適化しようとしています。例えばわずか20スイッチ(10レンジと10のトレンド相場は)では何の意味もないだろう。

問題は、足の総数に依存するように良好なリミットを見つけることです。妥当性の検討に制限を設定することができた場合、最初の結果を見てタブを取らなければなりません。

図08オプティADX ALLは、グラフィックスを切り替え

〜2500を扱う代わりに、sqrt(2500)=50のクラスを使用します。各クラスに、その平均値を計算し、それをプロットします。172が最低値があることがわかります。この境界を扱う方法を確認するために100を使用してみましょう。100から、この制限から遅い増加を保証するために、0.01の小さな係数を使用します。再び200であるかもしれませんが、上限を使用します。

他の係数を導出するために、関数プロッタを見てみましょう。曲線があまりにもレンジではないように、それらを適応させます。青は、SwitchesRawの機能です。

図9 スイッチのAtan(青)

他の2つの評価関数で、見てみましょう。
赤色はBrRawの関数です。:任意の相場の持続時間の最小3つの足、さらには8つの足(時間)が違いを生む保証の係数です。
緑はRangesRawです。:ここで奇跡を期待することができなかったとして、8つ以上は、おそらく深刻な結果ではないとします。

図10 Atanバー(赤)、レンジ(緑)、スイッチ(青)

OnTester()が値を返す OptValを計算をする関数を構築します。

  1. より良い3つの変数に適用されるように、それらを掛けることができます!
  2. fmax(0.0,atan(..)).:3つの変数で評価する必要がありますので、すべてAtan(..)が負になることがあります。それ以外の場合は、例えば、Atan()の2つの負の結果は関数は、 OptValの正の値になります。
//+------------------------------------------------------------------+
//|calcOptVal OptVal ストラテジーテスターに返す|
//|評価の係数|
//+------------------------------------------------------------------+
// Coeff. SwitchesAtan スイッチの数:
double SwHigh = 1.0, SwCoeff=0.01, SwMin = 100;
// Coeff. BrAtan、NUM。足:
double BrHigh = 1.0, BrCoeff=0.5,  BrMin = 3.0;
// Coeff. for RangesAtan, TrendRange/FlatRange:
double RgHigh = 1.0, RgCoeff=0.7,  RgMin = 1.0;

double calcOptVal() {
   if ( FlatNum*TrndNum>0 ) {
      SwitchesRaw  = TrndNum+FlatNum;
      SwitchesAtan = SwHigh*atan( SwCoeff*(SwitchesRaw-SwMin))/M_PI_2;

      FlatBarsAvg  = FlatBars/FlatNum;
      TrndBarsAvg  = TrndBars/TrndNum;
      BrRaw        = fmin(FlatBarsAvg,TrndBarsAvg);
      BrAtan       = BrHigh*atan( BrCoeff*(BrRaw-BrMin))/M_PI_2;

      FlatRange    = FlatRangHL / FlatNum;
      TrndRange    = TrndRangHL / TrndNum;
      RangesRaw    = FlatRange>0 ? TrndRange/FlatRange : 0.0; 
      RangesAtan   = FlatRange>0 ? RgHigh*atan( RgCoeff*(RangesRaw-RgMin))/M_PI_2 : 0.0;
      return(fmax(0.0,SwitchesAtan) * fmax(0.0,BrAtan) * fmax(0.0,RangesAtan));  
   }
   return(0.0);
}



擬似EAの他の部分は、OnInit()です。

//+------------------------------------------------------------------+
//|エキスパート初期化関数|
//+------------------------------------------------------------------+
int OnInit() 
  {
//---
   // Calc.-シートのヘッダー行
   if ( StringLen(fName)>0 ) {
      if ( StringFind(fName,".csv", StringLen(fName)-5) < 0 ) fName = fName+".csv";    //  ファイル名の確認
      if ( !FileIsExist(fName) ) {                                                     // 新しいファイルのコラムヘッダ
         int fH = FileOpen(fName,FILE_WRITE);
         if ( fH == INVALID_HANDLE ) Print("ERROR open ",fName,": ",_LastError); 
         string hdr = StringFormat("Name;OptVal;RangesRaw;PER;PRC;LIM;FlatNum;FlatBars;FlatBarsAvg;FlatRgHL;FlatRgCls;FlatRange;"+
                      "TrendNum;TrendBars;TrendBarsAvg;TrendRgHL;TrendRgCl;TrendRange;"+
                      "SwitchesRaw;SwitchesAtan;BrRaw;BrAtan;RangesRaw;RangesAtan;FlatHoursAvg;TrendHoursAvg;Bars;"+
                      "Switches: %.1f %.1f %.f, Hours: %.1f %.1f %.1f, Range: %.1f %.1f %.1f\n",
                      SwHigh,SwCoeff,SwMin,BrHigh,BrCoeff,BrMin,RgHigh,RgCoeff,RgMin);
         FileWriteString(fH, hdr, StringLen(hdr));
         FileClose(fH);
      }   
   }
//---
   return(INIT_SUCCEEDED);
  }

OnTester()で、相場状態を確定し、CSVファイルの末尾の最適化の結果を記述:

double OnTester() 
 {
   //ノックアウトリミットを確認:少なくとも一つのスイッチ
   if ( FlatNum*TrndNum<=1 ) return(0.0);  // either one is 0 => skip senseless results
   
   //最後の相場を確定:レンジ
   if ( MARKET == FLAT ) 
    {
      TrndRangCl += fabs(Close[2] - TrndBeg)/_Point;
      TrndRangHL += fabs(TrndHi - TrndLo)/_Point;

      //更新する値
      OptVal = calcOptVal();

    } 
   else if ( MARKET == TREND ) // .. トレンド
    {
      FlatRangCl += fabs(Close[2] - FlatBeg)/_Point;
      FlatRangHL += fabs(FlatHi - FlatLo)/_Point;

      //更新OptVal
      OptVal = calcOptVal();
    }
   
   // CSVファイルに値を書き込みます
   if ( StringLen(fName)>0 ) 
    {
      string row = StringFormat("%s;%.5f;%.3f;%i;%i;%.2f;%.0f;%.0f;%.1f;%.0f;%.0f;%.2f;%.2f;%.0f;%.0f;%.1f;%.0f;%.0f;%.2f;%.2f;%.0f;%.5f;%.6f;%.5f;%.6f;%.5f;%.2f;%.2f;%.0f\n",
                  iName,OptVal,RangesRaw,PER,PRC,LIM,
                  FlatNum,FlatBars,FlatBarsAvg,FlatRangHL,FlatRangCl,FlatRange,
                  TrndNum,TrndBars,TrndBarsAvg,TrndRangHL,TrndRangCl,TrndRange,
                  SwitchesRaw,SwitchesAtan,BrRaw,BrAtan,RangesRaw,RangesAtan,
                  FlatBarsAvg*_Period/60.0,TrndBarsAvg*_Period/60.0,
                  (FlatBars+TrndBars)
             );
             
      int fH = FileOpen(fName,FILE_READ|FILE_WRITE);
      if ( fH == INVALID_HANDLE ) Print("ERROR open ",fName,": ",_LastError);
      FileSeek(fH,0,SEEK_END); 
      FileWriteString(fH, row, StringLen(row) );
      FileClose(fH);
    }
   //Neg. の代わりに0.0を返す。values!最適化のグラフを台無しにします。
   return( fmax(0.0,OptVal) );
 }


擬似EAの準備ができて、最適化のストラテジーテスターを準備します。

  1. すべての組み合わせをテストするために、「遺伝的アルゴリズム」を無効にします。
  2. 「最適化パラメータ」に設定します。最適化グラフでもっと面白い画像を示します。
  3. ..\tester\caches内のキャッシュファイルが削除されていることを確認します
  4. CSVファイルについてfNameが空でないことを確認し、\tester\files内の既存のCSVファイルが削除されます。
  5. CSVファイルのファイル名のままにすると、オプティマイザは、そのサイズによって問題を抱えるまで、大きく追加します!
  6. シンボルはEURUSDを選択します。
  7. 期間は2015年から(H108。2015年11月20日〜13)。
  8. モデルは「始値のみ」に設定。
  9. "最適化"を有効にすることを忘れないでください。

2007からラップトップ上で25分後、ストラテジーテスターは、最適化を完了しました。

最適化グラフでは、参照することができます(下= LIM、右= PER):

図11 TesterGraph SwLim 100

これは最初の最適化よりもずっと良く見えます。34>PER>10 と 25>LIM13、ロットは..、90と4、..、90でずっと優れています。

スイッチの異なる結果が、同様に(=安定した結果を)見えるかどうか確認してみましょう:

SwMin = 50:

図11  TesterGraph SwLim 050

SwMin = 150

図13テスターグラフスリム150

SwMin = 200:

図14  TesterGraph SwLim 200

34>PER>10 and 25>LIM>13 が堅牢です。

注:
  • 3つの変数のOptValを均等にする関数 - Atan(..)を使用する必要がありました。
  • 異なる係数を有するAtan関数は、多かれ少なかれ任意です!満足のいく結果が得られるまで試してみました。自分自身を試してみてください!
  • 望むものを手に入れるまで、数値を変更したと思われるかもしれません。結果を慎重に確認する必要があります。
  • この擬似EAは最高の単一ソリューションを見つけるためのものではありませんが、各パラメータの合理的な小さいリミットを見つけます。最後に、成功はEAによって決定されます!


EXCELで結果を分析し、妥当性チェックします。

最適化中各パスは、利益、取引、利益ファクター、のように必要のないカテゴリをスキップし、ストラテジーテスターの提供よりも多くの情報をCSVファイルに新しい行を追加します... (LibreOffice)Excelで読み込むファイル。

まず、すべてソートする必要があり、 OptVal RangesRaw、その後に応じて、取得(タブ:「ADX SwLim100の最適化」):

図15 最適化ADX SwLim 100

OptValに記載の「最良」の50を見てください。様々なパラメータ PER PRC LIMに着色されています。

  1. RangesRawは、2.9から4.5まで変化します。これはトレンド相場はレンジ相場よりも3倍から4.5より大きい範囲を有することを意味します。
  2. レンジ相場は6〜9足(時間)持続します。
  3. レンジ相場の範囲は357から220ポイントに変わる - レンジ取引の十分なスペース。
  4. このトレンドは、30〜53時間持続します。
  5. トレンド相場は1250から882ポイントの範囲です。
  6. トップ50とトップ200を見れば、範囲がほぼ同じであるRangesRaw:2.5から5.4は、トレンドが範囲221から372の範囲である。:
  7. PERトップ200:14〜20および LIM:14〜20
  8. 一部を見れば OptValが0.0となっている RangesRawの非常に高い値を参照して、他の値は良いものではありません。

図16 OptVal0のスキップ

RangesRawは途方もなく高いが、FlatBarsAvgはトレードが短すぎるTrndBarsAvgは、1000時間と高すぎます。

一部のRangeRawをチェックし、 OptValその範囲に応じてソート(タブ:"OptVal>0 ソートRangesRaw」):

図17 OptVal gt 0 ソート RangesRaw

20から11までの範囲のRamgesRawの50の最高値。しかし、TrendBarsAvgを見てください。:100周りの平均では、4日間以上です。

合計で、 OptValは、すべてのADXの結果を切り下げました。一方、トップ200(5.4)またはトップ500(7.1)の高値RangesRawは非常に有望に見えます。



パラメータチェック

したがって、パラメータを見てADX PER PRCとその LIMリミットに妥当性をチェックします。

多くの行(=29106)に OptValが0よりも大きい行を必要としています。テーブルでは、これらは、最初の4085行です。to OptVal!). 新しいタブでそれらをコピーします。そこでは、 PERの横に3つの列を追加し、この画像に応じて追加します。すべての数式は、添付ファイルで見ることができます。

列D、E、Fの5行目のように、次のように入力します。AVERAGE(D$2:D5), StdDev(D$2:D5), SKEW(D$2:D5).。行2のセルが唯一の全RangesRawの統計結果であり、最後の行の値を示しています。なぜでしょう?テーブルには、ベストからワーストの順番に、nラインに平均、標準偏差、最高のn個の歪度が表示されます。探しているものを見つけられるすべての結果で最高のn値を比較します(タブ:"OptVal>0 チェックPER、PRC、LIM」):

図18 OptVal gt 0 PER、PRC、LIM

このことから何を学ぶことができるでしょう?2行目(lastの下)で、すべてのPERの平均値(Avg)は33.55標準偏差(StdDev)21.60であることがわかります。 PERは、ガウス分布に従って分布しているすべての値の68% PERを見つけます。33.55 - 21.60 = 11.95 及び 33.55 + 21.60 = 55,15 - ここでは、33.55の間です。行を見てください。平均は、5行目では19から始まり、ゆっくりと20に増加します。StdDevは2.0から2.6に変更します。今、68%が23から18までカバーしています。最後に、歪度を見てください。すべてのPERの行2で0.61です。つまり、左側が(小さい)ガウス分布であっても右側よりも多くの値を有することを意味します。歪度が+/-1.96を超えた場合、ガウス分布を仮定することはできませんし、平均と標準偏差を使用には注意する必要があります。一方の側が極端であるということは、他の側は多かれ少なかれ「空」であるが「太りすぎ」ということになります。歪度の大きさは、右側(>平均)が右側よりも小さい値を有することを意味します。よって PERはガウス分布であり、平均とStdDevを使用することができます。上位の結果を比較すると( OptVal)平均が19から20までゆっくりと上昇していることがわかります(行487!)。StdDevは、2.0から5.36に(行487)増加します。最初の10の結果をスキップする場合は、歪度は決して0.4を超えていないし、平均の左側にある1(または2)の値を追加する必要があることを意味しています。

PRCの結果は異なって処理されなければなりません! PERおよび LIM以外の PRCの値は、スケールを定義し、それらの間の計算が無意味になります。よって、表示される回数をカウントし、 RangesRawの平均値を計算します。とんでもないセットを確認しようとしたことを覚えておいてくださいあ。通常、PRC=Open (1), PRC=High (2) or PRC=Low (3).を使用することはありません(。しかし、始値、トップ50の中で最も頻度の高い値であることを認識する必要があります。これはおそらく、全体の足を使用することに起因し、ADXの用途として不適切な種類です。高値と安値で成功するでしょうか?説明するのは難しいです!EURUSDは8月に1.33から低下しているという事実1.08 2014年12月中2015年には、安値の成功が説明されるかもしれません。おそらく強力な相場力学の結果です。とにかく、それらをフェードアウトします。PER = Close, Typical, Median、 Weighted を比較して、大きな差はないことが分かりました。Q,R,Sを見たときにそういえます。トップ100のPRC=Typical(4) は、PRC=High(2)よりも最適な選択です。しかし、トップ500のうち、PRC=Closeはベストとなっています。

LIMに PERと同じ数式を使用しています。興味深いのは、最後の歪度は、(すべての)方法上記1.96ではないために、トップ100(=0.38)またはトップ500(=0.46)のものであることです。それでは、最高の500を使用してみましょう。トップ500の平均値は16.65であり、StdDev3.03。もちろん、この LIMは、 PERに依存しています。: PER LIM LIMの範囲はPER の範囲に対応します。

だから三つの変数の範囲を選択し、 PER PRC、および LIMの500の結果:

  • PER Avg=20.18 +/- StdDev=5.51 Skew=0.35 (-2) => (20.18-5.41-2=) 14,..,(20.18+5.52=) 26 (Step 1 => 13).
  • PRC唯一近い(ステップ0=>1)で決めることができます。
  • LIM Avg=16.64 +/- StdDev=3.03 Skew=0.46 (-2) => (16.64-3.03-2=) 12,..,(16.64+3.03=) 20 (Step 1 => 9)

合計で、その最適化は13*1*9=117の組み合わせがあります。

結果を詳しく見ることができます(シートのタブ名「OPT Top 500 Best PER's Average」):

図19 OPTトップ500ベストPERの平均

PER=18がトップ500と PER=22で最も頻繁にあります。両方とも、 LIMで覆われています。


ビジュアルモード

最終的に確認してみましょう PERトップ500の最高の平均と: PER=22。選択解除 PRC=Open,Low,High これは行38で4.48の範囲の関係、タブの前の画像で黄色の背景で設定を見つけます。

同じ設定でADXを適用してビジュアルモードで疑似EAを実行します。

ビジュアルモードでは、擬似EAはレンジ相場が検出された次の足から、トレンドの場合は赤上下矢印で青左右の矢印を置く:。2015年7月30日5時。2015年8月4日12時00分):

図22 ビジュアルモードPer22

明らかにこのアイデアを向上させるADXの二つの問題があります。

  1. 大きな変化があった場合、ADXはレンジ相場の検出が遅れます。再び「落ち着く」ことは非常に長い時間を必要とします。レンジ相場は約2015年8月3日0時00分ではなく、2015年8月3日09:00検出されたならば、素晴らしいでしょう。
  2. ADXが LIM近い場合、やすやすと仕上げることができます。2015年8月3日14:00にトレンド相場を検出することができた場合、もっと良かったはずです。
  3. ハイローレンジが小さくなった場合、小さな推移でさえトレンドとして認識されてしまいます。トレンドは2015年8月4日7時00分の周りに、後に検出された場合は、2015年8月3日20.00で新しいトレンドとできればもっと良かったはずです。
  4. 擬似EAは上昇トレンドまたは下降トレンドを区別しません。例えば、 DI+とDI-のインジケーターを使用します。
  5. トレンド相場(46.76)の平均長とすると4日間は長すぎる可能性があります。この場合、SwLim(100の代わり)または小さいSwCoeff(0.01の代わり)は、より良いアイデアを満たす結果が得られます。
独自のインジケーターや、より良い検出のインジケーターのセットをコーディングするための5つの明確な出発点です。ADXを使用することができます。自身の擬似EAを簡単にレンジやトレンド相場の定義を修正することができます。!



結論

EAは、54201の組み合わせをテストしなければならないADXを使用しています。EAが期待しているほど成功しなかった場合、改善する問題に対処することは困難です。ADXの54201のすべての組み合わせに数分だけ必要とすることが判明しました:

  1. ADXはレンジとトレンド相場とを区別することが可能です
  2. 54201から117(=13(PAR)*1(PRC)*9(LIM))に削減することができました。
  3. レンジ相場の範囲は、372と220ポイント(上位100)の間にあります。
  4. トレンド相場の範囲は、1277と782ポイントです。

EAの組み合わせを(117*40,000=) 4,680,000から2,168,040,000減らすことができます。これはほんの0.21パーセントであり、どちらかの99.7%速くなったり、EAの他の非ADXパラメータのより多くのバリエーションがチェックされますので、遺伝的最適化の場合には良くなります。擬似EAの縮小設定がありました。

図21 ストラテジーテスターセットアップEAのオプションの減少

図22 StratTesterセットアップの最適化縮小

さらに、トレードをする基準、決済する基準、ストップやターゲットなどの基準に関する貴重な情報を得ることができました。

擬似EAおよび添付のExcelファイルを見てください。すべてのステップを取るということを説明しました。EAでそれらを使用する前に、独自に最適化されたインジケーターを見つけて開始します。インジケーターの組み合わせが優れているかどうかを確認するために、ADXを使用して結果を比較し、レンジやトレンド相場を検出する独自の方法を開発しました。

より良いインジケーターの設定を見つけるために使用する場合は、calcOptValの係数を調整する必要があります。例えば。より長い期間を使用したい場合は、少なくともSwMinを増やす必要があります。良いOptValは、複数の組み合わせのうち、最良のセットアップを見つけるために遺伝的アルゴリズムを有効にします。しかし、インジケーターとは完全に異なる最適化でもこのアイデアを使うことができます。その場合、calcOptVal()関数を書き換えることを余儀なくされる可能性があります。

これでEAを扱いたい場合は、忘れないでください:

  1. ..\tester\caches のキャッシュファイルが必ず削除されたいることか確認してください。
  2. ..\tester\files\のCSVファイルが必要な場合、fNameのためのファイル名を入力し、既存のCSVファイルを削除します。
  3. CSVファイルを使用しない場合、擬似設定のfNameをしておきます。
  4. CSVファイルのファイル名を残す場合は、そのサイズの問題を抱えているまで、オプティマイザは行ずつ追加します!
  5. 最適化パラメータ"テスター"タブの"カスタム"を設定します。
  6. OptValと遺伝的アルゴリズムに影響を与える最も簡単な方法は、3つの係数の最小値を変化させることである。 SwMin, BrMin, RgMin
  7. 「モデル」"始値のみ"を設定します。これが最速です。
  8. 異なる日付を使用している場合("Use Date" : From..To) 、calcOptVal()関数の係数を調整する必要があります。
  9. 最適化が完了した後、「最適化結果」タブから設定を選択し、アイデアを満たしているかどうか確認するために、「ビジュアルモード」で再びテストします。
  10. 青い左右の矢印はレンジ相場のスタートで、赤い上下の矢印はトレンド相場のはじまりです。
  11. ADXのより良い代替手段を開発する場合、CSV-ファイルを必要としないかもしれません:ただし「ビジュアルモード」で最高の結果を見て、何かを変えるかもしれません。
  12. レンジ相場かトレンド相場にたいする疑問にはCSVファイルか OptValを計算する他の方法が必要かもしれません。

しかし、成功の保証がないことを覚えておいてください。


MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/2118

添付されたファイル |
otimIndi_Publ.mq4 (13.4 KB)
トレーダーライフハック:テスト中の資産、ドローダウン、負荷と目盛りインジケータ トレーダーライフハック:テスト中の資産、ドローダウン、負荷と目盛りインジケータ
テストプロセスをどのように視覚的に作ることができるでしょう?答えは簡単です:ストラテジーテスターでドローダウン・預金・負荷のインジケーターを含むティック・インジケータ、バランスインジケーターを使用します。このソリューションは、ティック、相場変化、ドローダウン、資産、負荷を視覚的に追跡するのに役立ちます。
グラフィカルインタフェースVIII: ツリービューコントロール(チャプター2) グラフィカルインタフェースVIII: ツリービューコントロール(チャプター2)
前のグラフィカルインターフェイス第八部では静的およびドロップダウンカレンダー要素に焦点が当てられました。この第2章は、グラフィカルインタフェースを作成するために使用されるすべての完全なライブラリーに含まれているツリービューという均等に複雑な要素に焦点を当てます。本稿で実装されるツリービューは複数の柔軟な設定とモードを含み、ニーズに合わせてコントロール要素を調整することができます。
グラフィカルインタフェースVIII: ファイルナビゲータコントロール(チャプター3) グラフィカルインタフェースVIII: ファイルナビゲータコントロール(チャプター3)
シリーズの第八部の前章では、ライブラリがマウスポインタ、カレンダー、ツリービューを開発するためのいくつかのクラスによって強化されました。本稿は、MQLアプリケーションのグラフィカルインターフェースの一部として使用できるファイルナビゲーターコントロールを扱います。
グラフィカルインタフェースVIII:カレンダーコントロール(チャプター1) グラフィカルインタフェースVIII:カレンダーコントロール(チャプター1)
このMetaTraderでのグラフィカルインタフェースの作成に専念した記事シリーズの第八部では、カレンダー、ツリービュー、およびファイルナビゲーターのような複雑な複合コントロールが検討されます。情報が大量のため、それぞれは個別の記事に書かれています。この部分の最初の章では、カレンダーコントロールとその拡張バージョンであるドロップダウンカレンダーに ついて説明します。