1. iBands関数の概要と実務での活用法
MQL5のiBands関数は、テクニカル分析の王道である「ボリンジャーバンド」の指標ハンドルを取得するための関数です。ボリンジャーバンドは、価格の変動範囲(ボラティリティ)を統計的に捉えるために使用され、中央の移動平均線と、その上下に配置された標準偏差(σ:シグマ)のラインで構成されます。
実務での活用シーン
実務開発において、ボリンジャーバンドは主に以下の3つの目的で多用されます。
1. 逆張り(平均回帰): 価格が±2σや±3σに達した際の「売られすぎ・買われすぎ」を判定する。
2. 順張り(ブレイクアウト): バンド幅が狭まる「スクイーズ」状態から、価格がバンドを突き抜けたタイミング(エクスパンション)でエントリーする。
3. ボラティリティフィルタ: バンド幅そのものを計測し、相場が動いていない(閑散としている)時はトレードを控える。
初心者がつまずきやすいポイント
MQL4から移行した開発者が最も混乱するのは、「iBands関数を呼び出しただけでは、バンドの数値(価格)は取得できない」という点です。MQL5では、まずiBandsで「計算機(ハンドル)」を作成し、その後CopyBuffer関数を使って、必要な時だけデータを配列にコピーするという2ステップの処理が必要になります。この「ハンドルの概念」を理解することが、MQL5マスターへの第一歩です。
2. 構文と戻り値
iBands関数の基本的な構文は以下の通りです。
int iBands(
string symbol, // 通貨ペア名(NULLで現在のチャート)
ENUM_TIMEFRAMES period, // 時間軸(0で現在の時間軸)
int bands_period, // 平均化期間(通常は20)
int bands_shift, // 水平シフト
double deviation, // 標準偏差(通常は2.0)
ENUM_APPLIED_PRICE applied_price // 適用価格(PRICE_CLOSEなど)
);
戻り値
- 成功時: 指標の「ハンドル」と呼ばれる整数値(int)を返します。
- 失敗時:
INVALID_HANDLEを返します。
インジケータバッファのインデックス
CopyBufferで使用する際、ボリンジャーバンドには以下の3つのバッファ番号が割り当てられています。
* 0: BASE_LINE(中央の移動平均線)
* 1: UPPER_BAND(上バンド)
* 2: LOWER_BAND(下バンド)
3. 具体的な使い方・実践サンプルコード
以下は、ボリンジャーバンドの±2σを価格が上抜けた、あるいは下抜けた時にログを出力する、実践的なEAの雛形コードです。
//+------------------------------------------------------------------+
//| Bands_Sample_EA.mq5 |
//+------------------------------------------------------------------+
#property strict
// グローバル変数
int handleBands; // ボリンジャーバンドのハンドルを格納
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// 1. ボリンジャーバンドのハンドルを取得(期間20, 偏差2.0)
handleBands = iBands(_Symbol, _Period, 20, 0, 2.0, PRICE_CLOSE);
// ハンドル取得に失敗した場合の処理
if(handleBands == INVALID_HANDLE)
{
Print("ボリンジャーバンドのハンドル取得に失敗しました。");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
double upperBuffer[]; // 上バンド格納用配列
double lowerBuffer[]; // 下バンド格納用配列
double closePrice[]; // 終値格納用配列
// 配列を時系列順(最新のバーがインデックス0)に設定
ArraySetAsSeries(upperBuffer, true);
ArraySetAsSeries(lowerBuffer, true);
ArraySetAsSeries(closePrice, true);
// 2. データを配列にコピー(最新のバーから3本分)
if(CopyBuffer(handleBands, 1, 0, 3, upperBuffer) < 0 ||
CopyBuffer(handleBands, 2, 0, 3, lowerBuffer) < 0 ||
CopyClose(_Symbol, _Period, 0, 3, closePrice) < 0)
{
Print("データのコピーに失敗しました。");
return;
}
// 3. ロジック判定(例:現在の終値がバンドを越えたか)
double currentClose = closePrice[0];
double upperBand = upperBuffer[0];
double lowerBand = lowerBuffer[0];
if(currentClose > upperBand)
{
Print("【シグナル】価格が+2σを上抜けました。現在の終値: ", currentClose);
}
else if(currentClose < lowerBand)
{
Print("【シグナル】価格が-2σを下抜けました。現在の終値: ", currentClose);
}
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// メモリ解放のためにハンドルを削除
IndicatorRelease(handleBands);
}
4. 使用上の注意点とよくあるエラー
配列の時系列順(ArraySetAsSeries)
MQL5のデフォルトでは、配列のインデックスは「古い順」に並んでいます。しかし、トレード戦略では「最新のバー(0番目)」として扱う方が直感的です。ArraySetAsSeries(array, true)を忘れると、最新の値を取得しようとして100本前のデータを参照してしまうようなミスに繋がります。
ハンドルの解放
OnInitで作成したハンドルは、EAが停止する際にIndicatorReleaseで解放するのがマナーです。これを怠ると、バックテストの繰り返し時にメモリ消費が肥大化し、プラットフォームの動作が不安定になる原因となります。
データ未充足時のエラー
MT5を起動直後や、新しい通貨ペアでEAを動かした直後は、ヒストリカルデータのダウンロードが完了しておらず、CopyBufferがエラーを返すことがあります。必ず戻り値をチェックし、データが取得できていない場合はそのティックの処理をスキップするように設計してください。
5. 【重要】自動売買における約定スピードと環境の罠
ボリンジャーバンドを用いたロジック、特にバンド端での逆張りやブレイクアウト手法において、最も致命的なリスクは「価格の変動」ではなく「ネットワーク遅延(レイテンシ)」です。自宅のPC環境から一般的なインターネット回線を通じて注文を出す場合、数ミリ秒から数百ミリ秒の遅延が発生します。ボリンジャーバンドが示すシグナルは一瞬の価格の歪みを捉えるものが多いため、このわずかな遅延が原因で「本来の有利な価格」を逃し、不利な価格で約定する(スリッページが発生する)ことになります。
特にボラティリティが高い局面では、ミリ秒単位の遅れが利益をすべて溶かし、最悪の場合は損失を招くことさえあります。プロのクオンツエンジニアが、ブローカーのサーバーに物理的に近い場所にある専用のVPS(仮想専用サーバー)を利用するのは、単に24時間稼働させるためだけではありません。約定スピードを極限まで高め、執行の優位性を確保するためです。自動売買を「趣味」から「投資」へと昇華させるのであれば、通信環境への投資は、優れたアルゴリズムの開発以上に優先すべき事項といえます。
💡 この記事の内容を実運用で活かすには?
この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント