
MQL5 クックブック:BookEvent の処理
はじめに
知られたことですが、MetaTrader 5 トレーディングターミナルはマルチマーケットプラットフォームで、Forex、株式市場、先物および差金決済契約でのトレードを容易にします。フリーランス セクションの統計によると、 Forex マーケット以外でもトレードしているトレーダー数は増加しています。
本稿では初心者の MQL5 プログラマーに BookEvent処理をご紹介したいと思います。このイベントはマーケットデプス-株式資産とそのデリバティブをトレードするインスツルメントに関連しています。ただし Forex トレーダーはマーケットデプスも有用であると思うことでしょう。ECN アカウントでは、アグリゲータモデルに過ぎませんが、流動性をもたらす人が注文に関するデータを供給します。こういったアカウントはより一般的になってきています。
1. BookEvent
ドキュメンテーションによると、このイベントはマーケットデプス状態が変わるときに生成されます。BookEvent はマーケットデプスイベントであると同意します。
マーケットデプスは注文の配列で、それは方向(売り、買い)、価格、ボリュームが異なります。マーケットデプスでは価格はマーケット価格に近く、そのためベストな価格であるとみなされます。
図1 MetaTrader 5 におけるマーケットデプス
MetaTrader 5 では『注文控元帳』は『マーケットデプス』と呼ばれます(図1)。マーケットデプスに関する詳細上昇は「クライアントターミナル」の「ユーザーガイド」にあります。
マーケットデプスに関する情報を提供するMqlBookInfo ストラクチャについては別に説明します。
struct MqlBookInfo { ENUM_BOOK_TYPE type; // order type from the ENUM_BOOK_TYPE enumeration double price; // price long volume; // volume };
そこにはフィールドが3つあります。オーダータイプのデータ、価格、ボリュームが注文ストラクチャを処理することで取得されます。
2. BookEvent のイベントハンドラ
イベント処理関数 OnBookEvent() はパラメータとして定数を1つ取ります。それは配列パラメータに対する参照です。
void OnBookEvent (const string& symbol)
文字列パラメータにはシンボル名があります。マーケットデプスイベントはそれに対して発生します。
イベントハンドラ自体は事前に準備する必要があります。EA がマーケットデプスイベントを処理するには、内蔵関数 MarketBookAdd() によってこのイベントがサブスクライブされる必要があります。通常それは EA の初期化ブロックにあります。マーケットデプスイベントがサブスクライブされていなければ、EA はそれを無視します。
イベント受け取りからアンサブスクライブする機能を入れることはよいプログラミングの練習であると考えられています。再初期化の際には、MarketBookRelease() 関数を呼び出すことでデータの受け取りからアンサブスクライブすることが必要です。
データ受信についてサブスクライブおよびアンサブスクライブするメカニズムは処理前にアクティブ化が必要なタイマーを作成と処理に似ています。
3. BookEvent 処理テンプレート
OnBookEvent() 関数を呼び出す簡単なのテンプレートを作成し、それにBookEventProcessor1.mq5と名づけます。
テンプレートにはハンドラの最小セットがあります。それはマーケットデプスイベントのハンドラのみならず EA の初期化と再初期化のハンドラです。
マーケットデプスイベントハンドラ自体はひじょうにシンプルです。
//+------------------------------------------------------------------+ //| BookEvent function | //+------------------------------------------------------------------+ void OnBookEvent(const string &symbol) { Print("Book event for: "+symbol); //--- select the symbol if(symbol==_Symbol) { //--- array of the DOM structures MqlBookInfo last_bookArray[]; //--- get the book if(MarketBookGet(_Symbol,last_bookArray)) { //--- process book data for(int idx=0;idx<ArraySize(last_bookArray);idx++) { MqlBookInfo curr_info=last_bookArray[idx]; //--- print PrintFormat("Type: %s",EnumToString(curr_info.type)); PrintFormat("Price: %0."+IntegerToString(_Digits)+"f",curr_info.price); PrintFormat("Volume: %d",curr_info.volume); } } } }
このマーケットデプスイベントはブロードキャスト(サブスクリプト後それはすべてのシンボルに対して表示されます)であるため、必要なインスツルメントを指定する必要があります。
最新の数ビルドであってもマーケットデプスの作用で変化がもたらされることに注意が必要です。現バージョン(ビルド975)では、ブロードキャストの兆しはみられていません。ハンドラは割り当てられたシンボルに対してのみ呼ばれます。この事実を実証するために私は単純に『エキスパートログ』に対して情報を入力するよう手配しました。
そのために内蔵関数 MarketBookGet() を使用します。それはマーケットデプスに関する情報をすべて返します。すなわち、指定のシンボルに対するマーケットデプスを持つストラクチャ配列 MqlBookInfo です。この配列はブローカーによりサイズが変わることに注意が必要です。
このテンプレートにより「ログ」内の配列ストラクチャの値を表示することができます。
EA はデバッグモードで先物 SBRF-12.14 に対して起動されました。以下はエキスポート内レコードのシーケンスです。
EL 0 11:24:32.250 BookEventProcessor1 (SBRF-12.14,M1) Book event for: SBRF-12.14 MF 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL KP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7708 LJ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 6 MP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL HF 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7705 LP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 6 MJ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL GL 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7704 ON 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 3 MD 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL FR 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7703 PD 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 2 MN 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL DH 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7701 QQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 10 GH 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL QM 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7700 OK 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 1011 ER 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL KS 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7698 EE 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 50 OM 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL KI 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7696 IO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 21 QG 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL LO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7695 MK 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 1 QQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL KE 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7694 QQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 5 QK 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL PK 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7691 LO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 2 QE 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL HQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7688 OE 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 106 MO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL RG 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7686 IP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 18 GI 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL FL 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7684 QI 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 3 GS 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL IR 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7681 LG 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 4 GM 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL JH 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7680 RM 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 2 GG 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL DN 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7679 HH 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 19 IQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL ED 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7678 EQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 1 IK 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL OJ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7676 DO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 2 IE 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL RP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7675 EE 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 1 QR 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY LF 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7671 LP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 40 QD 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY KL 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7670 QJ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 21 QN 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY CR 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7669 RD 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 20 QP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY DH 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7668 NN 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 17 QJ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY QN 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7667 RK 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 2 OL 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY DE 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7666 MQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 151 QF 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY OJ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7665 RO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 2 OH 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY FQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7664 EF 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 49 OR 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY GG 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7663 OS 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 3 ED 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY JM 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7662 PI 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 4 CN 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY ES 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7661 LD 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 13 CP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY FI 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7660 LM 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 2 IJ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY NO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7659 II 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 12 IL 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY ME 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7658 IP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 3 GF 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY NK 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7657 FM 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 15 GH 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY MQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7656 DD 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 6 MS 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY NG 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7655 KR 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 9 KE 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY OM 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7654 IK 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 14 KO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY NS 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7653 DF 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 534 MQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY OI 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7652 IO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 25
それが時間のある瞬間のマーケットデプスです。ストラクチャの配列の最初のエレメントは高値(7,708 ルーブル)で売る注文です。配列の最終エレメントは安値(7,652 ルーブル)で買う注文です。マーケットデプスデータは配列に対して上から下に読み出されます。
便宜のために表 1 にデータを集めました。
表1 SBRF-12.14 に対するマーケットデプス
赤で強調されている上のブロックには売り注文(指値売り)があります。グリーンで強調されている下のブロックには買い注文(指値買い)があります。
すべての売り注文中、注文No.6 は価格 7,700 ルーブルでボリューム1011 ロットの最大ボリュームとなっていることは明らかです。注文No.39 は価格 7,653 ルーブルでボリューム534 ロットのすべての買い注文中最大ボリュームとなっています。
マーケットデプスのソースデータはトレーディング戦略を行うためにトレーダーが分析する情報です。もっともシンプルなトレーディングの考えは、サポートとレジスタンスゾーンを作成する継続的な価格レベルにおいて大きなボリュームで注文を収集またはかたまりをつくる、というものです。次のセクションでは、マーケットデプスの変化を追跡するインディケータを作成します。
4. マーケットデプス
マーケットデプスデータを処理するインディケータは数多くあります。MetaTrader 5 マーケットで数種類の興味を引かれるものを見つけることができます。私は IShift が一番気に入っています。開発者である Yury Kulikov はコンパクトで有益なツール作成に成功しました。
マーケットデプスデータを処理するプログラムはすべて Expert Advisor またはインディケータの形式をしています。それはこういった MQL5 のプログラムがBookEvent イベントハンドラを備えているためです。
生のマーケットデプスデータを示す短いプログラムを作成します。まず表示するデータを指定する必要があります。それは注文ボリュームを示す水平バーを持つパネルです。ただし、バーのサイズは相対的なものとなります。現注文すべての最大ボリュームは 100% とみなされます。図2 は価格 7,507 ルーブルの注文が 519 ロットという最大ボリュームであることを示しています。
パネル初期化を正しく行うために、正確なマーケットデプスまたはレベル数を指定する必要があります("DOM depth" パラメータ)。この数字はブローカーごとに異なります。
図2 マーケットデプスパネル
パネルのプログラムコードはオブジェクト指向プログラミング方法で書かれます。パネル処理を行うクラスはCBookBarsPanelと名づけられます。
//+------------------------------------------------------------------+ //| Book bars class | //+------------------------------------------------------------------+ class CBookBarsPanel { private: //--- Data members CArrayObj m_obj_arr; uint m_arr_size; //--- uint m_width; uint m_height; //--- Methods public: void CBookBarsPanel(const uint _arr_size); void ~CBookBarsPanel(void){}; //--- bool Init(const uint _width,const uint _height); void Deinit(void){this.m_obj_arr.Clear();}; void Refresh(const MqlBookInfo &_bookArray[]); };
このクラスにはデータメンバーが4個あります。
- m_obj_arr 属性はCObject タイプに対するポインター用のコンテナです。それはマーケットデプスデータの格納に使用されます。後者に対しては別のクラスが作成されます。
- m_arr_size 属性はマーケットデプスレベルの数に関わりがあります。
- m_width and m_height 属性はパネルサイズ(ピクセル表示のタテとヨコ)を格納します。
メソッドに関する限り、標準的なコンストラクタとデストラクタ以外に以下を持ちます。
- 初期化メソッド
- 再初期化メソッド
- 更新メソッド
価格、水平バー、ボリュームを指定するパネルの各行(マーケットデプスレベル)に対しては個別のCBookRecord クラスを作成します。
それにはポインターが3個あります。そのうちの1つはCChartObjectRectLabelタイプ(水平バーに連携する長方形ラベル)のオブジェクト、CChartObjectLabel タイプ(価格とボリューム用テキストラベル)のポインターを2つ示します。
//+------------------------------------------------------------------+ //| Book record class | //+------------------------------------------------------------------+ class CBookRecord : public CObject { private: //--- Data members CChartObjectRectLabel *m_rect; CChartObjectLabel *m_price; CChartObjectLabel *m_vol; //--- color m_color; //--- Methods public: void CBookRecord(void); void ~CBookRecord(void); bool Create(const string _name,const color _color,const int _X, const int _Y,const int _X_size,const int _Y_size); //--- data bool DataSet(const long _vol,const double _pr,const uint _len); bool DataGet(long &_vol,double &_pr) const; private: string StringVolumeFormat(const long _vol); };
メソッドに含まれるのは以下です。
- レコード作成メソッド
- データ設定メソッド
- データ受信メソッド
- 大きな数字の形成メソッド
以下は EA に対するBookEvent のハンドラと基本的インディケータです。
//+------------------------------------------------------------------+ //| BookEvent function | //+------------------------------------------------------------------+ void OnBookEvent(const string &symbol) { //--- select the symbol if(symbol==_Symbol) { //--- array of the DOM structures MqlBookInfo last_bookArray[]; //--- get the book if(MarketBookGet(_Symbol,last_bookArray)) //--- refresh panel myPanel.Refresh(last_bookArray); } }
BookEvent が生成されるたびごとにパネルがそのデータを更新します。プログラムの更新バージョンをBookEventProcessor2.mq5.と名づけます。
上のビデオで EA がどのように動作するか確認することができます。
おわりに
本稿はターミナルのもうひとつのイベント、マーケットデプスイベントについて述べています。このイベントは高頻度トレーディング(HFT)アルゴリズムの核となることが多いものです。このトレードタイプはトレーダーの間で人気を集めています。
MQL5 のプログラムを始めるトレーダーの方々が本稿にあるマーケットデプスイベント処理の例を有用であると思われることを願っています。本稿単プのソースファイルはプロジェクトフォルダに入れるのに便利です。私の場合は \MQL5\Projects\BookEvent です。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/1179





- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索