ボリンジャーバンドは、移動平均線を中心に「価格の散らばり具合(標準偏差)」を帯(バンド)として表示するテクニカル指標です。MQL4には、このボリンジャーバンドの値をプログラムから簡単に取得できるiBands関数が用意されています。
この記事では、iBands関数の引数の意味をひとつずつ丁寧に解説し、基本的な使い方から逆張りEAのサンプルコード、さらに応用テクニックやよくある間違いまで、徹底的にまとめました。ボリンジャーバンドをEAやインジケーターで活用したい方は、ぜひ最後まで読んでみてください。
ボリンジャーバンドとは?
ボリンジャーバンドは、アメリカの投資家ジョン・ボリンジャー氏が考案したテクニカル指標で、以下の3本のラインで構成されます。
- ミドルバンド(中間線):単純移動平均線(SMA)そのもの
- アッパーバンド(上方バンド):ミドルバンド + 標準偏差 × n
- ロワーバンド(下方バンド):ミドルバンド − 標準偏差 × n
ここで「n」は標準偏差の倍率で、一般的には2σ(シグマ)がよく使われます。統計的には、価格が±2σの範囲に収まる確率は約95.4%とされています。この性質を利用して、バンドの上端・下端にタッチしたら逆張りする戦略や、バンドをブレイクした方向に順張りする戦略などに活用されます。
iBands関数の基本構文
MQL4でボリンジャーバンドの値を取得するには、組み込み関数iBandsを使います。基本構文は以下のとおりです。
double iBands(
string symbol, // ① 通貨ペア名
int timeframe, // ② 時間足
int period, // ③ 計算期間
double deviation, // ④ 標準偏差の倍率
int bands_shift, // ⑤ インジケーターのシフト数
int applied_price, // ⑥ 適用価格
int mode, // ⑦ ライン種類
int shift // ⑧ シフト数(何本前のバーか)
);
戻り値はdouble型で、指定した条件のボリンジャーバンドの値(価格)が返されます。引数が8つあるため少し多く感じますが、ひとつずつ見ていけば難しくありません。
各引数の詳細解説
① symbol(通貨ペア名)
計算対象の通貨ペアを文字列で指定します。現在のチャートの通貨ペアを使いたい場合はNULLまたはSymbol()を指定します。
// 現在のチャートの通貨ペアを使う場合
iBands(NULL, ...)
iBands(Symbol(), ...)
// 別の通貨ペアを指定する場合
iBands("USDJPY", ...)
② timeframe(時間足)
計算に使う時間足を指定します。現在のチャートの時間足を使う場合は0またはPERIOD_CURRENTを指定します。
| 定数 | 値 | 意味 |
|---|---|---|
| PERIOD_CURRENT | 0 | 現在のチャートの時間足 |
| PERIOD_M1 | 1 | 1分足 |
| PERIOD_M5 | 5 | 5分足 |
| PERIOD_M15 | 15 | 15分足 |
| PERIOD_M30 | 30 | 30分足 |
| PERIOD_H1 | 60 | 1時間足 |
| PERIOD_H4 | 240 | 4時間足 |
| PERIOD_D1 | 1440 | 日足 |
| PERIOD_W1 | 10080 | 週足 |
| PERIOD_MN1 | 43200 | 月足 |
③ period(計算期間)
移動平均線の計算に使うバーの本数を指定します。一般的には20がよく使われます。期間を短くするとバンドが価格に敏感に反応し、長くすると滑らかになります。
④ deviation(標準偏差の倍率)
バンドの幅を決める標準偏差の倍率です。一般的には2.0が使われます。1.0を指定すれば±1σ、3.0なら±3σのバンドが取得できます。
⑤ bands_shift(インジケーターのシフト数)
ボリンジャーバンド全体を左右にずらす本数です。通常は0を指定します。正の値を指定するとバンドが右(未来方向)にずれます。特殊な用途でない限り0で問題ありません。
⑥ applied_price(適用価格)
計算に使う価格の種類を指定します。通常はPRICE_CLOSE(終値)を使います。
| 定数 | 値 | 意味 |
|---|---|---|
| PRICE_CLOSE | 0 | 終値 |
| PRICE_OPEN | 1 | 始値 |
| PRICE_HIGH | 2 | 高値 |
| PRICE_LOW | 3 | 安値 |
| PRICE_MEDIAN | 4 | 中間価格 (High+Low)/2 |
| PRICE_TYPICAL | 5 | 典型的な価格 (High+Low+Close)/3 |
| PRICE_WEIGHTED | 6 | 加重終値 (High+Low+Close+Close)/4 |
⑦ mode(ライン種類)
取得したいラインを指定します。iBands関数は1回の呼び出しで1本のラインの値しか返さないため、3本すべてを取得するには3回呼び出す必要があります。
| 定数 | 値 | 意味 |
|---|---|---|
| MODE_MAIN | 0 | ミドルバンド(中間線・移動平均線) |
| MODE_UPPER | 1 | アッパーバンド(上方バンド) |
| MODE_LOWER | 2 | ロワーバンド(下方バンド) |
⑧ shift(シフト数)
何本前のバーの値を取得するかを指定します。0が現在のバー(まだ確定していないバー)、1が1本前の確定済みバー、2が2本前…という意味です。
EA(自動売買)で売買判断に使う場合は、確定済みの値であるshift=1を使うのが一般的です。shift=0は現在足の値なのでティックごとに変動し、判断がブレやすくなるためです。
基本的な使用例
まずは最もシンプルな例として、現在のチャートで期間20・偏差2.0のボリンジャーバンド3本の値を取得してみましょう。
void OnTick()
{
// 1本前の確定足でボリンジャーバンドの値を取得
double upper = iBands(NULL, 0, 20, 2.0, 0, PRICE_CLOSE, MODE_UPPER, 1);
double middle = iBands(NULL, 0, 20, 2.0, 0, PRICE_CLOSE, MODE_MAIN, 1);
double lower = iBands(NULL, 0, 20, 2.0, 0, PRICE_CLOSE, MODE_LOWER, 1);
// ログに出力して確認
Print("Upper: ", upper, " | Middle: ", middle, " | Lower: ", lower);
}
このコードでは、3つのiBands呼び出しでmode引数だけを変えて、上方バンド・中間線・下方バンドの3つの値をそれぞれ取得しています。それ以外の引数はすべて同じ値を指定します。
実践サンプル:ボリンジャーバンド逆張りEA
ここでは、ボリンジャーバンドの±2σを使ったシンプルな逆張りEAを作ってみましょう。ロジックは以下のとおりです。
- 買いエントリー:1本前の終値がロワーバンド(-2σ)を下回ったら買い
- 売りエントリー:1本前の終値がアッパーバンド(+2σ)を上回ったら売り
- 決済:ミドルバンドに到達したら決済
//+------------------------------------------------------------------+
//| ボリンジャーバンド逆張りEA |
//+------------------------------------------------------------------+
#property strict
// 入力パラメーター
input int BB_Period = 20; // ボリンジャーバンドの期間
input double BB_Deviation = 2.0; // 標準偏差の倍率
input double Lots = 0.1; // ロット数
input int Slippage = 3; // スリッページ
input int MagicNumber = 12345; // マジックナンバー
//+------------------------------------------------------------------+
//| OnTick関数 |
//+------------------------------------------------------------------+
void OnTick()
{
// ボリンジャーバンドの各ラインを取得(1本前の確定足)
double upper = iBands(NULL, 0, BB_Period, BB_Deviation, 0, PRICE_CLOSE, MODE_UPPER, 1);
double middle = iBands(NULL, 0, BB_Period, BB_Deviation, 0, PRICE_CLOSE, MODE_MAIN, 1);
double lower = iBands(NULL, 0, BB_Period, BB_Deviation, 0, PRICE_CLOSE, MODE_LOWER, 1);
// 1本前の終値
double prevClose = Close[1];
// 現在のポジション数を確認
int buyCount = CountOrders(OP_BUY);
int sellCount = CountOrders(OP_SELL);
// --- エントリーロジック ---
// 買いエントリー:終値がロワーバンドを下回った
if(buyCount == 0 && prevClose < lower)
{
int ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, 0, 0,
"BB Buy", MagicNumber, 0, clrBlue);
if(ticket < 0)
Print("Buy OrderSend Error: ", GetLastError());
}
// 売りエントリー:終値がアッパーバンドを上回った
if(sellCount == 0 && prevClose > upper)
{
int ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, 0, 0,
"BB Sell", MagicNumber, 0, clrRed);
if(ticket < 0)
Print("Sell OrderSend Error: ", GetLastError());
}
// --- 決済ロジック:ミドルバンドに到達したら決済 ---
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if(OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue;
// 現在のバーのミドルバンドを取得(決済判断用)
double currentMiddle = iBands(NULL, 0, BB_Period, BB_Deviation, 0, PRICE_CLOSE, MODE_MAIN, 0);
if(OrderType() == OP_BUY && Bid >= currentMiddle)
{
if(!OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, clrBlue))
Print("Buy OrderClose Error: ", GetLastError());
}
else if(OrderType() == OP_SELL && Ask <= currentMiddle)
{
if(!OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, clrRed))
Print("Sell OrderClose Error: ", GetLastError());
}
}
}
//+------------------------------------------------------------------+
//| 指定タイプのポジション数をカウントする関数 |
//+------------------------------------------------------------------+
int CountOrders(int orderType)
{
int count = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() == orderType)
count++;
}
return count;
}
このEAのポイントをまとめます。
- エントリー判断はshift=1(確定足)を使い、値がブレないようにしています
- 決済判断はshift=0(現在足)を使い、リアルタイムの価格とミドルバンドを比較しています
- CountOrders関数でポジション数を確認し、同方向に重複エントリーしないようにしています
- MagicNumberを使うことで、他のEAのポジションと区別しています
応用テクニック
複数のσを同時に使う
ボリンジャーバンドの±1σ、±2σ、±3σを同時に取得すれば、より細かい分析が可能です。deviation引数を変えるだけで実現できます。
// ±1σ
double upper1 = iBands(NULL, 0, 20, 1.0, 0, PRICE_CLOSE, MODE_UPPER, 1);
double lower1 = iBands(NULL, 0, 20, 1.0, 0, PRICE_CLOSE, MODE_LOWER, 1);
// ±2σ
double upper2 = iBands(NULL, 0, 20, 2.0, 0, PRICE_CLOSE, MODE_UPPER, 1);
double lower2 = iBands(NULL, 0, 20, 2.0, 0, PRICE_CLOSE, MODE_LOWER, 1);
// ±3σ
double upper3 = iBands(NULL, 0, 20, 3.0, 0, PRICE_CLOSE, MODE_UPPER, 1);
double lower3 = iBands(NULL, 0, 20, 3.0, 0, PRICE_CLOSE, MODE_LOWER, 1);
たとえば「±1σの範囲内ならレンジ相場と判断し取引を控える」「±3σにタッチしたら強い逆張りシグナル」といった使い方ができます。
バンド幅でボラティリティを判定する
アッパーバンドとロワーバンドの差を計算すれば、バンド幅(ボラティリティの目安)が分かります。
double upper = iBands(NULL, 0, 20, 2.0, 0, PRICE_CLOSE, MODE_UPPER, 1);
double lower = iBands(NULL, 0, 20, 2.0, 0, PRICE_CLOSE, MODE_LOWER, 1);
// バンド幅を計算
double bandWidth = upper - lower;
// バンド幅をポイント単位に変換(通貨ペアの桁数に応じて調整)
double bandWidthPoints = bandWidth / Point;
// ボラティリティ判定の例
if(bandWidthPoints < 200)
{
Print("スクイーズ状態(低ボラティリティ):バンド幅 = ", bandWidthPoints, " points");
// → この後のブレイクアウトに備える
}
else if(bandWidthPoints > 500)
{
Print("エクスパンション状態(高ボラティリティ):バンド幅 = ", bandWidthPoints, " points");
// → トレンドフォロー戦略を検討
}
バンドが極端に狭くなった状態(スクイーズ)は、その後大きなトレンドが発生する前兆とされています。バンドが急激に広がった状態(エクスパンション)はトレンドが発生中であることを示します。
よくある間違いと注意点
shift=0は未確定の値
最も多い間違いのひとつが、shift=0の値でエントリー判断をしてしまうことです。shift=0は現在のバー(まだローソク足が確定していない状態)の値なので、ティックが来るたびに値が変わります。
エントリー条件にはshift=1(確定済みのバー)を使うようにしましょう。バックテストとリアルトレードの結果が大きくずれる原因にもなります。
MODE定数の取り違え
iBands関数のmode引数で使う定数と、iMACD関数などの他のインジケーター関数のmode定数は名前が似ていても意味が異なる場合があります。iBandsではMODE_MAIN(0)、MODE_UPPER(1)、MODE_LOWER(2)の3つを使います。
特にMODE_MAINはiMACD関数でも使われる定数ですが、iBandsではミドルバンド(移動平均線)を意味します。関数ごとにどの定数がどのラインを表すか確認しましょう。
マルチタイムフレームでの注意
timeframe引数に現在のチャートと異なる時間足を指定すると、上位足のボリンジャーバンドを取得できます。しかし、いくつか注意点があります。
// 1時間足チャートで日足のボリンジャーバンドを取得
double dailyUpper = iBands(NULL, PERIOD_D1, 20, 2.0, 0, PRICE_CLOSE, MODE_UPPER, 1);
- 上位足のデータが十分にダウンロードされていないとエラーや不正確な値が返されることがあります
- 上位足のshift=0は上位足の現在のバーを指すため、確定タイミングがチャート時間足とは異なります
- バックテストでは「全ティック」モデルを使わないとマルチタイムフレームの値が正しく取得できない場合があります
まとめ
この記事では、MQL4のiBands関数について、基本構文から各引数の詳細、実践的なEAサンプル、応用テクニックまで解説しました。最後にポイントを整理します。
- iBands関数は8つの引数を持ち、ボリンジャーバンドの値をdouble型で返す
- mode引数でMODE_MAIN(中間線)、MODE_UPPER(上方バンド)、MODE_LOWER(下方バンド)を切り替える
- 3本のラインを取得するにはiBandsを3回呼び出す必要がある
- エントリー判断にはshift=1(確定足)を使うのが基本
- deviation引数を変えることで、±1σ/±2σ/±3σなど複数のバンドを簡単に取得できる
- バンド幅の計算でボラティリティの判定(スクイーズ・エクスパンション)にも活用できる
iBands関数はシンプルながらも応用範囲が広い関数です。まずは基本的な使い方をマスターし、他のテクニカル指標と組み合わせたり、エントリー条件を工夫したりして、自分だけのEA開発に挑戦してみてください!

