マーケットの情報をストリーミングで送信してくれ、と要求を投げます
要求が通ると CNEXサーバからレート情報がバンバン送られてくることになります
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();
・・・
どの通貨ペアの情報を取得するのかを引数で指定できるようにしときます
ついでに情報取得を「開始」するのか「終了」するのかを第2引数に指定
(デフォルトでは「開始」)
第3引数には情報深度?を指定
1 :TOP なら現在のレート情報のみを
0 :FULL なら現在のレートの上下5値?の板情報も取得です
第4引数の Aggregate はとりあえず true で
< V > MarketDataRequest
#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 だけで処理を組み立てたいので
引数の設定を変更したので呼び出し元も修正
・・・
/* Get Market Data Rate */
if( getRate )
{
/* <V> */ MarketDataRequest( symbol.getString() );
}
・・・
マーケット情報を保存するテーブルも準備
T_MARKET_DATA 最新値のみを保持するテーブル
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 マーケット情報の履歴を保持するテーブル
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 レートの板情報も保持するテーブル
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 ログ出力設定
次> 【QuickFIX】13 マーケット情報受信 < X > MarketDataIncrementalRefresh
一覧
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