チャートで価格が、ボリンジャーバンドの+2σや-2σのラインをタッチし続けて動くバンドウォーク。MQL4で、バンドウォークを検知する関数を作ってみました。
バンドウォークとは?
ボリンジャーバンドで、2σ、もしくは-2σのラインに沿って、価格が推移する値動きの事をバンドウォークと呼びます。バンドウォークが発生する時は、ボリンジャーバンドが狭い所から急に広がるエクスパンションと呼ばれる現象が発生しやすくなります。

バンドウォークのアルゴリズムの基本
結構、簡単かと思ったんですが、実際に組んでみると
例外ケースを考えると、難しい。というか、奥が深い。
正常ケースはシンプル
例えば、上側のボリンジャーバンド2σのラインにタッチし続けるケースは
- 1本前の終値 > 1本前のボリンジャーバンド+2σ
- 2本前の終値 > 2本前のボリンジャーバンド+2σ
- 3本前の終値 > 3本前のボリンジャーバンド+2σ
- 3本前のボリンジャーバンド+2σ < 2本前のボリンジャーバンド+2σ <1本前のボリンジャーバンド+2σ < 現在のボリンジャーバンド+2σ
上記をコードに起こすと
//変数
double bb2_0_upper = iBands(NULL,PERIOD_CURRENT,20,2,0,PRICE_CLOSE,MODE_UPPER,0);
double bb2_1_upper = iBands(NULL,PERIOD_CURRENT,20,2,0,PRICE_CLOSE,MODE_UPPER,1);
double bb2_2_upper = iBands(NULL,PERIOD_CURRENT,20,2,0,PRICE_CLOSE,MODE_UPPER,2);
double bb2_3_upper = iBands(NULL,PERIOD_CURRENT,20,2,0,PRICE_CLOSE,MODE_UPPER,3);
//バンドウォーク検知
if( (bb2_0_upper < Bid) && (bb2_1_upper < Close[1]) && (bb2_2_upper < Close[2]) && (bb2_3_upper < Close[3])&&
(bb2_0_upper > bb2_1_upper > bb2_2_upper > bb2_3_upper){
//何か処理
}
何本チェックするかにもよりますが、これじゃカバー出来ないケースはたくさんあるんです。
異常ケース
以下のチャートはこういうのもバンドウォークですよね。目視だと簡単にわかる。でも、プログラムだと数値で全て判断しないといけないので、少し考える必要があります。

2σに沿ってチャートは進んでるけど、触れたり、触れなかったり。
でも、価格は上昇している。
こういうのは目視だと一目瞭然ですが、プログラムでチェックするのが、面倒です。
比率をみてチェックするしかないかなーと思いました。
結果を踏まえてコードに起こすと以下のとおりになりました。
バンドウォークをチェックする関数
//+------------------------------------------------------------------+
//| ボリンジャーバンド上側バンドウォークチェック
//+------------------------------------------------------------------+
int Check_BB_BandWalk_Upper(int loop_no){
int ret = 0;
int i=0;
double bb_upper[];
//配列サイズの設定
ArrayResize(bb_upper,loop_no+1);
//ボリンジャーバンド取得
while(i < (loop_no + 1)){
bb_upper[i] = iBands(NULL,PERIOD_CURRENT,20,2,0,PRICE_CLOSE,MODE_UPPER,i);
i = i+1;
}
//何本2σにタッチしているか?
i=0;
int touch_no = 0;
while(i < loop_no){
if(bb_upper[i] <= Close[i]){
touch_no++;
}
i = i+1;
}
//ボリンジャーバンドが右肩あがり?
i=0;
int chk_expantion = 0;
while(i < loop_no){
if(bb_upper[i] > bb_upper[i+1]){
chk_expantion = 1;
}
i = i+1;
}
//バンドウォーク検知
if( touch_no >= (loop_no/2) && chk_expantion == 1){
ret = 1;
}
return ret;
}
//+------------------------------------------------------------------+
//| ボリンジャーバンド下側バンドウォークチェック
//+------------------------------------------------------------------+
int Check_BB_BandWalk_Lower(int loop_no){
int ret = 0;
int i=0;
double bb_lower[];
//配列サイズの設定
ArrayResize(bb_lower,loop_no+1);
//ボリンジャーバンド取得
while(i < (loop_no + 1)){
bb_lower[i] = iBands(NULL,PERIOD_CURRENT,20,2,0,PRICE_CLOSE,MODE_LOWER,i);
i = i+1;
}
//何本2σにタッチしているか?
i=0;
int touch_no = 0;
while(i < loop_no){
if(bb_lower[i] >= Close[i]){
touch_no++;
}
i = i+1;
}
//ボリンジャーバンドが右肩下がり?
i=0;
int chk_expantion = 0;
while(i < loop_no){
if(bb_lower[i] < bb_lower[i+1]){
chk_expantion = 1;
}
i = i+1;
}
//バンドウォーク検知
if( touch_no >= (loop_no/2) && chk_expantion == 1){
ret = 1;
}
return ret;
}
使い方
OnTick内でコールして使います。
引数はチェックする本数。
バンドウォークが発生していたら戻り値1が返ってきます。
//ボリンジャーバンドのバンドウォーク下側が発生したかチェック
if( Check_BB_BandWalk_Lower(4) == 1){
//何か処理
}
//ボリンジャーバンドのバンドウォーク上側が発生したかチェック
else if( Check_BB_BandWalk_Upper(4) == 1){
//何か処理
}








ご質問はコメント欄からお願いします