OnBookEvent

この関数は、BookEventイベントが発生するときに指標やEAで呼び出され、板情報の変化を処理するために設計されています。

void OnBookEvent(
  const string&  symbol        // 銘柄
  );

パラメータ

symbol

[in] BookEventが到着した銘柄の名称

戻り値

なし

注意事項

任意のシンボルのBookEventイベントを受け取るには、MarketBookAdd() 関数を使用してこのシンボルのBookEventイベント受信を事前に設定する必要があります。指定されたシンボルのBookEventへの購読を停止するにはMarketBookRelease()関数を呼ぶ必要があります。

BookEventはすべてのチャートにブロードキャストされます。これは、1 つのアプリケーションがMarketBookAddを使用してBookEventイベントの受信に購読した場合、同じチャートにある他のすべてのOnBookEvent() ハンドラを持っている指標とEAがこのイベントを受け取ることを意味します。よって、symbolパラメータとしてOnBookEvent()ハンドラに渡された銘柄名を分析する必要があります。

同じチャートで実行されているすべてのアプリケーションについて銘柄でソートされた個別のBookEventカウンターが提供されます。これは、各チャートが異なるシンボルに対して複数のサブスクリプションを持つことができ、各シンボルに対してカウンタが提供されることを意味します。BookEventを購読および購読解除すると、指定したシンボルの購読カウンタが1つのチャート内でのみ変更されます。言い換えれば、同じシンボルであるにもかかわらず購読カウンタの値が異なるBookEventには、2つの隣接するチャートが存在する可能性があります。

購読カウンタの初期値はゼロです。MarketBookAdd()が呼び出されるごとに、チャート上の指定されたシンボルの購読カウンタが1つ増えます(チャートシンボルと MarketBookAdd()内のシンボルは一致する必要はありません)。MarketBookRelease()を呼び出すと、チャート内の特定のシンボルに対する購読カウンタが1つ減少します。任意のシンボルのBookEventイベントは、カウンタが0になるまでチャート内でブロードキャストされます。したがって、MarketBookAdd ()の呼び出しを含むMQL5プログラムが全て、動作後にMarketBookRelease()を使用して正しくイベントの購読を解除することが重要です。これを達成するためには、MQL5プログラムの全体のライフタイムでのMarketBookAdd()MarketBookRelease()の呼び出し数は偶数であるべきです。プログラム内でフラグやカスタム購読カウンタを使用することで、BookEventイベントを安全に扱うことができ、購読を無効にして、同じイベントのサードパーティプログラムでイベントを取得することを防ぐことができます。

BookEventイベントはスキップされることはなく、前のBookEventの処理がまだ終わっていなくても、常にキューに入れられます。

 

//+------------------------------------------------------------------+
//|                                           OnBookEvent_Sample.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link     "https://www.mql5.com/en/articles/2635"
#property version   "1.00"
#property description "Example of measuring the market depth refresh rate using OnBookEvent()"
#property description "The code is taken from the article https://www.mql5.com/en/articles/2635"
//--- 入力パラメータ
input ulong ExtCollectTime   =30; // 秒単位でのテスト時間
input ulong ExtSkipFirstTicks=10; // 初めに抜かされるティックの数
//--- BookEventイベント購読のフラグ
bool book_subscribed=false;
//--- 板情報からリクエストを受け取る配列
MqlBookInfo  book[];
//+------------------------------------------------------------------+
//| エキスパート初期化関数                                                |
//+------------------------------------------------------------------+
int OnInit()
 {
//--- 初めを表示する
  Comment(StringFormat("Waiting for the first %I64u ticks to arrive",ExtSkipFirstTicks));
  PrintFormat("Waiting for the first %I64u ticks to arrive",ExtSkipFirstTicks);
//--- 板情報ブロードキャストを有効にする
  if(MarketBookAdd(_Symbol))
    {
     book_subscribed=true;
    PrintFormat("%s: MarketBookAdd(%s) function returned true",__FUNCTION__,_Symbol);
    }
  else
    PrintFormat("%s: MarketBookAdd(%s) function returned false!GetLastError()=%d",__FUNCTION__,_Symbol,GetLastError());
//--- 初期化が正常に完了
  return(INIT_SUCCEEDED);
 }
//+------------------------------------------------------------------+
//| エキスパートの初期化を解除する                                           |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
 {
//--- 初期化解除の理由コードを表示する
  Print(__FUNCTION__,": Deinitialization reason code = ",reason);  
//--- 板情報イベント受信の購読を取り消す
  if(book_subscribed)
    {
    if(!MarketBookRelease(_Symbol))
        PrintFormat("%s: MarketBookRelease(%s) returned false!GetLastError()=%d",_Symbol,GetLastError());
    else
        book_subscribed=false;
    }
//---
 }
//+------------------------------------------------------------------+
//| BookEvent関数                                                     |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
 {
  static ulong starttime=0;             // テスト開始時刻
  static ulong tickcounter=0;           // 板情報更新カウンタ
//--- 板情報イベントを扱うのは、自分たちで購読している場合のみである
  if(!book_subscribed)
    return;
//--- 特定シンボルのみの更新を数える
  if(symbol!=_Symbol)
    return;
//--- 最初のティックをスキップしてキューをクリアする
  tickcounter++;
  if(tickcounter<ExtSkipFirstTicks)
    return;
//--- 開始時刻を記憶する
  if(tickcounter==ExtSkipFirstTicks)
     starttime=GetMicrosecondCount();
//--- 板情報データをリクエストする
  MarketBookGet(symbol,book);
//--- 終了時  
  ulong endtime=GetMicrosecondCount()-starttime;
  ulong ticks  =1+tickcounter-ExtSkipFirstTicks;
// テストの開始からどれくらいの時間が経過したか
  if(endtime>ExtCollectTime*1000*1000)
    {
    PrintFormat("%I64u ticks for %.1f seconds: %.1f ticks/sec ",ticks,endtime/1000.0/1000.0,ticks*1000.0*1000.0/endtime);
    ExpertRemove();
    return;
    }
//--- カウンタをコメント欄に表示する
  if(endtime>0)
    Comment(StringFormat("%I64u ticks for %.1f seconds: %.1f ticks/sec ",ticks,endtime/1000.0/1000.0,ticks*1000.0*1000.0/endtime));
 }

 

 

参照

MarketBookAddMarketBookReleaseMarketBookGetOnTradeOnTradeTransactionOnTickイベント処理関数プログラムの実行クライエント端末イベント