【QuickFIX】12 マーケット情報要求 < V > MarketDataRequest

マーケットの情報をストリーミングで送信してくれ、と要求を投げます
要求が通ると CNEXサーバからレート情報がバンバン送られてくることになります


## Application.h ヘッダーファイル

```cpp:Application.h
・・・
  /* H  */ void OrderStatusRequest();
  /* V  */ void MarketDataRequest(
                    const std::string& target
                  , const bool& subType = FIX::SubscriptionRequestType_SNAPSHOT_PLUS_UPDATES
                  , const int depth = 1  /* 1=TopBook, 0=FullBook */
                  , const bool& aggregate = true /* true = Aggregate, false = NoAggregate */
                );
  /* AF */ void OrderMassStatusRequest();
  /* AN */ void RequestForPositions();
・・・

```

どの通貨ペアの情報を取得するのかを引数で指定できるようにしときます
ついでに情報取得を「開始」するのか「終了」するのかを第２引数に指定
（デフォルトでは「開始」）

第３引数には情報深度？を指定　
　１ ：TOP なら現在のレート情報のみを
　０ ：FULL なら現在のレートの上下５値？の板情報も取得です

第４引数の Aggregate はとりあえず true で


## < V > MarketDataRequest

```cpp:send_V__MarketDataRequest.cpp
#include "config.h"

#include "Application.h"
#include "quickfix/Session.h"
#include <iostream>

/* V  */
void Application::MarketDataRequest(
    const std::string& target
  , const bool& subType
  , const int depth
  , const bool& aggregate
)
{
  FIX44::MarketDataRequest message;

  /* 262  */ message.set(FIX::MDReqID( target ));
  /* 264  */ message.set(FIX::MarketDepth( depth )); /* 1=TopBook, 0=FullBook */
  /* 265  */ message.set(FIX::MDUpdateType( FIX::MDUpdateType_INCREMENTAL_REFRESH )); /* 1 Only */
  /* 266  */ message.set(FIX::AggregatedBook( aggregate )); /* true = Aggregate, false = NoAggregate */

  /* SubscriptionRequestType */
  char subTypeRequest;
  if ( subType )
  {
    subTypeRequest = FIX::SubscriptionRequestType_SNAPSHOT_PLUS_UPDATES;
    rate[ m_symbol[target] ].feedStatus = true;
  }
  else
  {
    subTypeRequest = FIX::SubscriptionRequestType_DISABLE_PREVIOUS_SNAPSHOT_PLUS_UPDATE_REQUEST;
    rate[ m_symbol[target] ].feedStatus = false;
  }
  /* 263  */ message.set(FIX::SubscriptionRequestType( subTypeRequest ));

  /* set entry type :: 要求する情報を設定（買値、売値） */
  std::vector<char>c;
  c.push_back(FIX::MDEntryType_BID);                           /* 0 売値 */
  c.push_back(FIX::MDEntryType_OFFER);                         /* 1 買値 */
  if( depth ) /* Top Book の場合に追加情報を要求 */
  {
    c.push_back(FIX::MDEntryType_TRADING_SESSION_HIGH_PRICE);  /* 7 高値 */
    c.push_back(FIX::MDEntryType_TRADING_SESSION_LOW_PRICE);   /* 8 安値 */
    c.push_back(FIX::MDEntryType_TRADING_SESSION_VWAP_PRICE);  /* 9 値幅 */
  }

  while( !c.empty() )
  {
    /* 267  */ FIX44::MarketDataRequest::NoMDEntryTypes entryType;
    /* 269  */ entryType.set(FIX::MDEntryType( c.back() ));
    c.pop_back();
    message.addGroup( entryType );
  }

  /* set target symbol :: 指定された通貨ペアを要求 */
  /* 146  */ FIX44::MarketDataRequest::NoRelatedSym symbolGroup;
  /* 55   */ symbolGroup.set( FIX::Symbol( target ));
  message.addGroup( symbolGroup );

  /* Symbol Record Insert :: 初回以外はエラーになるけど気にしない */
  FIX::MySQLQuery q1("insert into T_MARKET_DATA ( `Symbol`) VALUES ('"+ target +"');");
  m_sql->execute( q1 );

  /* Send Message */
  SetMessageHeader( message, SessionTypeRatefeed );
  FIX::Session::sendToTarget( message );

  //std::cout << "<V> MarketDataRequest: " << std::endl << message.toXML() << std::endl;
  LOG_DEBUG   << "<V> MarketDataRequest: " << std::endl << message;
  LOG_VERBOSE << "<V> MarketDataRequest: " << std::endl << message.toXML();
}

```

指定された通貨ペアについてレート情報要求します。
レート情報を受信した後に使うテーブルに通貨ペア情報をINSERTしときます。
※ バンバン送られてくるレート情報受信後の処理では判定とかしないで UPDATE だけで処理を組み立てたいので





## 引数の設定を変更したので呼び出し元も修正

```cpp:resp_y__SecurityList.cpp
・・・
    /* Get Market Data Rate */
    if( getRate )
    {
      /* <V> */ MarketDataRequest( symbol.getString() );
    }
・・・

```


## マーケット情報を保存するテーブルも準備

### T_MARKET_DATA 最新値のみを保持するテーブル

```sql:examples/tradeclient/sql/T_MARKET_DATA.sql
DROP TABLE IF EXISTS T_MARKET_DATA;
CREATE TABLE T_MARKET_DATA
(
  `Symbol`                VARCHAR(7)        NOT NULL                       COMMENT '55 ',
  `RespDateTime`          CHAR(21)          NULL                           COMMENT '52 yyyymmdd-HH:MM:SS.999',

  `BidOrders`             INT UNSIGNED      NULL                           COMMENT '269 0:Bid   - 346 Orders',
  `BidSize`               INT UNSIGNED      NULL                           COMMENT '269 0:Bid   - 271 Size',
  `Bid`                   REAL              NULL                           COMMENT '269 0:Bid   - 270 Px',
  `Spred`                 REAL              NULL                           COMMENT '269 9:Spred - 270 Px',
  `Offer`                 REAL              NULL                           COMMENT '269 1:Offer - 270 Px',
  `OfferSize`             INT UNSIGNED      NULL                           COMMENT '269 1:Offer - 271 Size',
  `OfferOrders`           INT UNSIGNED      NULL                           COMMENT '269 1:Offer - 346 Orders',

  `Created_at`            DATETIME          NOT NULL  DEFAULT CURRENT_TIMESTAMP,
  `Updated_at`            DATETIME          NOT NULL  DEFAULT CURRENT_TIMESTAMP   ON UPDATE CURRENT_TIMESTAMP,
  `Deleted_at`            DATETIME          NULL,
  PRIMARY KEY (`Symbol`)
)
COMMENT 'Market Data';

DESC T_MARKET_DATA;

```

### T_MARKET_DATA_HIST　マーケット情報の履歴を保持するテーブル

```sql:examples/tradeclient/sql/T_MARKET_DATA_HIST.sql
DROP TABLE IF EXISTS T_MARKET_DATA_HIST;
CREATE TABLE T_MARKET_DATA_HIST
(
  `id`                    INT UNSIGNED      NOT NULL  AUTO_INCREMENT       COMMENT 'id',

  `MDUpdateAction`        CHAR(1)           NOT NULL                       COMMENT '279 0:New 2:Delete ',
  `Symbol`                VARCHAR(7)        NOT NULL                       COMMENT '55 ',
  `RespDateTime`          CHAR(21)          NULL                           COMMENT '52 yyyymmdd-HH:MM:SS.999',

  `BidOrders`             INT UNSIGNED      NULL                           COMMENT '269 0:Bid   - 346 Orders',
  `BidSize`               INT UNSIGNED      NULL                           COMMENT '269 0:Bid   - 271 Size',
  `Bid`                   REAL              NULL                           COMMENT '269 0:Bid   - 270 Px',
  `Spred`                 REAL              NULL                           COMMENT '269 9:Spred - 270 Px',
  `Offer`                 REAL              NULL                           COMMENT '269 1:Offer - 270 Px',
  `OfferSize`             INT UNSIGNED      NULL                           COMMENT '269 1:Offer - 271 Size',
  `OfferOrders`           INT UNSIGNED      NULL                           COMMENT '269 1:Offer - 346 Orders',

  `Created_at`            DATETIME          NOT NULL  DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  INDEX `I_MARKET_HIST_Symbol` (`Symbol`)
)
COMMENT 'Market Data History';

DESC T_MARKET_DATA_HIST;

```


### T_MARKET_DATA_DETAIL　レートの板情報も保持するテーブル

```sql:examples/tradeclient/sql/T_MARKET_DATA_DETAIL.sql
DROP TABLE IF EXISTS T_MARKET_DATA_DETAIL;
CREATE TABLE T_MARKET_DATA_DETAIL
(
  `id`                    INT UNSIGNED      NOT NULL  AUTO_INCREMENT       COMMENT 'id',
  `histId`                INT UNSIGNED      NOT NULL                       COMMENT 'T_MARKET_DATA_HIST id',

  `type`                  CHAR(1)           NULL                           COMMENT '269 0:Bid 1:Offer',
  `px`                    REAL              NULL                           COMMENT '270 Px',
  `size`                  INT UNSIGNED      NULL                           COMMENT '271 Size',
  `orders`                INT UNSIGNED      NULL                           COMMENT '346 Orders',

  `Created_at`            DATETIME          NOT NULL  DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  INDEX `I_MARKET_DETAIL_histid` (`histId`)
)
COMMENT 'Market Data Detail';

DESC T_MARKET_DATA_DETAIL;


```



---

＜前 [【QuickFIX】11 ログ出力設定](https://qiita.com/nobu-maple/items/828d3859ebf2ab2237f8)
次＞ [【QuickFIX】13 マーケット情報受信 < X > MarketDataIncrementalRefresh](https://qiita.com/nobu-maple/items/eb7855841000eb2b0f04)

---
# 一覧
[01 サンプルのコンパイル](https://qiita.com/nobu-maple/items/051188f21efc59429808)
[02 ログイン時にPassword(554)を送信](https://qiita.com/nobu-maple/items/649f1fd2525523f12064)
[03 送受信ログをMySQLに保存](https://qiita.com/nobu-maple/items/cc943f0c1028f21161c0)
[04 情報保存用にMySQLコネクションを保持..他](https://qiita.com/nobu-maple/items/cfe505ad984e16d46af9)
[05 各種メッセージの枠を作成](https://qiita.com/nobu-maple/items/770d8da8c50c4f5a5a54)
[06 独自メッセージ仕様](https://qiita.com/nobu-maple/items/580815f3c304d96bde31)
[07 セッション開始 <h> TradingSessionStatus](https://qiita.com/nobu-maple/items/98369bad8351cb662740)
[08 通貨ペア要求 <x> SecurityListRequest](https://qiita.com/nobu-maple/items/ba0fb7175c378bc4c608)
[09 通貨ペア取得 <y> SecurityList](https://qiita.com/nobu-maple/items/66feda02d9a717bd31b9)
[10 デモ環境サーバへ接続](https://qiita.com/nobu-maple/items/52de92892a03f59c7368)
[11 ログ出力設定](https://qiita.com/nobu-maple/items/828d3859ebf2ab2237f8)
[12 マーケット情報要求 < V > MarketDataRequest](https://qiita.com/nobu-maple/items/1c4f2d27cabde8eff713)
[13 マーケット情報受信 < X > MarketDataIncrementalRefresh](https://qiita.com/nobu-maple/items/eb7855841000eb2b0f04)
[14 口座情報要求 < AN > RequestForPositions](https://qiita.com/nobu-maple/items/30c286f8dbf1e9b0e173)
[15 口座情報取得 < AZ > CollateralResponse](https://qiita.com/nobu-maple/items/a16e3c787ef5e83f3971)

---