ボリンジャーバンドの角度によってトレンドを判断するヒストグラムインジケーター
今回はボリンジャーバンドを活用したヒストグラムインジケーターを作成したいと思います。
ヒストグラムインジケーターは難しそうだと感じますが、
実は仕組みさえ理解してしまえばそれほど難しくはありません。
今回のロジックは、
- ボリンジャーバンドの上バンドと下バンドが上向き:上昇
 - ボリンジャーバンドの上バンドと下バンドが下向き:下降
 - ボリンジャーバンドの上バンドと下バンドの向きが水平:レンジ
 
という形で作成したいと思います。
メタエディタ(MetaEditor)を立ち上げる
メタエディタ(MetaEditor)を立ち上げましょう。操作は以下に記載しています。

今回は名前を「Bollinger-band-Histogram」で作成します。
プロパティを記述する
プロパティを記述しましょう。
サブウィンドウに表示するのでseparate_windowに設定しましょう。
#property indicator_separate_window
バッファは上昇トレンド、下降トレンド、レンジの3つになります。
#property indicator_buffers 3//バッファ3つ
色は上昇トレンドは緑色、下降トレンドは赤色、レンジは黄色に設定しましょう。
#property indicator_color1 Blue//緑色 #property indicator_color2 Red//赤色 #property indicator_color3 Yellow//黄色
幅は2に設定します。
#property indicator_width1 2//幅2 #property indicator_width2 2//幅2 #property indicator_width3 2//幅2
ウィンドウの最大サイズを1に最小サイズを0に設定します。
#property indicator_maximum 1//指標ウィンドウの最大サイズ #property indicator_minimum 0//指標ウィンドウの最小サイズ
これでプロパティの記述は完了です。
#property indicator_separate_window #property indicator_buffers 3//バッファ3つ #property indicator_color1 Blue//緑色 #property indicator_color2 Red//赤色 #property indicator_color3 Yellow//黄色 #property indicator_width1 2//幅2 #property indicator_width2 2//幅2 #property indicator_width3 2//幅2 #property indicator_maximum 1//指標ウィンドウの最大サイズ #property indicator_minimum 0//指標ウィンドウの最小サイズ
バッファを定義する
バッファを定義しましょう。
上昇トレンドをUP[]、下降トレンドをDOWN[]、レンジをEVEN[]に設定します。
double UP[];//上昇 double DOWN[];//下降 double EVEN[];//レンジ
これでバッファを定義は完了です。
double UP[];//上昇 double DOWN[];//下降 double EVEN[];//レンジ
パラメーターを記述する
パラメーターを記述しましょう。
ボリンジャーバンドの期間を決められるように設定しましょう。
input int BBands_Period = 20;//ボリンジャーバンドの期間
これで、パラメーターを記述は完了です。
input int BBands_Period = 20;//ボリンジャーバンドの期間
OnInit()関数に記述する
OnInit()関数に記述しましょう。
それぞれのインデックスに紐付けします。
SetIndexBuffer(0,UP);//インデックス0にUPを紐付け SetIndexBuffer(1,DOWN);//インデックス1にDOWNを紐付け SetIndexBuffer(2,EVEN);//インデックス2にEVENを紐付け
今回のキモです。
サブウィンドウにヒストグラムを表示させたいのでインデックスをヒストグラムに設定しましょう。
SetIndexStyle(0,DRAW_HISTOGRAM);//インデックス0をヒストグラムに SetIndexStyle(1,DRAW_HISTOGRAM);//インデック1をヒストグラムに SetIndexStyle(2,DRAW_HISTOGRAM);//インデックス2をヒストグラムに
これでOnInit()関数の記述は完了です。
SetIndexBuffer(0,UP);//インデックス0にUPを紐付け SetIndexBuffer(1,DOWN);//インデックス1にDOWNを紐付け SetIndexBuffer(2,EVEN);//インデックス2にEVENを紐付け SetIndexStyle(0,DRAW_HISTOGRAM);//インデックス0をヒストグラムに SetIndexStyle(1,DRAW_HISTOGRAM);//インデック1をヒストグラムに SetIndexStyle(2,DRAW_HISTOGRAM);//インデックス2をヒストグラムに
OnCalculate()関数に記述する
OnCalculate()関数に記述すしましょう。
int limit = Bars - IndicatorCounted();//未だ計算されていないバー数(チャート上のバー数 - 計算済みバー数)
for文で繰り返し設定します。
for(int i = limit-1; i>=0; i--)
配列の中身を0にしましょう。
UP[i]=0;//UP配列の値を0に DOWN[i]=0;//DOWN配列の値を0に EVEN[i]=0;//EVEN配列の値を0に
ボリンジャーバンドの上バンドの現在の値と一つ前の値を取得します。
iBands関数については以下の記事を参照してください。

double BB_up = iBands(NULL, 0, BBands_Period, 2, 0, PRICE_CLOSE, 1, i);//現在の上バンド double BB_up1 = iBands(NULL, 0, BBands_Period, 2, 0, PRICE_CLOSE, 1, i+1);//過去の上バンド
そして次に下バンドの現在の値と一つの前の値を取得します。
double BB_low = iBands(NULL, 0, BBands_Period, 2, 0, PRICE_CLOSE, 2, i);//現在の下バンド double BB_low1 = iBands(NULL, 0, BBands_Period, 2, 0, PRICE_CLOSE, 2, i+1);//過去の下バンド
もしBB_up1よりBB_upのほうが大きく、BB_low1よりBB_lowが大きい場合にUP[i]を1にします。
if(BB_up1 < BB_up && BB_low1 < BB_low) UP[i] = 1;//もしBB_up1よりBB_upのほうが大きく、BB_low1よりBB_lowが大きい場合にUP[i]を1にする
もしBB_up1よりBB_upのほうが小さく、BB_low1よりBB_lowが小さい場合にDOWN[i]を1にします。
else if(BB_up1 > BB_up && BB_low1 > BB_low) DOWN[i] = 1;//もしBB_up1よりBB_upのほうが小さく、BB_low1よりBB_lowが小さい場合にDOWN[i]を1にする
違えばEVEN[i]を1にします。
else EVEN[i] = 1;//違えばEVEN[i]を1にする
これでOnCalculate()関数の記述は完了です。
  int limit = Bars - IndicatorCounted();//未だ計算されていないバー数(チャート上のバー数 - 計算済みバー数)
   for(int i = limit-1; i>=0; i--) 
   {
      UP[i]=0;//UP配列の値を0に
      DOWN[i]=0;//DOWN配列の値を0に
      EVEN[i]=0;//EVEN配列の値を0に
      
      double BB_up = iBands(NULL, 0, BBands_Period, 2, 0, PRICE_CLOSE, 1, i);//現在の上バンド
      double BB_up1 = iBands(NULL, 0, BBands_Period, 2, 0, PRICE_CLOSE, 1, i+1);//過去の上バンド
      double BB_low = iBands(NULL, 0, BBands_Period, 2, 0, PRICE_CLOSE, 2, i);//現在の下バンド
      double BB_low1 = iBands(NULL, 0, BBands_Period, 2, 0, PRICE_CLOSE, 2, i+1);//過去の下バンド
      
      if(BB_up1 < BB_up && BB_low1 < BB_low) UP[i] = 1;//もしBB_up1よりBB_upのほうが大きく、BB_low1よりBB_lowが大きい場合にUP[i]を1にする
      else if(BB_up1 > BB_up && BB_low1 > BB_low) DOWN[i] = 1;//もしBB_up1よりBB_upのほうが小さく、BB_low1よりBB_lowが小さい場合にDOWN[i]を1にする
      else EVEN[i] = 1;//違えばEVEN[i]を1にする
   }コンパイルする
コンパイルしましょう。サブウィンドウに表示されていれば完了です。

しっかりとバンドの角度によって色が変わっていることが確認できたらOKです。

ソースコード全体
Bollinger-band-Barのソースコード全体は以下に記載しています。
//+------------------------------------------------------------------+
//|                                     Bollinger-band-Histogram.mq4 |
//|                     Copyright 2020, FX-EA System Project Creator |
//|                        https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, FX-EA System Project Creator"
#property link      "https://creator.fx-ea-system-project.com/"
#property version   "1.00"
#property strict
/*プロパティ*/
#property indicator_separate_window
#property indicator_buffers 3//バッファ3つ
#property indicator_color1 Blue//緑色
#property indicator_color2 Red//赤色
#property indicator_color3 Yellow//黄色
#property indicator_width1 2//幅2
#property indicator_width2 2//幅2
#property indicator_width3 2//幅2
#property indicator_maximum 1//指標ウィンドウの最大サイズ
#property indicator_minimum 0//指標ウィンドウの最小サイズ
/*バッファ*/
double UP[];//上昇
double DOWN[];//下降
double EVEN[];//レンジ
/*パラメーター*/
input int BBands_Period = 20;//ボリンジャーバンドの期間
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,UP);//インデックス0にUPを紐付け
   SetIndexBuffer(1,DOWN);//インデックス1にDOWNを紐付け
   SetIndexBuffer(2,EVEN);//インデックス2にEVENを紐付け
   SetIndexStyle(0,DRAW_HISTOGRAM);//インデックス0をヒストグラムに
   SetIndexStyle(1,DRAW_HISTOGRAM);//インデック1をヒストグラムに
   SetIndexStyle(2,DRAW_HISTOGRAM);//インデックス2をヒストグラムに
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
   int limit = Bars - IndicatorCounted();
   for(int i = limit-1; i>=0; i--) 
   {
      UP[i]=0;//UP配列の値を0に
      DOWN[i]=0;//DOWN配列の値を0に
      EVEN[i]=0;//EVEN配列の値を0に
      
      double BB_up = iBands(NULL, 0, BBands_Period, 2, 0, PRICE_CLOSE, 1, i);//現在の上バンド
      double BB_up1 = iBands(NULL, 0, BBands_Period, 2, 0, PRICE_CLOSE, 1, i+1);//過去の上バンド
      double BB_low = iBands(NULL, 0, BBands_Period, 2, 0, PRICE_CLOSE, 2, i);//現在の下バンド
      double BB_low1 = iBands(NULL, 0, BBands_Period, 2, 0, PRICE_CLOSE, 2, i+1);//過去の下バンド
      
      if(BB_up1 < BB_up && BB_low1 < BB_low) UP[i] = 1;//もしBB_up1よりBB_upのほうが大きく、BB_low1よりBB_lowが大きい場合にUP[i]を1にする
      else if(BB_up1 > BB_up && BB_low1 > BB_low) DOWN[i] = 1;//もしBB_up1よりBB_upのほうが小さく、BB_low1よりBB_lowが小さい場合にDOWN[i]を1にする
      else EVEN[i] = 1;//違えばEVEN[i]を1にする
   }
   return(rates_total);
}






コメント