バックテストで問題が見つかり、根本的な原因がわからない! - ページ 5

 
jollydragon:

.やはり峰が消えるのはダメなんですね。どうすれば「再初期化」できるのでしょうか?

再初期化には、タイムフレームを変更する方法と

または

インジケータ入力ウィンドウを開き、OKをクリックする。

 

グムライ2015.05.14 21:51#

You can re-initialise by either changing timeframes

or

インジケータ入力ウィンドウを開き、OKをクリック


試した結果、ピークの位置が変わると言ったのと同じ意味だと理解しています。正しいですか?

GumRai さんへ

 
WHRoeder:

すべての反復処理で、(最初を除いて)Fish 1は前のバッファ要素の値ですが、ExtBuffer1[limit] に初期化しません。

つまり、最初の反復処理(limit == barsのとき)には、ExtBuffer1[0] = 1.1*ExtBuffer1[1] を設定します。

しかし、その後のティックでは(limit == 1のとき)ExtBuffer1[0] = 1.1*0.00001 に設定されます。

WHRoederさんへ。

ありがとうございます!あなたの指示で問題が少しよくわかりました。

しかし、さらに明確にするために、まだいくつかの質問が必要な場合があります。

1.1. "double Fish1=0.00001;" は、すべての関数の最初と最後に定義されているのがお分かりになると思います。

これはグローバル変数で、新しいティックが来ても最後のExBuffer1[0]に代入されていると理解しています。

それとも、新しいティックが来るたびに自動的に "0.00001 "にリカバリするのでしょうか?

2.2.各バーは1ティックまたは多くの後続ティックで異なるように描画されますが、なぜライブM1チャートで...、bar[8]、...、bar[1]の再描画を中断することなく見ることができるのでしょうか?

3.リフレッシュされた後、ピークの位置が変わってしまうのはなぜですか?

4.M1ライブチャートで、"EMPTY_VALUE"(2147483647)よりも少ないピーク(約959870576)が形成されるのは何故ですか?

5.新しいバーが出ると、前のExtBuffer1[0]が自動的にExtBuffer1[1]に変更されます。正しいですか?

6.6. 再初期化や再描画の可能性を防ぐにはどうしたらいいでしょうか?

多分、私はまだいくつかの重要な点で混乱しているので、あなたの偉大な忍耐力が必要です。1つ1つ質問に答えていただけると助かります。

 

WHRoeder,GumRai さんへ

再度投稿を拝見し、私の理解に従い、下記のコードのように私のインジケータを更新しました。

バックテストに使ってみたところ、結果はインジケータとかなり一致するようになりました。しかし、まだ2つの問題があります。以下のスクリーンショットを参照してください。

1.1.最初の注文から4つのインジケータのシグナルが出た後に取引が行われる。

2.2.インディケーターシグナルの4小節前にまだ1つの注文変更が起こっている。

以下は、更新されたインジケータコードです。

#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.50"
#property strict
#property  indicator_separate_window
#property  indicator_buffers 2

extern int    period=35;
extern double smooth=0.3;

datetime       lastAlertTime;
double         ExtBuffer0[];
double         ExtBuffer1[];
double         ExtValue[];
double         Value1=0,Buffer0_1=0;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   IndicatorBuffers(3);
   SetIndexBuffer(0,ExtBuffer0); SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,1,clrWhiteSmoke);
   SetIndexBuffer(1,ExtBuffer1); SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,1,clrGoldenrod);
   SetIndexBuffer(2,ExtValue);
   IndicatorShortName(" Solar Joy   ^v^  ");
   ArraySetAsSeries(ExtBuffer0,true);
   ArraySetAsSeries(ExtBuffer1,true);
   ArraySetAsSeries(ExtValue,true);

   SetIndexDrawBegin(1,period);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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(rates_total<=period)    return(0);

   int    i,limit;
   double price,MinL,MaxH;

   if(prev_calculated<rates_total-1) limit=rates_total-period-1;
   else                              limit=1;

   for(i=limit-1; i>=0; i--)
     {
      MaxH = High[iHighest(NULL,0,MODE_HIGH,period,i)];
      MinL = Low[iLowest(NULL,0,MODE_LOW,period,i)];
      price=(High[i]+Low[i])/2;
      if(limit==1)
        {
         Value1=ExtValue[1];
         Buffer0_1=ExtBuffer0[1];
        }
      ExtValue[i]=(1-smooth)*(2*(price-MinL)/(MaxH-MinL)-1.0) + smooth*Value1;
      ExtValue[i]=MathMin(MathMax(ExtValue[i],-0.999),0.999); // Value=Value>0.999?0.999:Value<-0.999?-0.999:Value;
      ExtBuffer0[i]=(1-smooth)*MathLog((1+ExtValue[i])/(1-ExtValue[i]))+smooth*Buffer0_1;
      Value1=ExtValue[i];
      Buffer0_1=ExtBuffer0[i];
      if(ExtBuffer0[i]>0) ExtBuffer1[i]=3;
      else ExtBuffer1[i]=-3;
     }

   return(rates_total);
  }
//+------------------------------------------------------------------+

 
jollydragon:

1.double Fish1=0.00001;" は、すべての関数の先頭と末尾に定義されています。

ということは、グローバル変数で、新しいティックが来ても最後のExBuffer1[0]が代入されていると理解していいのでしょうか?

それとも、新しいティックが来ると、毎回自動的に "0.00001 "に回復するのでしょうか?

いいえ、違います。しかし、ExtBuffer1[limit] に初期化しない」のどの部分が不明だったのでしょうか?
if(prev_calculated<rates_total-1){ limit=rates_total-period-1; Fish1=0.00001;       }
else                             { limit=1;                    Fish1=ExtBuffer0[1]; }
for(i=limit-1; i>=0; i--)
  {
   ExtBuffer1[i]=1.1*Fish1;
   Fish1=ExtBuffer1[i];
   if(Fish1>=EMPTY_VALUE)
      Fish1=1;
  }

個人的には、チャート/バッファは時系列なので、rates_total/prev_calculated/OnCalculateの引数は忌々しいと思い、旧来の方法でやってしまいますね。
int counted = IndicatorCounted();
limit = Bars - MathMax(counted, period-1); // Lookback period-1
Fish1 = counted == 0 ? 0.00001 : ExtBuffer0[limit];
for(i=limit-1; i>=0; i--)