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

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

OnBookEventは、MT5(MQL5)において「板情報(Depth of Market: DOM)」が更新された際に自動的に呼び出されるイベントハンドラです。通常のOnTick関数が「価格(成行価格)の変動」で動くのに対し、OnBookEventは「板に並んでいる指値注文の数量や価格の変化」をトリガーにします。

実務での活用法

プロのクオンツやHFT(高頻度取引)の領域では、単なるローソク足の動きだけでなく、板の厚み(流動性)を監視してエッジを見出します。
* スプレッド監視: 非常に狭いスプレッドを狙うスキャルピングEAのトリガー。
* 板の偏り分析: 買い板と売り板の厚みの差(インバランス)を計算し、短期的方向性を予測。
* 大口注文の検知: 板に現れた巨大な指値(いわゆる「壁」)を検知して反発を狙う。

開発者がつまずきやすい点

初心者の方が最初につまずくのは、「関数を書くだけでは動かない」という点です。OnBookEventを動作させるには、MarketBookAdd関数を使って、特定の通貨ペアの板情報を購読(サブスクライブ)する処理を明示的に記述する必要があります。また、板情報はティックよりも更新頻度が圧倒的に高いため、処理の重いコードを書くとプラットフォーム全体がフリーズする原因にもなります。


2. 構文と戻り値

OnBookEvent関数の構造は非常にシンプルです。

void OnBookEvent(
   const string&  symbol    // イベントが発生した通貨ペア名
);
  • 引数 (symbol): 板情報の変更が発生した通貨ペアの名称が渡されます。複数の通貨ペアを監視している場合、どのペアで変更があったかを識別するために使用します。
  • 戻り値: なし(void型)。

この関数自体は値を返しませんが、関数内で MarketBookGet 関数を呼び出すことで、現在の具体的な板情報(価格ごとの注文量)を取得するのが一般的な流れです。


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

以下のサンプルは、特定の通貨ペアの板情報を取得し、最良気配(Best Bid/Ask)とそのボリュームをターミナルに表示する実用的なEAの骨格です。

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

//--- 初期化関数
int OnInit()
{
    // 現在のチャートの通貨ペアの板情報を購読する
    if(!MarketBookAdd(_Symbol))
    {
        Print("板情報の購読に失敗しました。");
        return(INIT_FAILED);
    }
    return(INIT_SUCCEEDED);
}

//--- 終了処理関数
void OnDeinit(const int reason)
{
    // 終了時には必ず購読を解除する
    MarketBookRelease(_Symbol);
}

//--- 板情報更新イベント
void OnBookEvent(const string &symbol)
{
    // 監視している通貨ペア以外のイベントは無視
    if(symbol != _Symbol) return;

    MqlBookInfo book[]; // 板情報を格納する構造体配列

    // 現在の板情報を取得
    if(MarketBookGet(symbol, book))
    {
        // 板情報の配列から最良気配付近を抽出
        // 通常、MarketBookGetで取得した配列の中央付近に現在値がくる
        for(int i=0; i<ArraySize(book); i++)
        {
            // 売り指値(OFFER)と買い指値(BID)の境界付近のみを表示する例
            if(book[i].type == BOOK_TYPE_SELL && book[i+1].type == BOOK_TYPE_BUY)
            {
                PrintFormat("通貨ペア: %s | 売り: %.5f (量: %lld) | 買い: %.5f (量: %lld)", 
                            symbol, 
                            book[i].price, book[i].volume, 
                            book[i+1].price, book[i+1].volume);
                break; 
            }
        }
    }
    else
    {
        Print("板情報の取得に失敗しました。");
    }
}

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

  1. ブローカーの対応可否:
    FXブローカーによっては、DOM(板情報)を提供していない場合があります。その場合、MarketBookAddは成功しても、MarketBookGetで取得できるデータが空、あるいは更新されないことがあります。
  2. パフォーマンスのボトルネック:
    OnBookEventは1秒間に数十回、時には数百回呼ばれます。この中でループ処理や複雑な計算、Print関数の多用を行うと、PCのCPU負荷が急増し、注文の執行遅延(レイテンシ)を招きます。計算は必要最小限に留めてください。
  3. 配列のサイズ管理:
    MarketBookGetで取得される配列 MqlBookInfo の要素数は、ブローカーや市場状況によって変動します。必ず ArraySize() で要素数を確認してからループを回すようにし、インデックス外参照エラーを防ぎましょう。

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

OnBookEventを利用するような高度なアルゴリズムトレードにおいて、最も注意すべきはコードの良し悪しよりも「物理的な実行環境」です。自宅のPCから一般的なインターネット回線を通じて自動売買を行うことは、F1レースに軽自動車で参戦するようなものです。FXサーバーとの通信には必ず「ネットワーク遅延(レイテンシ)」が存在し、自宅環境ではこの遅延が数十ミリ秒〜数百ミリ秒に達します。板情報が更新された瞬間にチャンスを検知しても、注文がサーバーに届く頃にはすでに価格が変動し、不利な価格での約定(スリッページ)やリクオートが発生して、理論上の利益はすべて消失します。

この遅延を極限まで排除し、コンマ数秒を争うトレードで優位に立つためには、ブローカーのデータセンターに物理的に近い場所に設置された「専用のVPS(仮想専用サーバー)」の利用が不可欠です。プロのトレーダーが例外なくVPSを利用するのは、それが単なる便利ツールではなく、約定スピードという勝敗に直結するインフラだからです。安定した電源、24時間の稼働、そして圧倒的な低レイテンシ環境を整えることこそが、自動売買で生き残るための最低条件と言えます。

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

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

コメント

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