LoginSignup
1
2

More than 3 years have passed since last update.

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

Last updated at Posted at 2017-05-16

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

< AZ > CollateralResponse

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;
}

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

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

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;
     ・・・

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

独自フィールド対応

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

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>
    ・・・

動作確認用

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

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 を入力すると口座情報を要求して
最新の口座情報を表示する

DB保存

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

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)

履歴も確認

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


一覧

01 サンプルのコンパイル
02 ログイン時にPassword(554)を送信
03 送受信ログをMySQLに保存
04 情報保存用にMySQLコネクションを保持..他
05 各種メッセージの枠を作成
06 独自メッセージ仕様
07 セッション開始 TradingSessionStatus
08 通貨ペア要求 SecurityListRequest
09 通貨ペア取得 SecurityList
10 デモ環境サーバへ接続
11 ログ出力設定
12 マーケット情報要求 < V > MarketDataRequest
13 マーケット情報受信 < X > MarketDataIncrementalRefresh
14 口座情報要求 < AN > RequestForPositions
15 口座情報取得 < AZ > CollateralResponse


1
2
18

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2