【MQL5】iBWMFI関数の使い方と自動売買実装コード

1. iBWMFI関数の概要と実務での活用法

iBWMFIは、著名なトレーダーであるビル・ウィリアムズ氏が考案した「マーケット・ファシリテーション・インデックス(Market Facilitation Index:MFI)」の値を取得するための関数です。

このインジケーターの最大の特徴は、「価格の変化」と「ティックボリューム(出来高)」の相関関係を数値化する点にあります。一般的なテクニカル指標が価格の推移のみを追うのに対し、BWMFIは「その価格変動にどれだけのエネルギー(出来高)が伴っているか」を可視化します。

実務での活用とつまずきポイント

実務開発において、初心者が最も陥りやすい罠は「標準のMoney Flow Index (iMFI)」との混同です。標準のMFIはオシレーター系(0〜100)ですが、ビル・ウィリアムズのMFIは単位が異なり、値そのものよりも「前本数との比較」に意味があります。

開発現場では、数値そのものをエントリー条件にするのではなく、以下の4つの状態(カラー)を判定するために活用するのが一般的です。

  1. Green(緑): 価格変動と出来高の両方が増加(トレンドの加速)
  2. Fade(枯れ): 両方が減少(トレンドの終焉)
  3. Fake(ニセ): 価格は動くが出来高が減少(ダマシの可能性)
  4. Squat(しゃがみ): 価格変動は小さいが出来高が急増(爆発前夜)

特に「Squat」の状態を検知し、ブレイクアウトの準備段階をプログラムで捉える手法は、中級者以上の開発者が好んで使うロジックです。


2. 構文と戻り値

MQL5におけるiBWMFI関数の基本構文は以下の通りです。

int iBWMFI(
   string              symbol,            // 通貨ペア名(NULLで現在のチャート)
   ENUM_TIMEFRAMES     period,            // 時間軸(0で現在の時間軸)
   ENUM_APPLIED_VOLUME applied_volume     // 使用するボリュームの種類
);

パラメーター解説

  • symbol: 対象となる通貨ペア。通常は _Symbol を指定します。
  • period: 参照する時間足。 PERIOD_CURRENTPERIOD_H1 などを指定します。
  • applied_volume: ボリュームの種類。FXでは通常 VOLUME_TICK(ティックボリューム)を使用します。

戻り値

  • 成功した場合、インジケーターのハンドル(int型)を返します。
  • 失敗した場合は INVALID_HANDLE を返します。

※この関数自体は指標の「値」を返すのではなく、値を計算するための「窓口(ハンドル)」を作成するものです。実際の数値を取得するには、後述するように CopyBuffer 関数を組み合わせて使用します。


3. 具体的な使い方・実践サンプルコード

以下は、iBWMFIを使用して現在のバーのMFI値とボリュームを取得し、ビル・ウィリアムズの4つの状態を判定するシンプルなEAのテンプレートです。

//+------------------------------------------------------------------+
//|                                              BWMFI_Sample_EA.mq5 |
//+------------------------------------------------------------------+
#property strict

// インジケーターハンドルを格納する変数
int bwmfi_handle;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
    // 1. iBWMFIのハンドルを作成(ティックボリュームを使用)
    bwmfi_handle = iBWMFI(_Symbol, PERIOD_CURRENT, VOLUME_TICK);

    // ハンドル作成に失敗した場合は初期化エラーを返す
    if(bwmfi_handle == INVALID_HANDLE)
    {
        Print("iBWMFIハンドルの作成に失敗しました。");
        return(INIT_FAILED);
    }

    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    double mfi_buffer[];   // MFI値を格納する動的配列
    long   vol_buffer[];   // ボリューム値を格納する動的配列(ボリュームはlong型)

    // 時系列の順序を直近から過去へ(最新がインデックス0)に設定
    ArraySetAsSeries(mfi_buffer, true);

    // 2. ハンドルを使って最新2本分のMFIデータを取得
    if(CopyBuffer(bwmfi_handle, 0, 0, 2, mfi_buffer) < 2) return;

    // 3. ボリュームデータも取得(iBWMFIの判定にはボリューム比較が必要)
    // iVolume関数などで最新2本分のボリュームを取得
    long current_vol = iVolume(_Symbol, PERIOD_CURRENT, 0);
    long prev_vol    = iVolume(_Symbol, PERIOD_CURRENT, 1);

    double current_mfi = mfi_buffer[0];
    double prev_mfi    = mfi_buffer[1];

    // 4. ビル・ウィリアムズの4大状態判定ロジック
    string status = "";

    if(current_mfi > prev_mfi && current_vol > prev_vol)
        status = "Green (トレンド加速)";
    else if(current_mfi < prev_mfi && current_vol < prev_vol)
        status = "Fade (トレンド減衰)";
    else if(current_mfi > prev_mfi && current_vol < prev_vol)
        status = "Fake (ダマシの可能性)";
    else if(current_mfi < prev_mfi && current_vol > prev_vol)
        status = "Squat (ブレイク寸前の溜め)";

    Comment("現在の市場状態: ", status, "\nMFI: ", current_mfi, "\nVol: ", current_vol);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    // メモリ解放のためにハンドルを削除
    IndicatorRelease(bwmfi_handle);
}

4. 使用上の注意点とよくあるエラー

① ボリュームデータの信頼性

iBWMFIは計算式にボリューム(出来高)を含みます。FX業者によって提供される「ティックボリューム」は業者ごとに異なるため、同じロジックでもA社では「Green」なのにB社では「Fake」になるという現象が起こり得ます。バックテストを行う際は、リアル口座と同じブローカーのデータを使用することが極めて重要です。

② ハンドルの二重作成に注意

OnTick 内で iBWMFI 関数を呼び出さないでください。ティックが来るたびに新しい計算用ハンドルを作成すると、メモリを大量に消費し、ターミナルの動作が極端に重くなる「メモリリーク」の原因となります。必ず OnInit で一度だけ作成し、変数に保存して使い回してください。

③ CopyBufferの戻り値チェック

ネットワークの瞬断などでデータが取得できない場合があります。CopyBuffer の戻り値(取得できた要素数)を必ずチェックし、期待した数(例:2本分)が取れていない場合は、計算をスキップするように設計してください。


5. 【重要】自動売買における約定スピードと環境の罠

自動売買プログラム(EA)を完成させた後、多くのエンジニアが見落とす致命的な要素が「実行環境のレイテンシ(遅延)」です。自宅のPCや一般的な光回線でEAを運用すると、取引サーバーとの間に数十から数百ミリ秒の物理的な距離による遅延が発生します。

iBWMFIのようなティックボリュームに依存するインジケーターは、一瞬の価格変動と出来高の急増を捉えるのが真骨頂です。しかし、自宅PCからの注文がサーバーに届く頃には、検知した「Squat」や「Green」の状態は既に過去のものとなり、最悪のタイミングで約定する「スリッページ」を招きます。このコンマ数秒の遅れが、バックテストでは右肩上がりのロジックをリアルトレードで赤字に変えてしまいます。

プロのクオンツエンジニアとして断言しますが、極限まで約定スピードを高め、エッジを利益に変えるためには、取引サーバーに物理的に近いデータセンター内に設置された専用のVPS(仮想専用サーバー)の利用は「推奨」ではなく「必須」です。ネットワーク遅延という技術的負債を抱えたまま、アルゴリズムの優位性だけで勝ち続けることは不可能です。

💡 この記事の内容を実運用で活かすには?

この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント

タイトルとURLをコピーしました