iBandsで取得したインジケーターの値とデータウィンドウ表示の値が異なる

 

iBands関数を使って取得した ボリンジャーバンド の値(Upper/Lower/Middle)とデータウィンドウで表示されている値が異なります。

原因わかる方教えて頂けないでしょうか。

以下、ソースコード抜粋です。

int OnInit(void)

  {
//--- prepare trade class to control positions if hedging mode is active
   ExtHedging=((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING);
   ExtTrade.SetExpertMagicNumber(MA_MAGIC);
   ExtTrade.SetMarginMode();
   ExtTrade.SetTypeFillingBySymbol(Symbol());
   
   
   bb_handle=iBands(_Symbol,_Period,e_bands_period,e_bands_shift,e_deviation,e_applied_price);
   macd_handle=iMACD(_Symbol,_Period,MACD_fast_ema_period,MACD_slow_ema_period ,MACD_signal_period,MACD_applied_price);

//--- Moving Average indicator
   if(ExtHandle==INVALID_HANDLE)
     {
      printf("Error creating MA indicator");
      return(INIT_FAILED);
     }
//--- ok
   return(INIT_SUCCEEDED);
  }
  
//+------------------------------------------------------------------+
//| shorエントリー                               |
//+------------------------------------------------------------------+
void CheckForSell(int handle)
   {
//--- BB
   double         UpperBuffer[];
   double         LowerBuffer[];
   double         MiddleBuffer[];
   ArraySetAsSeries(MiddleBuffer,true);
   CopyBuffer(handle,0,0,1,MiddleBuffer);
   ArraySetAsSeries(UpperBuffer,true);
   CopyBuffer(handle,1,0,1,UpperBuffer);
   ArraySetAsSeries(LowerBuffer,true);
   CopyBuffer(handle,2,0,1,LowerBuffer);
   

//--- 
   double L[];
   double H[];
   ArraySetAsSeries(L,true);
   CopyLow(_Symbol,_Period,0,1,L);
   ArraySetAsSeries(H,true);
   CopyHigh(_Symbol,_Period,0,1,H);

   MqlRates rt[2];
   
//--- go trading only for first ticks of new bar
   if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return;
     }
   if(rt[1].tick_volume>1)
      return;
   
   //ohlc とbb値出力
   Print("ohlc");
   Print("rt[0].open:",rt[0].open);
   Print("rt[0].high:",rt[0].high);
   Print("rt[0].low:",rt[0].low);
   Print("rt[0].close:",rt[0].close);
   Print("Bollinger Band value");
   Print("UpperBuffer[0]:",UpperBuffer[0]);
   Print("MiddleBuffer[0]:",MiddleBuffer[0]);
   Print("LowerBuffer[0]:",LowerBuffer[0]);

//--- check signals
   ENUM_ORDER_TYPE signal=WRONG_VALUE;

//**~途中略~**//

//--- additional checking
   if(signal!=WRONG_VALUE){
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
         ExtTrade.PositionOpen(_Symbol,signal,TradeSizeOptimized(),
                               SymbolInfoDouble(_Symbol,signal==ORDER_TYPE_SELL ? SYMBOL_BID:SYMBOL_ASK),
                               sl,0);
       }
 }


//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(void)
  {
  double iClose1[1],iClose2[1];
  static bool Recount1=true,Recount2=true;
  static CIsNewBar NB1,NB2; 
   
      
   if(NB2.IsNewBar(Symbol(),PERIOD_H1) || Recount2){ // 新しいバーをチェック
      Recount2=false;
      //---- 新しく出現したデータを配列にコピーする
      if(CopyClose(Symbol(),PERIOD_H1,1,1,iClose2)<=0) {Recount2=true; return;}
      /* 取引シグナル2を受信するブロックのコード */      
         //取引処理
         if(SelectPosition()){
            CheckForClose();
         }
         else{
               CheckForSell(bb_handle);
         }
      }
}
 

単純化して比較してみましたが全く違いはありません。

ところで、指標バッファではなく、ただの配列なのになぜ ArraySetAsSeries を使っているのですか?

それに、どうせ1データしかコピーしないのだから 

double         MiddleBuffer[1];

でいいのでは?

 

NewBar チェックをしているのに、コピーしているデータは0番だからこの辺で違いが出てるんじゃないの?

動作テストできないから分からないけど。

 
Nagisa Unada:

単純化して比較してみましたが全く違いはありません。

ところで、指標バッファではなく、ただの配列なのになぜ ArraySetAsSeries を使っているのですか?

それに、どうせ1データしかコピーしないのだから 

でいいのでは?

Nagisa Unadaさん

比較してみて頂いたとのこと回答ありがとうございます。

違いはないのですね。

ArraySetAsSeriesを使っているのは、参考にしたコードで使っていたためで、おっしゃる通りMiddleBuffer[1]で事足りますね。

 

>NewBar チェックをしているのに、コピーしているデータは0番だからこの辺で違いが出てるんじゃないの?

ご指摘の通りでした。

ありがとうございました。

CopyBuffer(handle,0,0,2,MiddleBuffer);

Print("UpperBuffer[0]:",UpperBuffer[0]);

としたら、同じ値になりました。

(一応、今の足の値も取るようにしてます。)

 
CopyBuffer(handle,0,0,2,MiddleBuffer);

Print("UpperBuffer[0]:",UpperBuffer[0]);

これは単純な間違いですか?


NewBar チェックをしている場合、新しいバーが出現した直後に1度だけ実行することになり、その後の価格の変動が反映されません。

ですから通常は0番ではなく、値の確定している1番のデータを使います。値に差異が出たのもそのためではないかと思ったんですが、0番のデータで問題ないんですか?


 
Nagisa Unada:

これは単純な間違いですか?


NewBar チェックをしている場合、新しいバーが出現した直後に1度だけ実行することになり、その後の価格の変動が反映されません。

ですから通常は0番ではなく、値の確定している1番のデータを使います。値に差異が出たのもそのためではないかと思ったんですが、0番のデータで問題ないんですか?


おっしゃる通りで、0番のデータを使ったことが差異の原因でした。

Printで"UpperBuffer[0]"としていたのは単純なコメント記載間違いです。。

実際の処理では、MiddleBuffer[1]として1番目のデータを使いました。

CopyBuffer(handle,0,0,2,MiddleBuffer);
Print("MiddleBuffer[1]:",MiddleBuffer[1]);


理由: