0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2017-04-25

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

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

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

メッセージ受信 < y > SecurityList

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 テーブル

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

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" ならレート情報の受信は行わない
という感じ

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

レート情報保存領域

構造体を定義しときます

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 ヘッダーファイル

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

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 対象に追加

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 \

コンパイル

tradeclient]$ make clean
tradeclient]$ make

エラーなく終了すること

受信メッセージサンプル

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 通貨ペア要求 SecurityListRequest
次> 【QuickFIX】10 デモ環境サーバへ接続


一覧

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


0
3
6

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
0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?