English Русский 中文 Español Deutsch Português
DoEasyライブラリでの価格(第63部): 板情報とその抽象リクエストクラス

DoEasyライブラリでの価格(第63部): 板情報とその抽象リクエストクラス

MetaTrader 5 | 4 5月 2021, 09:57
339 0
Artyom Trishkin
Artyom Trishkin

内容


概念

本稿では、板情報(DOM)を使用するための機能の実装を開始します。概念的には、DOMを使用するためのクラスは、以前に実装されたすべてのライブラリクラスと同じです。同時に、DOMに保存されている注文に関するデータを特徴とするDOMのモールドがあります。データは、OnBookEvent()ハンドラがアクティブ化されたときにMarketBookGet()関数によって取得されます。DOMに変更があった場合、DOMイベントへのアクティブなサブスクリプションを持つ銘柄ごとにイベントがハンドラ内でアクティブ化されます。

したがって、DOMクラスの構造は次のようになります。

  1. DOM注文オブジェクトクラス — OnBookEvent()ハンドラが1つの銘柄に対してトリガーされたときにDOMから取得された複数の注文のうちの1つの注文のデータを記述するオブジェクト
  2. DOMモールドオブジェクトクラス — 1つの銘柄に対するOnBookEvent()ハンドラの1回のアクティブ化で同時にDOMから取得されたすべての注文のデータを記述するオブジェクト — 現在のDOMモールドを構成するオブジェクトのp1セット
  3. 1つの銘柄の各OnBookEvent()アクティブ化で時系列リストに入力されたp2オブジェクトシーケンスで構成される時系列クラス
  4. DOMイベントへのサブスクリプションが有効になっている、使用されているすべての銘柄のDOMデータの時系列コレクションクラス

今日は、注文オブジェクトクラス(1)を実装し、現在の銘柄に対してOnBookEvent()がアクティブ化されたときのDOMデータの取得をテストします。

各注文のプロパティは、DOMでデータを提供するMqlBookInfo構造体で設定されます。

  • ENUM_BOOK_TYPE列挙体からの注文タイプ
  • 注文価格
  • 注文量
  • 注文量(高精度)

DOMには、以下の4つの注文タイプがあります(ENUM_BOOK_TYPE列挙体から)。

  • 売り注文
  • 成行売り注文
  • 買い注文
  • 成行買い注文

ご覧のとおり、注文タイプには4つあります(2つは買いで2つは売り)。すべてのタイプの注文を2つに分割するには、既存のプロパティにもう1つのプロパティを追加する必要があります。これは、その方向(売りまたは買い)を示す注文ステータスです。これにより、すべての注文を需要と供給の2つにすばやく分割できます。

単一のDOMリクエストのオブジェクトは、注文オブジェクト(および他の多くのライブラリオブジェクト)と同様に作成されます。DOM抽象注文の基本オブジェクトと、注文タイプが指定された4つの子孫オブジェクトがあります。このようなオブジェクトを構築するという概念は、ライブラリ開発の最初の段階の第1部第2部でで検討されました。

    DOMを使用するためのクラスを実装する前に、新しいライブラリメッセージを追加し、ティックデータオブジェクトクラスをわずかに改善します。\MQL5\Include\DoEasy\Data.mqhに新しいメッセージインデックスを追加します。

       MSG_SYM_EVENT_SYMBOL_ADD,                          // Added symbol to Market Watch window
       MSG_SYM_EVENT_SYMBOL_DEL,                          // Symbol removed from Market Watch window
       MSG_SYM_EVENT_SYMBOL_SORT,                         // Changed location of symbols in Market Watch window
       MSG_SYM_SYMBOLS_MODE_CURRENT,                      // Work with current symbol only
       MSG_SYM_SYMBOLS_MODE_DEFINES,                      // Work with predefined symbol list
       MSG_SYM_SYMBOLS_MODE_MARKET_WATCH,                 // Work with Market Watch window symbols
       MSG_SYM_SYMBOLS_MODE_ALL,                          // Work with full list of all available symbols
       MSG_SYM_SYMBOLS_BOOK_ADD,                          // Subscribed to Depth of Market 
       MSG_SYM_SYMBOLS_BOOK_DEL,                          // Unsubscribed from Depth of Market 
       MSG_SYM_SYMBOLS_MODE_BOOK,                         // Subscription to Depth of Market
       MSG_SYM_SYMBOLS_ERR_BOOK_ADD,                      // Error subscribing to DOM
       MSG_SYM_SYMBOLS_ERR_BOOK_DEL,                      // Error unsubscribing from DOM
       
    //--- CAccount
    
    

    ...

    //--- CTickSeries
       MSG_TICKSERIES_TEXT_TICKSERIES,                    // Tick series
       MSG_TICKSERIES_ERR_GET_TICK_DATA,                  // Failed to get tick data
       MSG_TICKSERIES_FAILED_CREATE_TICK_DATA_OBJ,        // Failed to create tick data object
       MSG_TICKSERIES_FAILED_ADD_TO_LIST,                 // Failed to add tick data object to list
       MSG_TICKSERIES_TEXT_IS_NOT_USE,                    // Tick series not used. Set the flag using SetAvailable()
       MSG_TICKSERIES_REQUIRED_HISTORY_DAYS,              // Requested number of days
       
    //--- CMarketBookOrd
       MSG_MBOOK_ORD_TEXT_MBOOK_ORD,                      // Order in DOM
       MSG_MBOOK_ORD_VOLUME,                              // Volume
       MSG_MBOOK_ORD_VOLUME_REAL,                         // Extended accuracy volume
       MSG_MBOOK_ORD_STATUS_BUY,                          // Buy side
       MSG_MBOOK_ORD_STATUS_SELL,                         // Sell side
       MSG_MBOOK_ORD_TYPE_SELL,                           // Sell order
       MSG_MBOOK_ORD_TYPE_BUY,                            // Buy order 
       MSG_MBOOK_ORD_TYPE_SELL_MARKET,                    // Sell order by Market
       MSG_MBOOK_ORD_TYPE_BUY_MARKET,                     // Buy order by Market
    
      };
    //+------------------------------------------------------------------+
    
    

    また、新しく追加したインデックスに対応するメッセージテキストも追加します。

       {"В окно \"Обзор рынка\" добавлен символ","Added symbol to \"Market Watch\" window"},
       {"Из окна \"Обзор рынка\" удалён символ","Removed from \"Market Watch\" window"},
       {"Изменено расположение символов в окне \"Обзор рынка\"","Changed arrangement of symbols in \"Market Watch\" window"},
       {"Работа только с текущим символом","Work only with the current symbol"},
       {"Работа с предопределённым списком символов","Work with predefined list of symbols"},
       {"Работа с символами из окна \"Обзор рынка\"","Working with symbols from \"Market Watch\" window"},
       {"Работа с полным списком всех доступных символов","Work with full list of all available symbols"},
       {"Осуществлена подписка на стакан цен ","Subscribed to Depth of Market"},
       {"Осуществлена отписка от стакан цен ","Unsubscribed from Depth of Market"},
       {"Подписка на стакан цен","Subscription to Depth of Market"},
       {"Ошибка при подписке на стакан цен",""},
       {"Ошибка при отписке от стакан цен",""},
       
    //--- CAccount
    
    

    ...

    //--- CMarketBookOrd
       {"Заявка в стакане цен","Order in Depth of Market"},
       {"Объем","Volume"},
       {"Объем c повышенной точностью","Volume Real"},
       {"Сторона Buy","Buy side"},
       {"Сторона Sell","Sell side"},
       {"Заявка на продажу","Sell order"},
       {"Заявка на покупку","Buy order"},
       {"Заявка на продажу по рыночной цене","Sell order at market price"},
       {"Заявка на покупку по рыночной цене","Buy order at market price"},
       
      };
    //+---------------------------------------------------------------------+
    
    

    DOMをサブスクライブするときのエラーに関するメッセージの表示を、銘柄オブジェクトクラスの\MQL5\Include\DoEasy\Objects\Symbols\Symbol.mqhファイルに追加します。

    //+------------------------------------------------------------------+
    //| Subscribe to the Depth of Market                                 |
    //+------------------------------------------------------------------+
    bool CSymbol::BookAdd(void)
      {
       this.m_book_subscribed=(#ifdef __MQL5__ ::MarketBookAdd(this.m_name) #else false #endif);
       this.m_long_prop[SYMBOL_PROP_BOOKDEPTH_STATE]=this.m_book_subscribed;
       if(this.m_book_subscribed)
          ::Print(CMessage::Text(MSG_SYM_SYMBOLS_BOOK_ADD)+" "+this.m_name);
       else
          ::Print(CMessage::Text(MSG_SYM_SYMBOLS_ERR_BOOK_ADD)+": "+CMessage::Text(::GetLastError()));
       return this.m_book_subscribed;
      }
    //+------------------------------------------------------------------+
    
    

    サブスクリプション解除についても繰り返します。

    //+------------------------------------------------------------------+
    //| Close the market depth                                           |
    //+------------------------------------------------------------------+
    bool CSymbol::BookClose(void)
      {
    //--- If the DOM subscription flag is off, subscription is disabled (or not enabled yet). Return 'true'
       if(!this.m_book_subscribed)
          return true;
    //--- Save the result of unsubscribing from the DOM
       bool res=( #ifdef __MQL5__ ::MarketBookRelease(this.m_name) #else true #endif );
    //--- If unsubscribed successfully, reset the DOM subscription flag and write the status to the object property
       if(res)
         {
          this.m_long_prop[SYMBOL_PROP_BOOKDEPTH_STATE]=this.m_book_subscribed=false;
          ::Print(CMessage::Text(MSG_SYM_SYMBOLS_BOOK_DEL)+" "+this.m_name);
         }
       else
         {
          this.m_long_prop[SYMBOL_PROP_BOOKDEPTH_STATE]=this.m_book_subscribed=true;
          ::Print(CMessage::Text(MSG_SYM_SYMBOLS_ERR_BOOK_DEL)+": "+CMessage::Text(::GetLastError()));
         }
    //--- Return the result of unsubscribing from DOM
       return res;
      }
    //+------------------------------------------------------------------+
    
    

    \MQL5\Include\DoEasy\Objects\Ticks\TickSeries.mqhのティックシリーズクラスのティックシリーズ更新メソッドから、前の記事でテストのために残された銘柄チャートへのデバッグコメントの表示を削除します。

    //+------------------------------------------------------------------+
    //| Update the tick series list                                      |
    //+------------------------------------------------------------------+
    void CTickSeries::Refresh(void)
      {
       MqlTick ticks_array[];
       if(IsNewTick())
         {
          //--- Copy ticks from m_last_time time+1 ms to the end of history
          int err=ERR_SUCCESS;
          int total=::CopyTicksRange(this.Symbol(),ticks_array,COPY_TICKS_ALL,this.m_last_time+1,0);
          //--- If the ticks have been copied, create new tick data objects and add them to the list in the loop by their number
          if(total>0)
            {
             for(int i=0;i<total;i++)
               {
                //--- Create the tick object and add it to the list
                CDataTick *tick_obj=this.CreateNewTickObj(ticks_array[i]);
                if(tick_obj==NULL)
                   break;
                //--- Write the last tick time for subsequent copying of newly arrived ticks
                long end_time=ticks_array[::ArraySize(ticks_array)-1].time_msc;
                if(this.Symbol()=="AUDUSD")
                   Comment(DFUN,this.Symbol(),", copied=",total,", m_last_time=",TimeMSCtoString(m_last_time),", end_time=",TimeMSCtoString(end_time),", total=",DataTotal());
                this.m_last_time=end_time;
               }
             //--- If the number of ticks in the list exceeds the default maximum number,
             //--- remove the calculated number of tick objects from the end of the list
             if(this.DataTotal()>TICKSERIES_MAX_DATA_TOTAL)
               {
                int total_del=m_list_ticks.Total()-TICKSERIES_MAX_DATA_TOTAL;
                for(int j=0;j<total_del;j++)
                   this.m_list_ticks.Delete(j);
               }
            }
         }
      }
    //+------------------------------------------------------------------+
    
    

    前回の記事の前回と現在のティックタイムを特徴とする銘柄チャートコメントとして検証データを表示する必要があったため、最後のティック時間がm_last_time変数にすぐに設定されるようになりました。今ではそれは必要なく、時間はすぐに変数に保存されます。

    //+------------------------------------------------------------------+
    //| Update the tick series list                                      |
    //+------------------------------------------------------------------+
    void CTickSeries::Refresh(void)
      {
       MqlTick ticks_array[];
       if(IsNewTick())
         {
          //--- Copy ticks from m_last_time time+1 ms to the end of history
          int err=ERR_SUCCESS;
          int total=::CopyTicksRange(this.Symbol(),ticks_array,COPY_TICKS_ALL,this.m_last_time+1,0);
          //--- If the ticks have been copied, create new tick data objects and add them to the list in the loop by their number
          if(total>0)
            {
             for(int i=0;i<total;i++)
               {
                //--- Create the tick object and add it to the list
                CDataTick *tick_obj=this.CreateNewTickObj(ticks_array[i]);
                if(tick_obj==NULL)
                   break;
                //--- Write the last tick time for subsequent copying of newly arrived ticks
                this.m_last_time=ticks_array[::ArraySize(ticks_array)-1].time_msc;
               }
             //--- If the number of ticks in the list exceeds the default maximum number,
             //--- remove the calculated number of tick objects from the end of the list
             if(this.DataTotal()>TICKSERIES_MAX_DATA_TOTAL)
               {
                int total_del=m_list_ticks.Total()-TICKSERIES_MAX_DATA_TOTAL;
                for(int j=0;j<total_del;j++)
                   this.m_list_ticks.Delete(j);
               }
            }
         }
      }
    //+------------------------------------------------------------------+
    
    


    板情報における抽象注文オブジェクトのクラス

    すべてのライブラリオブジェクトがオブジェクトプロパティ定数を定義するための列挙セットを持つのと同様に、DOM注文の整数、実数、文字列オブジェクトプロパティの列挙も作成する必要があります。

    \MQL5\Include\DoEasy\Defines.mqhにDOM注文オブジェクトのプロパティとパラメータの列挙を追加します。DOMで各注文を処理するイベントモデルを実装するつもりはないので(ある時点で注文書にはすべての注文の現在の状態が表示され、それらの変更は次の状態につながり、次のOnBookEvent()のアクティブ化で処理されます)、すべてのオブジェクトの定数のIDを維持して同じ形式にするためにDOMイベントの最後のコードの後に次のイベントのコードを指定する定数を追加するだけです。

    //+------------------------------------------------------------------+
    //| Data for working with DOM                                        |
    //+------------------------------------------------------------------+
    //+------------------------------------------------------------------+
    //| List of possible DOM events                                      |
    //+------------------------------------------------------------------+
    #define MBOOK_ORD_EVENTS_NEXT_CODE  (SERIES_EVENTS_NEXT_CODE+1)   // The code of the next event after the last DOM event code
    //+------------------------------------------------------------------+
    
    

    単一のDOM注文の2つの可能な状態(売りまたは買い)を特徴とする列挙を定義します。

    //+------------------------------------------------------------------+
    //| Abstract DOM type (status)                                       |
    //+------------------------------------------------------------------+
    enum ENUM_MBOOK_ORD_STATUS
      {
       MBOOK_ORD_STATUS_BUY,                              // Buy side
       MBOOK_ORD_STATUS_SELL,                             // Sell side
      };
    //+------------------------------------------------------------------+
    
    

    DOM内のすべての注文をこれらのプロパティで並べ替えることで、これらのプロパティによって需要または供給のいずれかに属するDOM内のすべての注文をすばやく選択できます。

    次に、DOM注文オブジェクトプロパティの整数実数文字列プロパティの列挙を追加します。

    //+------------------------------------------------------------------+
    //| Integer properties of DOM order                                  |
    //+------------------------------------------------------------------+
    enum ENUM_MBOOK_ORD_PROP_INTEGER
      {
       MBOOK_ORD_PROP_STATUS = 0,                         // Order status
       MBOOK_ORD_PROP_TYPE,                               // Order type
       MBOOK_ORD_PROP_VOLUME,                             // Order volume
      }; 
    #define MBOOK_ORD_PROP_INTEGER_TOTAL (3)              // Total number of integer properties
    #define MBOOK_ORD_PROP_INTEGER_SKIP  (0)              // Number of integer DOM properties not used in sorting
    //+------------------------------------------------------------------+
    //| Real properties of DOM order                                     |
    //+------------------------------------------------------------------+
    enum ENUM_MBOOK_ORD_PROP_DOUBLE
      {
       MBOOK_ORD_PROP_PRICE = MBOOK_ORD_PROP_INTEGER_TOTAL, // Order price
       MBOOK_ORD_PROP_VOLUME_REAL,                        // Extended accuracy order volume
      };
    #define MBOOK_ORD_PROP_DOUBLE_TOTAL  (2)              // Total number of real properties
    #define MBOOK_ORD_PROP_DOUBLE_SKIP   (0)              // Number of real properties not used in sorting
    //+------------------------------------------------------------------+
    //| String properties of DOM order                                   |
    //+------------------------------------------------------------------+
    enum ENUM_MBOOK_ORD_PROP_STRING
      {
       MBOOK_ORD_PROP_SYMBOL = (MBOOK_ORD_PROP_INTEGER_TOTAL+MBOOK_ORD_PROP_DOUBLE_TOTAL), // Order symbol name
      };
    #define MBOOK_ORD_PROP_STRING_TOTAL  (1)              // Total number of string properties
    //+------------------------------------------------------------------+
    
    

    作成されたプロパティに従ってDOMで注文を並べ替える可能性のある基準の列挙を実装しましょう。

    //+------------------------------------------------------------------+
    //| Possible sorting criteria of DOM orders                          |
    //+------------------------------------------------------------------+
    #define FIRST_MB_DBL_PROP  (MBOOK_ORD_PROP_INTEGER_TOTAL-MBOOK_ORD_PROP_INTEGER_SKIP)
    #define FIRST_MB_STR_PROP  (MBOOK_ORD_PROP_INTEGER_TOTAL-MBOOK_ORD_PROP_INTEGER_SKIP+MBOOK_ORD_PROP_DOUBLE_TOTAL-MBOOK_ORD_PROP_DOUBLE_SKIP)
    enum ENUM_SORT_MBOOK_ORD_MODE
      {
    //--- Sort by integer properties
       SORT_BY_MBOOK_ORD_STATUS = 0,                      // Sort by order status
       SORT_BY_MBOOK_ORD_TYPE,                            // Sort by order type
       SORT_BY_MBOOK_ORD_VOLUME,                          // Sort by order volume
    //--- Sort by real properties
       SORT_BY_MBOOK_ORD_PRICE = FIRST_MB_DBL_PROP,       // Sort by order price
       SORT_BY_MBOOK_ORD_VOLUME_REAL,                     // Sort by extended accuracy order volume
    //--- Sort by string properties
       SORT_BY_MBOOK_ORD_SYMBOL = FIRST_MB_STR_PROP,      // Sort by symbol name
      };
    //+------------------------------------------------------------------+
    
    

    これで、DOMで抽象注文オブジェクトクラスを作成できるようになりました。

    \MQL5\Include\DoEasy\Objects\で、すべてのCBaseObjライブラリオブジェクトの基本オブジェクトから継承されたCMarketBookOrdクラスのMarketBookOrd.mqhファイルを含む新しいBook\フォルダを作成します 。

    //+------------------------------------------------------------------+
    //|                                                MarketBookOrd.mqh |
    //|                        Copyright 2021, MetaQuotes Software Corp. |
    //|                             https://mql5.com/en/users/artmedia70 |
    //+------------------------------------------------------------------+
    #property copyright "Copyright 2021, MetaQuotes Software Corp."
    #property link      "https://mql5.com/en/users/artmedia70"
    #property version   "1.00"
    #property strict    // Necessary for mql4
    //+------------------------------------------------------------------+
    //| Include files                                                    |
    //+------------------------------------------------------------------+
    #include "..\..\Services\DELib.mqh"
    #include "..\..\Objects\BaseObj.mqh"
    //+------------------------------------------------------------------+
    //| DOM abstract order class                                         |
    //+------------------------------------------------------------------+
    class CMarketBookOrd : public CBaseObj
      {
    private:
       int               m_digits;                                       // Number of decimal places
       long              m_long_prop[MBOOK_ORD_PROP_INTEGER_TOTAL];      // Integer properties
       double            m_double_prop[MBOOK_ORD_PROP_DOUBLE_TOTAL];     // Real properties
       string            m_string_prop[MBOOK_ORD_PROP_STRING_TOTAL];     // String properties
    
    //--- Return the index of the array the (1) double and (2) string properties are actually located at
       int               IndexProp(ENUM_MBOOK_ORD_PROP_DOUBLE property)  const { return(int)property-MBOOK_ORD_PROP_INTEGER_TOTAL;                              }
       int               IndexProp(ENUM_MBOOK_ORD_PROP_STRING property)  const { return(int)property-MBOOK_ORD_PROP_INTEGER_TOTAL-MBOOK_ORD_PROP_DOUBLE_TOTAL;  }
    
    public:
    //--- Set object's (1) integer, (2) real and (3) string properties
       void              SetProperty(ENUM_MBOOK_ORD_PROP_INTEGER property,long value)   { this.m_long_prop[property]=value;                      }
       void              SetProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property,double value)  { this.m_double_prop[this.IndexProp(property)]=value;    }
       void              SetProperty(ENUM_MBOOK_ORD_PROP_STRING property,string value)  { this.m_string_prop[this.IndexProp(property)]=value;    }
    //--- Return object’s (1) integer, (2) real and (3) string property from the properties array
       long              GetProperty(ENUM_MBOOK_ORD_PROP_INTEGER property)        const { return this.m_long_prop[property];                     }
       double            GetProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property)         const { return this.m_double_prop[this.IndexProp(property)];   }
       string            GetProperty(ENUM_MBOOK_ORD_PROP_STRING property)         const { return this.m_string_prop[this.IndexProp(property)];   }
    //--- Return itself
       CMarketBookOrd   *GetObject(void)                                                { return &this;}
    
    //--- Return the flag of the object supporting this property
       virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property)          { return true; }
       virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property)           { return true; }
       virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_STRING property)           { return true; }
    
    //--- Get description of (1) integer, (2) real and (3) string properties
       string            GetPropertyDescription(ENUM_MBOOK_ORD_PROP_INTEGER property);
       string            GetPropertyDescription(ENUM_MBOOK_ORD_PROP_DOUBLE property);
       string            GetPropertyDescription(ENUM_MBOOK_ORD_PROP_STRING property);
    
    //--- Display the description of object properties in the journal (full_prop=true - all properties, false - supported ones only)
       void              Print(const bool full_prop=false);
    //--- Display a short description of the object in the journal
       virtual void      PrintShort(void);
    //--- Return the object short name
       virtual string    Header(void);
       
    //--- Compare CMarketBookOrd objects by all possible properties (to sort the lists by a specified order object property)
       virtual int       Compare(const CObject *node,const int mode=0) const;
    //--- Compare CMarketBookOrd objects by all properties (to search for equal request objects)
       bool              IsEqual(CMarketBookOrd* compared_req) const;
       
    //--- Default constructor
                         CMarketBookOrd(){;}
    protected:
    //--- Protected parametric constructor
                         CMarketBookOrd(const ENUM_MBOOK_ORD_STATUS status,const MqlBookInfo &book_info,const string symbol);
                         
    public:
    //+-------------------------------------------------------------------+ 
    //|Methods of a simplified access to the DOM request object properties|
    //+-------------------------------------------------------------------+
    //--- Return order (1) status, (2) type and (3) order volume
       ENUM_MBOOK_ORD_STATUS Status(void)        const { return (ENUM_MBOOK_ORD_STATUS)this.GetProperty(MBOOK_ORD_PROP_STATUS);   }
       ENUM_BOOK_TYPE    TypeOrd(void)           const { return (ENUM_BOOK_TYPE)this.GetProperty(MBOOK_ORD_PROP_TYPE);            }
       long              Volume(void)            const { return this.GetProperty(MBOOK_ORD_PROP_VOLUME);                          }
    //--- Return (1) the price and (2) extended accuracy order volume
       double            Price(void)             const { return this.GetProperty(MBOOK_ORD_PROP_PRICE);                           }
       double            VolumeReal(void)        const { return this.GetProperty(MBOOK_ORD_PROP_VOLUME_REAL);                     }
    //--- Return (1) order symbol and (2) symbol's Digits
       string            Symbol(void)            const { return this.GetProperty(MBOOK_ORD_PROP_SYMBOL);                          }
       int               Digits()                const { return this.m_digits;                                                    }
       
    //--- Return the description of order  (1) type (ENUM_BOOK_TYPE) and (2) status (ENUM_MBOOK_ORD_STATUS)
       virtual string    TypeDescription(void)   const { return this.StatusDescription();                                         }
       string            StatusDescription(void) const;
    
      };
    //+------------------------------------------------------------------+
    
    

    クラスの構成は、他のクラスのライブラリオブジェクトとまったく同じです。それらについては頻繁に言及してきました。詳細な説明は、最初と後続の記事にあります。

    クラスメソッドの実装を見てみましょう。

    クラスのクローズドパラメトリックコンストラクタで、DOMからコンストラクタに渡される注文構造体からすべてのオブジェクトプロパティを設定します。

    //+------------------------------------------------------------------+
    //| Parametric constructor                                           |
    //+------------------------------------------------------------------+
    CMarketBookOrd::CMarketBookOrd(const ENUM_MBOOK_ORD_STATUS status,const MqlBookInfo &book_info,const string symbol)
      {
    //--- Save symbol’s Digits
       this.m_digits=(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS);
    //--- Save integer object properties
       this.SetProperty(MBOOK_ORD_PROP_STATUS,status);
       this.SetProperty(MBOOK_ORD_PROP_TYPE,book_info.type);
       this.SetProperty(MBOOK_ORD_PROP_VOLUME,book_info.volume);
    //--- Save real object properties
       this.SetProperty(MBOOK_ORD_PROP_PRICE,book_info.price);
       this.SetProperty(MBOOK_ORD_PROP_VOLUME_REAL,book_info.volume_real);
    //--- Save additional object properties
       this.SetProperty(MBOOK_ORD_PROP_SYMBOL,(symbol==NULL || symbol=="" ? ::Symbol() : symbol));
      }
    //+------------------------------------------------------------------+
    
    

    コンストラクタは、新しいDOM注文オブジェクトを作成するときに、クラスの子孫オブジェクトで指定された注文ステータスも受け取ります。

    以下は、2つのCMarketBookOrdオブジェクトの指定されたプロパティの同等性を定義するための、指定されたプロパティによって2つのCMarketBookOrdオブジェクトを比較するメソッドです。

    //+------------------------------------------------------------------+
    //| Compare CMarketBookOrd objects                                   |
    //| by a specified property                                          |
    //+------------------------------------------------------------------+
    int CMarketBookOrd::Compare(const CObject *node,const int mode=0) const
      {
       const CMarketBookOrd *obj_compared=node;
    //--- compare integer properties of two objects
       if(mode<MBOOK_ORD_PROP_INTEGER_TOTAL)
         {
          long value_compared=obj_compared.GetProperty((ENUM_MBOOK_ORD_PROP_INTEGER)mode);
          long value_current=this.GetProperty((ENUM_MBOOK_ORD_PROP_INTEGER)mode);
          return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
         }
    //--- compare real properties of two objects
       else if(mode<MBOOK_ORD_PROP_DOUBLE_TOTAL+MBOOK_ORD_PROP_INTEGER_TOTAL)
         {
          double value_compared=obj_compared.GetProperty((ENUM_MBOOK_ORD_PROP_DOUBLE)mode);
          double value_current=this.GetProperty((ENUM_MBOOK_ORD_PROP_DOUBLE)mode);
          return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
         }
    //--- compare string properties of two objects
       else if(mode<MBOOK_ORD_PROP_DOUBLE_TOTAL+MBOOK_ORD_PROP_INTEGER_TOTAL+MBOOK_ORD_PROP_STRING_TOTAL)
         {
          string value_compared=obj_compared.GetProperty((ENUM_MBOOK_ORD_PROP_STRING)mode);
          string value_current=this.GetProperty((ENUM_MBOOK_ORD_PROP_STRING)mode);
          return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
         }
       return 0;
      }
    //+------------------------------------------------------------------+
    
    

    このメソッドは、プロパティを現在のオブジェクトの同じプロパティと比較する必要があるオブジェクトを受け取ります。比較対象のオブジェクトの指定されたプロパティ値が現在の値よりも低い場合、プロパティが等しい場合、より大きな場合は-1が返され、0が返されます。

    以下は、すべてのプロパティによって2つのCMarketBookOrdオブジェクトを比較するメソッドです。これにより、比較された2つのオブジェクトの完全なIDを判別できます。

    //+------------------------------------------------------------------+
    //| Compare CMarketBookOrd objects by all properties                 |
    //+------------------------------------------------------------------+
    bool CMarketBookOrd::IsEqual(CMarketBookOrd *compared_obj) const
      {
       int beg=0, end=MBOOK_ORD_PROP_INTEGER_TOTAL;
       for(int i=beg; i<end; i++)
         {
          ENUM_MBOOK_ORD_PROP_INTEGER prop=(ENUM_MBOOK_ORD_PROP_INTEGER)i;
          if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return false; 
         }
       beg=end; end+=MBOOK_ORD_PROP_DOUBLE_TOTAL;
       for(int i=beg; i<end; i++)
         {
          ENUM_MBOOK_ORD_PROP_DOUBLE prop=(ENUM_MBOOK_ORD_PROP_DOUBLE)i;
          if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return false; 
         }
       beg=end; end+=MBOOK_ORD_PROP_STRING_TOTAL;
       for(int i=beg; i<end; i++)
         {
          ENUM_MBOOK_ORD_PROP_STRING prop=(ENUM_MBOOK_ORD_PROP_STRING)i;
          if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return false; 
         }
       return true;
      }
    //+------------------------------------------------------------------+
    
    

    ここでは、2つのオブジェクトの後続の各プロパティが1つずつ比較されます。オブジェクトが等しくない場合、falseが返されます。2つのオブジェクトのすべてのプロパティが等しいことを確認し、falseが取得されなかった場合は、trueを返します。両方のオブジェクトは完全に同一です。

    以下は、操作ログ内のすべてのオブジェクトプロパティを表示するメソッドです。

    //+------------------------------------------------------------------+
    //| Display object properties in the journal                         |
    //+------------------------------------------------------------------+
    void CMarketBookOrd::Print(const bool full_prop=false)
      {
       ::Print("============= ",CMessage::Text(MSG_LIB_PARAMS_LIST_BEG)," (",this.Header(),") =============");
       int beg=0, end=MBOOK_ORD_PROP_INTEGER_TOTAL;
       for(int i=beg; i<end; i++)
         {
          ENUM_MBOOK_ORD_PROP_INTEGER prop=(ENUM_MBOOK_ORD_PROP_INTEGER)i;
          if(!full_prop && !this.SupportProperty(prop)) continue;
          ::Print(this.GetPropertyDescription(prop));
         }
       ::Print("------");
       beg=end; end+=MBOOK_ORD_PROP_DOUBLE_TOTAL;
       for(int i=beg; i<end; i++)
         {
          ENUM_MBOOK_ORD_PROP_DOUBLE prop=(ENUM_MBOOK_ORD_PROP_DOUBLE)i;
          if(!full_prop && !this.SupportProperty(prop)) continue;
          ::Print(this.GetPropertyDescription(prop));
         }
       ::Print("------");
       beg=end; end+=MBOOK_ORD_PROP_STRING_TOTAL;
       for(int i=beg; i<end; i++)
         {
          ENUM_MBOOK_ORD_PROP_STRING prop=(ENUM_MBOOK_ORD_PROP_STRING)i;
          if(!full_prop && !this.SupportProperty(prop)) continue;
          ::Print(this.GetPropertyDescription(prop));
         }
       ::Print("============= ",CMessage::Text(MSG_LIB_PARAMS_LIST_END)," (",this.Header(),") =============\n");
      }
    //+------------------------------------------------------------------+
    
    

    後続の各プロパティの文字列の説明は、整数、実数、文字列オブジェクトのプロパティごとに3つのループで表示されます。

    以下は、整数実数文字列オブジェクトプロパティの説明を返すメソッドです。

    //+------------------------------------------------------------------+
    //| Return description of object's integer property                  |
    //+------------------------------------------------------------------+
    string CMarketBookOrd::GetPropertyDescription(ENUM_MBOOK_ORD_PROP_INTEGER property)
      {
       return
         (
          property==MBOOK_ORD_PROP_STATUS        ?  CMessage::Text(MSG_ORD_STATUS)+
             (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
              ": "+this.StatusDescription()
             )  :
          property==MBOOK_ORD_PROP_TYPE          ?  CMessage::Text(MSG_ORD_TYPE)+
             (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
              ": "+this.TypeDescription()
             )  :
          property==MBOOK_ORD_PROP_VOLUME        ?  CMessage::Text(MSG_MBOOK_ORD_VOLUME)+
             (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
              ": "+(string)this.GetProperty(property)
             )  :
          ""
         );
      }
    //+------------------------------------------------------------------+
    //| Return description of object's real property                     |
    //+------------------------------------------------------------------+
    string CMarketBookOrd::GetPropertyDescription(ENUM_MBOOK_ORD_PROP_DOUBLE property)
      {
       int dg=(this.m_digits>0 ? this.m_digits : 1);
       return
         (
          property==MBOOK_ORD_PROP_PRICE         ?  CMessage::Text(MSG_LIB_TEXT_REQUEST_PRICE)+
             (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
              ": "+::DoubleToString(this.GetProperty(property),dg)
             )  :
          property==MBOOK_ORD_PROP_VOLUME_REAL   ?  CMessage::Text(MSG_MBOOK_ORD_VOLUME_REAL)+
             (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
              ": "+::DoubleToString(this.GetProperty(property),dg)
             )  :
          ""
         );
      }
    //+------------------------------------------------------------------+
    //| Return description of object's string property                   |
    //+------------------------------------------------------------------+
    string CMarketBookOrd::GetPropertyDescription(ENUM_MBOOK_ORD_PROP_STRING property)
      {
       return(property==MBOOK_ORD_PROP_SYMBOL ? CMessage::Text(MSG_LIB_PROP_SYMBOL)+": \""+this.GetProperty(property)+"\"" : "");
      }
    //+------------------------------------------------------------------+
    
    

    各メソッドは、説明を返す必要があるプロパティを受け取ります。メソッドに渡されたプロパティに応じて、メソッドから最終的に返される文字列が作成されます。

    以下は、短いオブジェクト名を返すメソッドです。

    //+------------------------------------------------------------------+
    //| Return the object short name                                     |
    //+------------------------------------------------------------------+
    string CMarketBookOrd::Header(void)
      {
       return this.TypeDescription()+" \""+this.Symbol()+"\"";
      }
    //+------------------------------------------------------------------+
    
    

    このメソッドは、注文タイプの説明とその銘柄で構成される文字列を返します。

    以下は、操作ログに短いオブジェクトの説明を表示するメソッドです。

    //+------------------------------------------------------------------+
    //| Display a short description of the object in the journal         |
    //+------------------------------------------------------------------+
    void CMarketBookOrd::PrintShort(void)
      {
       ::Print(this.Header());
      }
    //+------------------------------------------------------------------+
    
    

    このメソッドは、前のメソッドで作成された文字列を操作ログに表示するだけです。

    以下は、DOMの注文ステータスの説明を返すメソッドです。

    //+------------------------------------------------------------------+
    //| Return the order status description in DOM                       |
    //+------------------------------------------------------------------+
    string CMarketBookOrd::StatusDescription(void) const
      {
       return
         (
          Status()==MBOOK_ORD_STATUS_SELL  ?  CMessage::Text(MSG_MBOOK_ORD_STATUS_SELL) :
          Status()==MBOOK_ORD_STATUS_BUY   ?  CMessage::Text(MSG_MBOOK_ORD_STATUS_BUY)  :
          ""
         );
      }
    //+------------------------------------------------------------------+
    
    

    注文「ステータス」に応じて、ステータスの説明を含む文字列が返されます。

    DOM注文オブジェクトクラスはこれですべてです。

    次に、この抽象注文オブジェクトから継承する4つのクラスを作成する必要があります。子孫クラスはDOMから新しい注文オブジェクトを作成するために使用されます。 作成された注文オブジェクトのステータスは、注文タイプに応じて、子孫クラスコンストラクタの初期化リストで指定されます。


    抽象注文オブジェクトの子孫クラス

    \MQL5\Include\DoEasy\Objects\Book\に、CMarketBookBuyクラスのMarketBookBuy.mqhファイルを作成します。新しく作成されたCMarketBookOrd抽象注文クラスは親クラスになります

    //+------------------------------------------------------------------+
    //|                                                MarketBookBuy.mqh |
    //|                        Copyright 2021, MetaQuotes Software Corp. |
    //|                             https://mql5.com/en/users/artmedia70 |
    //+------------------------------------------------------------------+
    #property copyright "Copyright 2021, MetaQuotes Software Corp."
    #property link      "https://mql5.com/en/users/artmedia70"
    #property version   "1.00"
    //+------------------------------------------------------------------+
    //| Include files                                                    |
    //+------------------------------------------------------------------+
    #include "MarketBookOrd.mqh"
    //+------------------------------------------------------------------+
    //| Buy order in DOM                                                 |
    //+------------------------------------------------------------------+
    class CMarketBookBuy : public CMarketBookOrd
      {
    private:
    
    public:
       //--- Constructor
                         CMarketBookBuy(const string symbol,const MqlBookInfo &book_info) :
                            CMarketBookOrd(MBOOK_ORD_STATUS_BUY,book_info,symbol) {}
       //--- Supported order properties (1) real, (2) integer
       virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property);
       virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property);
    //--- Return the object short name
       virtual string    Header(void);
    //--- Return the description of order type (ENUM_BOOK_TYPE)
       virtual string    TypeDescription(void);
      };
    //+------------------------------------------------------------------+
    //| Return 'true' if an order supports a passed                      |
    //| integer property, otherwise return 'false'                       |
    //+------------------------------------------------------------------+
    bool CMarketBookBuy::SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property)
      {
       return true;
      }
    //+------------------------------------------------------------------+
    //| Return 'true' if an order supports a passed                      |
    //| real property, otherwise return 'false'                          |
    //+------------------------------------------------------------------+
    bool CMarketBookBuy::SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property)
      {
       return true;
      }
    //+------------------------------------------------------------------+
    //| Return the object short name                                     |
    //+------------------------------------------------------------------+
    string CMarketBookBuy::Header(void)
      {
       return CMessage::Text(MSG_MBOOK_ORD_TYPE_BUY)+" \""+this.Symbol()+
              "\": "+::DoubleToString(this.Price(),this.Digits())+" ["+::DoubleToString(this.VolumeReal(),2)+"]";
      }
    //+------------------------------------------------------------------+
    //| Return the description of order type                             |
    //+------------------------------------------------------------------+
    string CMarketBookBuy::TypeDescription(void)
      {
       return CMessage::Text(MSG_MBOOK_ORD_TYPE_BUY);
      }
    //+------------------------------------------------------------------+
    
    

    新しいDOM注文オブジェクトを作成するときは、親クラスコンストラクタで「買い側」を設定します

    整数および実数プロパティをサポートするフラグを返す仮想メソッドでは、trueを返します。各プロパティはオブジェクトによってサポートされます。

    DOM注文オブジェクトの短い名前を返す仮想メソッドで、次の形式で文字列を返します。

    タイプ "銘柄": 価格 [VolumeReal]

    以下は例です。

    "EURUSD" buy order: 1.20123 [10.00]

    DOM注文オブジェクトタイプの説明を返す仮想メソッドで、文字列「Buy order」を返します。

    DOM抽象注文基本クラスから継承された残りの3つのクラスは、注文ステータスを除いて、検討対象のクラスと同じです。各クラスコンストラクタは、記述された注文オブジェクトに対応するステータスと、各オブジェクトによって記述されたDOM注文タイプに対応する文字列を返す仮想メソッドを備えています。これらのクラスはすべて、上記のフォルダと同じフォルダにあります。ここにそれらのリストを表示して、仮想メソッドを分析および比較できるようにします。

    MarketBookBuyMarket.mqh:

    //+------------------------------------------------------------------+
    //|                                          MarketBookBuyMarket.mqh |
    //|                        Copyright 2021, MetaQuotes Software Corp. |
    //|                             https://mql5.com/en/users/artmedia70 |
    //+------------------------------------------------------------------+
    #property copyright "Copyright 2021, MetaQuotes Software Corp."
    #property link      "https://mql5.com/en/users/artmedia70"
    #property version   "1.00"
    //+------------------------------------------------------------------+
    //| Include files                                                    |
    //+------------------------------------------------------------------+
    #include "MarketBookOrd.mqh"
    //+------------------------------------------------------------------+
    //| Buy order by Market in DOM                                       |
    //+------------------------------------------------------------------+
    class CMarketBookBuyMarket : public CMarketBookOrd
      {
    private:
    
    public:
       //--- Constructor
                         CMarketBookBuyMarket(const string symbol,const MqlBookInfo &book_info) :
                            CMarketBookOrd(MBOOK_ORD_STATUS_BUY,book_info,symbol) {}
       //--- Supported order properties (1) real, (2) integer
       virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property);
       virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property);
    //--- Return the object short name
       virtual string    Header(void);
    //--- Return the description of order type (ENUM_BOOK_TYPE)
       virtual string    TypeDescription(void);
      };
    //+------------------------------------------------------------------+
    //| Return 'true' if an order supports a passed                      |
    //| integer property, otherwise return 'false'                       |
    //+------------------------------------------------------------------+
    bool CMarketBookBuyMarket::SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property)
      {
       return true;
      }
    //+------------------------------------------------------------------+
    //| Return 'true' if an order supports a passed                      |
    //| real property, otherwise return 'false'                          |
    //+------------------------------------------------------------------+
    bool CMarketBookBuyMarket::SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property)
      {
       return true;
      }
    //+------------------------------------------------------------------+
    //| Return the object short name                                     |
    //+------------------------------------------------------------------+
    string CMarketBookBuyMarket::Header(void)
      {
       return CMessage::Text(MSG_MBOOK_ORD_TYPE_BUY_MARKET)+" \""+this.Symbol()+
              "\": "+::DoubleToString(this.Price(),this.Digits())+" ["+::DoubleToString(this.VolumeReal(),2)+"]";
      }
    //+------------------------------------------------------------------+
    //| Return the description of order type                             |
    //+------------------------------------------------------------------+
    string CMarketBookBuyMarket::TypeDescription(void)
      {
       return CMessage::Text(MSG_MBOOK_ORD_TYPE_BUY_MARKET);
      }
    //+------------------------------------------------------------------+
    
    

    MarketBookSell.mqh:

    //+------------------------------------------------------------------+
    //|                                               MarketBookSell.mqh |
    //|                        Copyright 2021, MetaQuotes Software Corp. |
    //|                             https://mql5.com/en/users/artmedia70 |
    //+------------------------------------------------------------------+
    #property copyright "Copyright 2021, MetaQuotes Software Corp."
    #property link      "https://mql5.com/en/users/artmedia70"
    #property version   "1.00"
    //+------------------------------------------------------------------+
    //| Include files                                                    |
    //+------------------------------------------------------------------+
    #include "MarketBookOrd.mqh"
    //+------------------------------------------------------------------+
    //| Sell order in DOM                                                |
    //+------------------------------------------------------------------+
    class CMarketBookSell : public CMarketBookOrd
      {
    private:
    
    public:
       //--- Constructor
                         CMarketBookSell(const string symbol,const MqlBookInfo &book_info) :
                            CMarketBookOrd(MBOOK_ORD_STATUS_SELL,book_info,symbol) {}
       //--- Supported order properties (1) real, (2) integer
       virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property);
       virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property);
    //--- Return the object short name
       virtual string    Header(void);
    //--- Return the description of order type (ENUM_BOOK_TYPE)
       virtual string    TypeDescription(void);
      };
    //+------------------------------------------------------------------+
    //| Return 'true' if an order supports a passed                      |
    //| integer property, otherwise return 'false'                       |
    //+------------------------------------------------------------------+
    bool CMarketBookSell::SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property)
      {
       return true;
      }
    //+------------------------------------------------------------------+
    //| Return 'true' if an order supports a passed                      |
    //| real property, otherwise return 'false'                          |
    //+------------------------------------------------------------------+
    bool CMarketBookSell::SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property)
      {
       return true;
      }
    //+------------------------------------------------------------------+
    //| Return the object short name                                     |
    //+------------------------------------------------------------------+
    string CMarketBookSell::Header(void)
      {
       return CMessage::Text(MSG_MBOOK_ORD_TYPE_SELL)+" \""+this.Symbol()+
              "\": "+::DoubleToString(this.Price(),this.Digits())+" ["+::DoubleToString(this.VolumeReal(),2)+"]";
      }
    //+------------------------------------------------------------------+
    //| Return the description of order type                             |
    //+------------------------------------------------------------------+
    string CMarketBookSell::TypeDescription(void)
      {
       return CMessage::Text(MSG_MBOOK_ORD_TYPE_SELL);
      }
    //+------------------------------------------------------------------+
    
    

    MarketBookSellMarket.mqh:

    //+------------------------------------------------------------------+
    //|                                         MarketBookSellMarket.mqh |
    //|                        Copyright 2021, MetaQuotes Software Corp. |
    //|                             https://mql5.com/en/users/artmedia70 |
    //+------------------------------------------------------------------+
    #property copyright "Copyright 2021, MetaQuotes Software Corp."
    #property link      "https://mql5.com/en/users/artmedia70"
    #property version   "1.00"
    //+------------------------------------------------------------------+
    //| Include files                                                    |
    //+------------------------------------------------------------------+
    #include "MarketBookOrd.mqh"
    //+------------------------------------------------------------------+
    //| Sell order by Market in DOM                                      |
    //+------------------------------------------------------------------+
    class CMarketBookSellMarket : public CMarketBookOrd
      {
    private:
    
    public:
       //--- Constructor
                         CMarketBookSellMarket(const string symbol,const MqlBookInfo &book_info) :
                            CMarketBookOrd(MBOOK_ORD_STATUS_SELL,book_info,symbol) {}
       //--- Supported order properties (1) real, (2) integer
       virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property);
       virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property);
    //--- Return the object short name
       virtual string    Header(void);
    //--- Return the description of order type (ENUM_BOOK_TYPE)
       virtual string    TypeDescription(void);
      };
    //+------------------------------------------------------------------+
    //| Return 'true' if an order supports a passed                      |
    //| integer property, otherwise return 'false'                       |
    //+------------------------------------------------------------------+
    bool CMarketBookSellMarket::SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property)
      {
       return true;
      }
    //+------------------------------------------------------------------+
    //| Return 'true' if an order supports a passed                      |
    //| real property, otherwise return 'false'                          |
    //+------------------------------------------------------------------+
    bool CMarketBookSellMarket::SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property)
      {
       return true;
      }
    //+------------------------------------------------------------------+
    //| Return the object short name                                     |
    //+------------------------------------------------------------------+
    string CMarketBookSellMarket::Header(void)
      {
       return CMessage::Text(MSG_MBOOK_ORD_TYPE_SELL_MARKET)+" \""+this.Symbol()+
              "\": "+::DoubleToString(this.Price(),this.Digits())+" ["+::DoubleToString(this.VolumeReal(),2)+"]";
      }
    //+------------------------------------------------------------------+
    //| Return the description of order type                             |
    //+------------------------------------------------------------------+
    string CMarketBookSellMarket::TypeDescription(void)
      {
       return CMessage::Text(MSG_MBOOK_ORD_TYPE_SELL_MARKET);
      }
    //+------------------------------------------------------------------+
    
    

    今回の記事でやりたかったのはこれだけです。


    検証

    テストを実行するには、前の記事のEAを\MQL5\Experts\TestDoEasy\Part63\TestDoEasyPart63.mq5として保存します。

    EAを起動した後、仕事の設定で指定された銘柄のDOMをサブスクライブします。DOMを持つすべてのイベントは、 OnBookEvent()ハンドラに登録されます。したがって、このハンドラでは、イベントが現在の銘柄で発生したことを確認します。また、DOMスナップショットを取得し、既存のすべての注文を価格値で並び替えられたリストに保存します。次に、チャートのコメントのリストから最初と最後の注文を表示します。したがって、2つの極端なDOM注文(売りと買い)を表示します。操作ログで、最初のOnBookEvent()がアクティブ化した時に取得されたすべてのDOM注文のリストを表示します。

    EAが新しく作成されたクラスを表示できるようにするには、それらをEAファイルにインクルードします(現在、CEngineライブラリのメインオブジェクトからアクセスすることはできません)。

    //+------------------------------------------------------------------+
    //|                                             TestDoEasyPart63.mq5 |
    //|                        Copyright 2021, MetaQuotes Software Corp. |
    //|                             https://mql5.com/en/users/artmedia70 |
    //+------------------------------------------------------------------+
    #property copyright "Copyright 2021, MetaQuotes Software Corp."
    #property link      "https://mql5.com/en/users/artmedia70"
    #property version   "1.00"
    //--- includes
    #include <DoEasy\Engine.mqh>
    #include <DoEasy\Objects\Book\MarketBookBuy.mqh>
    #include <DoEasy\Objects\Book\MarketBookSell.mqh>
    #include <DoEasy\Objects\Book\MarketBookBuyMarket.mqh>
    #include <DoEasy\Objects\Book\MarketBookSellMarket.mqh>
    //--- enums
    
    

    次に、EAでOnBookEvent()ハンドラを作成し、その中でDOMイベントの処理を実装する必要があります。

    //+------------------------------------------------------------------+
    //| OnBookEvent function                                             |
    //+------------------------------------------------------------------+
    void OnBookEvent(const string& symbol)
      {
       static bool first=true;
       //--- Get a symbol object
       CSymbol *sym=engine.GetSymbolCurrent();
       //--- If failed to get a symbol object or it is not subscribed to DOM, exit
       if(sym==NULL || !sym.BookdepthSubscription()) return;
       //--- create the list for storing DOM order objects
       CArrayObj *list=new CArrayObj();
       if(list==NULL) return;
       //--- Work by the current symbol
       if(symbol==sym.Name())
         {
          //--- Declare the DOM structure array
          MqlBookInfo book_array[];
          //--- Get DOM entries to the structure array
          if(!MarketBookGet(sym.Name(),book_array))
             return;
          //--- clear the list
          list.Clear();
          //--- In the loop by the structure array
          int total=ArraySize(book_array);
          for(int i=0;i<total;i++)
            {
             //--- Create order objects of the current DOM snapshot depending on the order type
             CMarketBookOrd *mbook_ord=NULL;
             switch(book_array[i].type)
               {
                case BOOK_TYPE_BUY         : mbook_ord=new CMarketBookBuy(sym.Name(),book_array[i]);         break;
                case BOOK_TYPE_SELL        : mbook_ord=new CMarketBookSell(sym.Name(),book_array[i]);        break;
                case BOOK_TYPE_BUY_MARKET  : mbook_ord=new CMarketBookBuyMarket(sym.Name(),book_array[i]);   break;
                case BOOK_TYPE_SELL_MARKET : mbook_ord=new CMarketBookSellMarket(sym.Name(),book_array[i]);  break;
                default: break;
               }
             if(mbook_ord==NULL)
                continue;
             //--- Set the sorted list flag for the list (by the price value) and add the current order object to it
             list.Sort(SORT_BY_MBOOK_ORD_PRICE);
             if(!list.InsertSort(mbook_ord))
                delete mbook_ord;
            }
          //--- Get the very first and last DOM order objects from the list
          CMarketBookOrd *ord_0=list.At(0);
          CMarketBookOrd *ord_N=list.At(list.Total()-1);
          if(ord_0==NULL || ord_N==NULL) return;
          //--- Display the size of the current DOM snapshot in the chart comment, 
          //--- the maximum number of displayed orders in DOM for a symbol and
          //--- the highest and lowest orders of the current DOM snapshot
          Comment
            (
             DFUN,sym.Name(),": ",TimeMSCtoString(sym.Time()),", array total=",total,", book size=",sym.TicksBookdepth(),", list.Total: ",list.Total(),"\n",
             "Max: ",ord_N.Header(),"\nMin: ",ord_0.Header()
            );
          //--- Display the first DOM snapshot in the journal
          if(first)
            {
             for(int i=list.Total()-1;i>WRONG_VALUE;i--)
               {
                CMarketBookOrd *ord=list.At(i);
                ord.PrintShort();
               }
             first=false;
            }
         }
       //--- Delete the created list
       delete list;
      }
    //+------------------------------------------------------------------+
    
    

    コードのコメントにはすべての詳細が含まれています。質問がある場合は、コメント欄でお気軽にお問い合わせください。

    EAをコンパイルし、現在の銘柄と時間枠を使用するように設定で事前に定義されている銘柄チャートで起動します。


    EAが起動され、最初のDOM変更イベントが到着すると、現在のDOMスナップショットリストのパラメータが、最高の買いと最低の売りの2つの注文とともにグラフのコメントに表示されます。


    操作ログには、現在のDOMスナップショットのすべての注文のリストが表示されます。

    Subscribed to Depth of Market  AUDUSD
    Subscribed to Depth of Market  EURUSD
    Library initialization time: 00:00:11.391
    "EURUSD" sell order: 1.20250 [250.00]
    "EURUSD" sell order: 1.20245 [100.00]
    "EURUSD" sell order: 1.20244 [50.00]
    "EURUSD" sell order: 1.20242 [36.00]
    "EURUSD" buy order: 1.20240 [16.00]
    "EURUSD" buy order: 1.20239 [20.00]
    "EURUSD" buy order: 1.20238 [50.00]
    "EURUSD" buy order: 1.20236 [100.00]
    "EURUSD" buy order: 1.20232 [250.00]
    
    


    次の段階

    次の記事では、DOMを使用するための機能を引き続き作成します。

    ライブラリの現在のバージョンのすべてのファイルは、テストおよびダウンロードできるように、MQL5のテストEAファイルと一緒に以下に添付されています。
    DOMを使用するためのクラスは開発中であるため、この段階でカスタムプログラムで使用しないことを強くお勧めします。
    質問や提案はコメント欄にお願いします。

    目次に戻る

    *連載のこれまでの記事:

    DoEasyライブラリの時系列(第59部): 単一ティックのデータを格納するオブジェクト
    DoEasyライブラリでの価格(第60部): 銘柄ティックデータのシリーズリスト
    DoEasyライブラリでの価格(第61部): 銘柄ティックシリーズのコレクション
    DoEasyライブラリでの価格(第62部): ティックシリーズをリアルタイムで更新して板情報で作業するための準備

    MetaQuotes Ltdによってロシア語から翻訳されました。
    元の記事: https://www.mql5.com/ru/articles/9010

    添付されたファイル |
    MQL5.zip (3891.18 KB)
    DoEasyライブラリでの価格(第64部): 板情報、DOMスナップショットのクラスおよびスナップショットシリーズオブジェクト DoEasyライブラリでの価格(第64部): 板情報、DOMスナップショットのクラスおよびスナップショットシリーズオブジェクト
    本稿では、2つのクラス(DOMスナップショットオブジェクトのクラスとDOMスナップショットシリーズオブジェクトのクラス)を作成し、DOMデータシリーズの作成をテストします。
    DoEasyライブラリでの価格(第62部): ティックシリーズをリアルタイムで更新して板情報で作業するための準備 DoEasyライブラリでの価格(第62部): ティックシリーズをリアルタイムで更新して板情報で作業するための準備
    この記事では、ティックデータの更新をリアルタイムで実装し、板情報を操作するための銘柄オブジェクトクラスを準備します(DOM自体は次の記事で実装されます)。
    DoEasyライブラリでの価格(第65部): 板情報コレクションとMQL5.comシグナル操作クラス DoEasyライブラリでの価格(第65部): 板情報コレクションとMQL5.comシグナル操作クラス
    本稿では、すべての銘柄の板情報コレクションクラスを作成し、シグナルオブジェクトクラスを作成することによってMQL5.comシグナルサービスを使用するための機能の開発を開始します。
    自己適応アルゴリズム(第IV部):その他の機能とテスト 自己適応アルゴリズム(第IV部):その他の機能とテスト
    引き続き、必要最小限の機能でアルゴリズムを実装して結果をテストします。収益性は非常に低いですが、連載では、完全に自動化された、根本的に異なる市場で取引される完全に異なる商品で収益性の高い取引モデルを示しています。