【QuickFIX】15 口座情報取得 < AZ > CollateralResponse

< AN > RequestForPositions の返信メッセージの < AZ > CollateralResponse で口座情報を取得して残高とかを保存しときます。


## < AZ > CollateralResponse

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

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

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

  /* Get Account ID */
  /* 1    */ FIX::FieldBase accountID(FIX::FIELD::Account, m_accountID);
             message.getFieldIfSet( accountID );

  /* Get Currency */
  /* 15   */ FIX::FieldBase currency(FIX::FIELD::Currency, "NA");
             message.getFieldIfSet( currency );

  /* Get Transact Time */
  /* 60   */ FIX::FieldBase transactTime(FIX::FIELD::TransactTime, "");
             message.getFieldIfSet( transactTime );
             std::string transactDay = transactTime.getString().substr(0,8);

  /* Get Financial Status 1:Disable  3:Active */
  /* 291  */ FIX::FieldBase status(FIX::FIELD::FinancialStatus, "0");
             message.getFieldIfSet( status );

  /* Get MarginRatio */
  /* 898  */ FIX::FieldBase ratio(FIX::FIELD::MarginRatio, "0");
             message.getFieldIfSet( ratio );

  /* Get Response Type */
  /* 905  */ FIX::FieldBase result(FIX::FIELD::CollAsgnRespType, "0");
             message.getFieldIfSet( result );

  /* Get Start Cash - Trading Day Opening Balance */
  /* 921  */ FIX::FieldBase startCash(FIX::FIELD::StartCash, "0");
             message.getFieldIfSet( startCash );

  /* Get End Cash - Current Balance - max 40億 */
  /* 922  */ FIX::FieldBase endCash(FIX::FIELD::EndCash, "0");
             message.getFieldIfSet( endCash );

  /* Insert into Balance Hist */
  std::ostringstream s1;
  s1 << "INSERT INTO  `T_BALANCE_HIST` " <<
    " ( " <<
    "   `Account`         " << /* 1    */
    " , `Result`          " << /* 905  1:Accepted  3:Reject */
    " , `TransactTime`    " << /* 60   yyyymmdd-hh:mm:ss */
    " , `TransactDay`     " << /* 60   yyyymmdd */
    " , `FinansialStatus` " << /* 291  1=Disabled  3:Active */
    " , `Currency`        " << /* 15   */
    " , `MarginRatio`     " << /* 898  */
    " , `StartCash`       " << /* 921  */
    " , `EndCash`         " << /* 922  */
    " )  VALUES  ( " <<
    "   '" << accountID     << "' " <<    /* 1    */
    " , '" << result        << "' " <<    /* 905  */
    " , '" << transactTime  << "' " <<    /* 60   */
    " , '" << transactDay   << "' " <<    /* 60   */
    " , '" << status        << "' " <<    /* 291  */
    " , '" << currency      << "' " <<    /* 15   */
    " , '" << ratio         << "' " <<    /* 898  */
    " , '" << startCash     << "' " <<    /* 921  */
    " , '" << endCash       << "' " <<    /* 922  */
    " ) ";
  FIX::MySQLQuery q1( s1.str() );
  if( m_sql->execute( q1 ) != true )
  {
    LOG_WARNING << "INSERT ERROR T_BALANCE_HIST :" << q1.reason() << std::endl << s1.str();
  }
  else
  {
    LOG_VERBOSE << "INSERT T_BALANCE_HIST : " << q1.reason() << std::endl << s1.str();
  }

  /* reject ? */
  if( result.getString() != "1" ) return;

  /* finansial status disable ? */
  if( status.getString() != "3" ) return;

  /* Update Current Balance */
  std::ostringstream s2;
  s2 << "UPDATE `T_BALANCE` " <<
    " SET `TransactTime` = '" << transactTime << "' " <<  /* 60   */
    "   , `Currency`     = '" << currency     << "' " <<  /* 15   */
    "   , `MarginRatio`  = '" << ratio        << "' " <<  /* 898  */
    "   , `StartCash`    = '" << startCash    << "' " <<  /* 921  */
    "   , `EndCash`      = '" << endCash      << "' " <<  /* 922  */
    " WHERE `Account`    = '" << accountID    << "' " <<  /* 1    */
    "";
  FIX::MySQLQuery q2( s2.str() );
  if( m_sql->execute( q2 ) != true )
  {
    LOG_WARNING << "UPDATE ERROR T_BALANCE :" << q2.reason() << std::endl << s2.str();
  }
  else
  {
    LOG_VERBOSE << "UPDATE T_BALANCE : " << q2.reason() << std::endl << s2.str();
  }

  /* set current cash & ratio */
  m_cash = std::stoul(endCash.getString());
  m_ratio = std::stof(ratio.getString());
  if(m_start_cash == 0)
    m_start_cash = m_cash;

  /* normal return */
  return;
}

```

口座状況や残高情報を取得
ＤＢとメモリに保存しちゃいます


### 残高情報をメモリに保持できるように宣言

```cpp:Application.h
    ・・・
        public:
          Application( const FIX::SessionSettings& settings )
            : m_settings( settings )
          {
            m_sql = MySQLConnect();
            m_accountID = getSetting("AccountID");
            m_partyID = getSetting("PartyID");
            m_tradingSessionStatus = 0;
★          m_cash = 1000000000;
★          m_start_cash = 0;
★          m_ratio = 1.0;
            plog::init( (plog::Severity)std::stoi(getSetting("LOGLevel", "3"))  // default warning(3)
                      , std::string(getSetting("LOGFile", "tradeclient") + YmdHMS(".%Y%m%d.log")).c_str() // default filename
                      , std::stoul(getSetting("LOGMaxSize", "10240000"))        // default 10MB=10,240,000byte
                      , std::stoi(getSetting("LOGMaxFiles", "10")) );            // default files= 10
          }

          ~Application()
          {
            if (m_sql) delete m_sql;
          }

          void run();

        private:
          FIX::SessionSettings m_settings;
          FIX::MySQLConnection *m_sql;
          std::string m_database;
          std::string m_user;
          std::string m_pass;
          std::string m_host;
          short m_port;
          int m_tradingSessionStatus;
          std::map<std::string, std::string> m_senderID;
          std::map<std::string, std::string> m_targetID;
          std::string m_accountID;
          std::string m_partyID;

          std::map<std::string, int> m_symbol;
          std::vector<Rate> rate;

★        unsigned long m_cash;
★        unsigned long m_start_cash;
★        float m_ratio;
     ・・・

```

残高情報を保持するように宣言して、初期化してます


### 独自フィールド対応

標準とは必須とかフィールドとか値とかが違うので対応
（前にやった時の作業漏れ）

```xml:FIX44.xml
    ・・・
          <message name='CollateralResponse' msgtype='AZ' msgcat='app'>
           <field name='CollRespID' required='Y' />
-          <field name='CollAsgnID' required='Y' />
+          <field name='CollAsgnID' required='N' />
           <field name='CollReqID' required='N' />
-          <field name='CollAsgnReason' required='Y' />
+          <field name='CollAsgnReason' required='N' />
           <field name='CollAsgnTransType' required='N' />
           <field name='CollAsgnRespType' required='Y' />
           <field name='CollAsgnRejectReason' required='N' />
           <field name='TransactTime' required='Y' />
+          <field name='FinancialStatus' required='Y' />
           <component name='Parties' required='N' />
           <field name='Account' required='N' />
           <field name='AccountType' required='N' />
           <field name='ClOrdID' required='N' />
           <field name='OrderID' required='N' />
           <field name='SecondaryOrderID' required='N' />
           <field name='SecondaryClOrdID' required='N' />
           <component name='ExecCollGrp' required='N' />
           <component name='TrdCollGrp' required='N' />
           <component name='Instrument' required='N' />
           <component name='FinancingDetails' required='N' />
           <field name='SettlDate' required='N' />
           <field name='Quantity' required='N' />
           <field name='QtyType' required='N' />
           <field name='Currency' required='N' />
           <component name='InstrmtLegGrp' required='N' />
           <component name='UndInstrmtCollGrp' required='N' />
           <field name='MarginExcess' required='N' />
           <field name='TotalNetValue' required='N' />
           <field name='CashOutstanding' required='N' />
           <component name='TrdRegTimestamps' required='N' />
           <field name='Side' required='N' />
           <component name='MiscFeesGrp' required='N' />
           <field name='Price' required='N' />
           <field name='PriceType' required='N' />
           <field name='AccruedInterestAmt' required='N' />
           <field name='EndAccruedInterestAmt' required='N' />
           <field name='StartCash' required='N' />
           <field name='EndCash' required='N' />
           <component name='SpreadOrBenchmarkCurveData' required='N' />
           <component name='Stipulations' required='N' />
           <field name='Text' required='N' />
           <field name='EncodedTextLen' required='N' />
           <field name='EncodedText' required='N' />
          </message>
    ・・・
          <field number='291' name='FinancialStatus' type='MULTIPLEVALUESTRING'>
           <value enum='1' description='BANKRUPT' />
           <value enum='2' description='PENDING_DELISTING' />
+          <value enum='3' description='RESTRICTED' />
          </field>
    ・・・

```


### 動作確認用

受け取った口座情報を表示できるようにしときます

```cpp:Application.cpp
    ・・・
        void Application::run()
        {
          while ( true )
          {
            try
            {
              std::string action;
              std::cout << "------ " << YmdHMSs("%04d/%02d/%02d %02d:%02d:%02d.%03d" ) << " --------" << std::endl
                << "q) Quit" << std::endl
★              << "r) Show rate " << std::endl
                << "Action: ";
              std::cin >> action;
              LOG_DEBUG << "COMMAND: " << action;

              if ( action == "q" )
                break;
              else
★            if ( action == "r" )
              {
★              RequestForPositions( YmdHMS("%Y%m%d") );
★              std::cout <<
★                "START  : " << std::setw(15) << std::right << numFormat(m_start_cash) << std::endl <<
★                "CURRENT: " << std::setw(15) << std::right << numFormat(m_cash)       << std::endl <<
★                "RATIO  : " << m_ratio << std::endl;
                for( auto symbol: m_symbol)
                {
                  if(rate[symbol.second].feedStatus)
                  {
                    std::ostringstream s;
                    // s << std::fixed;
                    s << std::setprecision(8) ;
                    s << symbol.first  << "\t"
                      << rate[symbol.second].Time   << "  "
                      << rate[symbol.second].Symbol << "  "
                      << rate[symbol.second].Bid    << " \t"
                      << rate[symbol.second].Spred  << " \t"
                      << rate[symbol.second].Ask    << "  "
                      << std::endl;
                    std::cout << s.str();
                  }
                }
              }
            }
            catch ( std::exception & e )
            {
              std::cout << "Message Not Sent: " << e.what();
              LOG_WARNING << "Message Not Sent: " << e.what();
            }
          }
        }

    ・・・

```

メニューで r を入力すると口座情報を要求して
最新の口座情報を表示する



## ＤＢ保存

保存されていることを確認しとく

```sql:T_BALANCE
mysql> select *
    ->   from T_BALANCE;
+-----------------+-------------------+----------+-------------+------------+------------+---------------------+---------------------+------------+
| Account         | TransactTime      | Currency | MarginRatio | StartCash  | EndCash    | Created_at          | Updated_at          | Deleted_at |
+-----------------+-------------------+----------+-------------+------------+------------+---------------------+---------------------+------------+
| CAXDemo_Account | 20170424-15:04:25 | JPY      |           1 | 1000003830 | 1000003830 | 2017-04-24 23:33:23 | 2017-04-25 00:04:25 | NULL       |
+-----------------+-------------------+----------+-------------+------------+------------+---------------------+---------------------+------------+
1 row in set (0.02 sec)

```

履歴も確認

```sql:T_BALANCE_HIST
mysql> select *
    ->   from T_BALANCE_HIST
    ->  limit 16, 100;
+----+-----------------+--------+-------------------+-------------+-----------------+----------+-------------+------------+------------+---------------------+
| id | Account         | Result | TransactTime      | TransactDay | FinansialStatus | Currency | MarginRatio | StartCash  | EndCash    | Created_at          |
+----+-----------------+--------+-------------------+-------------+-----------------+----------+-------------+------------+------------+---------------------+
| 17 | CAXDemo_Account | 1      | 20170424-14:55:38 | 20170424    | 3               | JPY      |           1 | 1000003830 | 1000003830 | 2017-04-24 23:55:38 |
| 18 | CAXDemo_Account | 1      | 20170424-14:55:40 | 20170424    | 3               | JPY      |           1 | 1000003830 | 1000003830 | 2017-04-24 23:55:41 |
| 19 | CAXDemo_Account | 1      | 20170424-14:55:42 | 20170424    | 3               | JPY      |           1 | 1000003830 | 1000003830 | 2017-04-24 23:55:43 |
| 20 | CAXDemo_Account | 1      | 20170424-14:55:43 | 20170424    | 3               | JPY      |           1 | 1000003830 | 1000003830 | 2017-04-24 23:55:43 |
| 21 | CAXDemo_Account | 1      | 20170424-14:57:30 | 20170424    | 3               | JPY      |           1 | 1000003830 | 1000003830 | 2017-04-24 23:57:30 |
| 22 | CAXDemo_Account | 1      | 20170424-14:57:32 | 20170424    | 3               | JPY      |           1 | 1000003830 | 1000003830 | 2017-04-24 23:57:32 |
| 23 | CAXDemo_Account | 1      | 20170424-15:02:34 | 20170424    | 3               | JPY      |           1 | 1000003830 | 1000003830 | 2017-04-25 00:02:34 |
| 24 | CAXDemo_Account | 1      | 20170424-15:03:32 | 20170424    | 3               | JPY      |           1 | 1000003830 | 1000003830 | 2017-04-25 00:03:32 |
| 25 | CAXDemo_Account | 1      | 20170424-15:04:25 | 20170424    | 3               | JPY      |           1 | 1000003830 | 1000003830 | 2017-04-25 00:04:25 |
+----+-----------------+--------+-------------------+-------------+-----------------+----------+-------------+------------+------------+---------------------+
9 rows in set (0.00 sec)


```

---

＜前 [【QuickFIX】14 口座情報要求 < AN > RequestForPositions](https://qiita.com/nobu-maple/items/30c286f8dbf1e9b0e173)

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

---