【QuickFIX】09 通貨ペア取得 <y> SecurityList

通貨ペアの要求 < x > SecurityListRequest に対する返答 < y > SecurityList を受け取ります

返答には利用可能な 通貨ペア 情報がぎっしり？詰め込まれているので、１つ１つ取り出して、ＤＢへ保存しときます
ついでにレート情報の要求も投げ込めるようにしときましょう

レート情報を受け取った後の情報保持用に変数の初期化なんかもやっときます


## メッセージ受信　< y > SecurityList
```cpp:resp_y__SecurityList.cpp
#include "config.h"

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

/* y  */
void Application::onMessage(const FIX44::SecurityList& message, const FIX::SessionID& sessionID )
{
  std::cout << "<y> SecurityList: " << std::endl << message.toXML() << std::endl;

  /* Get Message Data  */
  /* 146  */ FIX::FieldBase symbolCount( FIX::FIELD::NoRelatedSym, "0" );
             message.getFieldIfSet( symbolCount );

  /* Check Counter - none return */
  if(std::stoi(symbolCount.getString()) <= 0) return;

  /* UPDATE ALL Status - flase */
  FIX::MySQLQuery q( "UPDATE `T_SYMBOL` SET `Status` = 0  WHERE `Status` = 1;" );
  m_sql->execute( q );

  /* INIT rate vector */
  rate.clear();
  rate.shrink_to_fit();
  rate.resize(std::stoi(symbolCount.getString()));

  /* Loop: Currency Pair */
  for( int i=1; i <= std::stoi(symbolCount.getString()); i++ )
  {
    /* 146  */ FIX44::SecurityList::NoRelatedSym r;
               message.getGroup(i, r);

    /* 55   */ FIX::FieldBase symbol( FIX::FIELD::Symbol, "NA");
               r.getFieldIfSet( symbol );

    /* SELECT SYMBOL */
    bool getRate = false;
    std::ostringstream s1;
    s1 << "SELECT `Symbol`, `GetRate` FROM `T_SYMBOL`  WHERE `Symbol` = '" << symbol << "'";
    FIX::MySQLQuery q1( s1.str() );
    m_sql->execute( q1 );

    /* UPDATE Status - true  */
    if( q1.rows() != 0 )
    {
      std::ostringstream s2;
      s2 << "UPDATE `T_SYMBOL`" <<
        "   SET `Status` = 0" <<
        " WHERE `Symbol` = '" << symbol << "'";
      FIX::MySQLQuery q2( s2.str() );
      m_sql->execute( q2 );

      /* Get Rate? */
      if (std::string(q1.getValue(0,1)) == "1")
        getRate = true;
    }

    /* INSERT SYMBOL Status - true  */
    else
    {
      std::ostringstream s3;
      s3 << "INSERT INTO  `T_SYMBOL` " <<
        " ( `Symbol`, `Status` ) " <<
        " VALUES ('" << symbol << "', 0 )";
      FIX::MySQLQuery q3( s3.str() );
      m_sql->execute( q3 );
    }

    /* Symbol : map - vector */
    m_symbol[symbol.getString()] = (i - 1);
    rate[ m_symbol[symbol.getString()] ].Symbol = symbol.getString();
    rate[ m_symbol[symbol.getString()] ].feedStatus = false;

    /* Get Market Data Rate */
    if( getRate )
    {
      /* <V> */ MarketDataRequest(); // symbol.getString() );
    }
  }
  /* End : Currency Pair */
}

```

ってな感じの処理になってます


## T_SYMBOL テーブル
通貨ペアを保存するためのテーブルはこんな感じ

```sql:examples/tradeclient/sql/T_SYMBOL.sql
DROP TABLE IF EXISTS T_SYMBOL;
CREATE TABLE T_SYMBOL
(
  `Symbol`                VARCHAR(7)        NOT NULL                       COMMENT '55 ',
  `Status`                CHAR(1)           NOT NULL  DEFAULT 0            COMMENT '---- 0:FALSE 1:TRUE ',
  `GetRate`               CHAR(1)           NOT NULL  DEFAULT 0            COMMENT '---- 0:None  1:GetRate ',

  `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 'Symbol List';

INSERT INTO `T_SYMBOL` (`Symbol`, `GetRate`) VALUES ('USD/JPY', '1');
INSERT INTO `T_SYMBOL` (`Symbol`, `GetRate`) VALUES ('EUR/JPY', '1');
INSERT INTO `T_SYMBOL` (`Symbol`, `GetRate`) VALUES ('EUR/USD', '1');

DESC T_SYMBOL;

```

Status が "0" ならCNEXの対象外通貨ペア
GetRate が "0" ならレート情報の受信は行わない
という感じ

とりあえず３ペアをレート情報受信対象としてレコード追加しときます。
　・USD/JPY
　・EUR/JPY
　・EUR/USD


## レート情報保存領域

構造体を定義しときます

```cpp:Rate.h
typedef struct {
  std::string Symbol;
  double Bid;
  long BidSize;
  long BidOrder;
  double Spred;
  double Ask;
  long AskSize;
  long AskOrder;
  double High;
  double Low;
  std::string Time;
  bool feedStatus;
} Rate;

```


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

レート情報保存領域とかの準備を

```cpp:Application.h
@@ -37,6 +37,8 @@
 #include "resp_CG_PartyDetailsListReport.h"                 // resp < CG >
 #include "resp_PU_OrderRateUpdate.h"                        // resp < PU >

+#include "Rate.h"
+
 #include <queue>
 #include <vector>
 #include <map>
@@ -84,6 +86,9 @@ private:
   std::string m_accountID;
   std::string m_partyID;

+  std::map<std::string, int> m_symbol;
+  std::vector<Rate> rate;
+
   void onCreate( const FIX::SessionID& ) {}
   void onLogon( const FIX::SessionID& sessionID );
   void onLogout( const FIX::SessionID& sessionID );

```

ヘッダーファイル Rate.h を読み込んで、保存領域を宣言




## make 対象に追加
```cpp:Makefile.am
@@ -4,6 +4,7 @@ tradeclient_SOURCES = \
        tradeclient.cpp \
        Application.h \
        Application.cpp \
+       Rate.h \
        resp_8__ExecutionReport.cpp \
        resp_9__OrderCancelReject.cpp \
        resp_AO_RequestForPositionsAck.cpp \
```


## コンパイル
```bash:
tradeclient]$ make clean
tradeclient]$ make

```

エラーなく終了すること


## 受信メッセージサンプル

```bash:
8=FIX.4.4 
9=939 
35=y 
49=CNX 
34=3 
52=20170412-15:39:30.879 
56=Demo_Trd 
320=SecListReq_20170412-153930.773 
322=1 
560=0 
146=19 
55=USD/JPY 870=2 871=18 872=2 871=16 872=2 
55=AUD/CHF 870=2 871=18 872=4 871=16 872=4 
55=USD/CHF 870=2 871=18 872=4 871=16 872=4 
55=AUD/USD 870=2 871=18 872=4 871=16 872=4 
55=EUR/CHF 870=2 871=18 872=4 871=16 872=4 
55=EUR/AUD 870=2 871=18 872=4 871=16 872=4 
55=EUR/GBP 870=2 871=18 872=4 871=16 872=4 
55=EUR/JPY 870=2 871=18 872=2 871=16 872=2 
55=EUR/USD 870=2 871=18 872=4 871=16 872=4 
55=GBP/USD 870=2 871=18 872=4 871=16 872=4 
55=ZAR/JPY 870=2 871=18 872=2 871=16 872=2 
55=NZD/USD 870=2 871=18 872=4 871=16 872=4 
55=GBP/CHF 870=2 871=18 872=4 871=16 872=4 
55=CHF/JPY 870=2 871=18 872=2 871=16 872=2 
55=CAD/CHF 870=2 871=18 872=4 871=16 872=4 
55=GBP/JPY 870=2 871=18 872=2 871=16 872=2 
55=AUD/JPY 870=2 871=18 872=2 871=16 872=2 
55=CAD/JPY 870=2 871=18 872=2 871=16 872=2 
55=NZD/JPY 870=2 871=18 872=2 871=16 872=2 
10=156 
```

こんな感じのメッセージを受け取るハズ



---

＜前 [【QuickFIX】08 通貨ペア要求 <x> SecurityListRequest](https://qiita.com/nobu-maple/items/ba0fb7175c378bc4c608)
次＞ [【QuickFIX】10 デモ環境サーバへ接続](https://qiita.com/nobu-maple/items/52de92892a03f59c7368)

---
# 一覧
[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)

---