日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

交易系统开发(十一)——QuickFIX简介

發布時間:2024/3/7 windows 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 交易系统开发(十一)——QuickFIX简介 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、QuickFIX簡介

1、QuickFIX簡介

QuickFIX是一款C++實現的開源FIX引擎,同時提供Python、Ruby語言實現。

QuickFIX官網:

http://www.quickfixengine.org
Github地址:

https://github.com/quickfix/quickfix

2、QuickFIX編譯

編譯選項配置:

configure

編譯:

make

檢查:

make check

安裝:

sudo make install

二、FIX應用模式

1、FIX應用模式簡介

FIX應用有initiator和acceptor兩種模式。

initiator是TCP連接的發起方,acceptor是TCP連接監聽方。標準FIX應用(如CTS FIX網關)可以同時支持initiator和acceptor兩種模式,既可以發起連接,也可以接受連接請求。
開發FIX應用時,需要先確定FIX應用模式,然后選擇對應的QuickFIX類對象。

initiator模式的FIX應用可以使用SocketInitiator、SSLSocketInitiator、ThreadedSocketInitiator、ThreadedSSLSocketInitiator創建FIX Initiator應用。

acceptor模式的FIX應用可以使用SocketAcceptor、SSLSocketAcceptor、ThreadedSocketAcceptor、ThreadedSSLSocketAcceptor創建FIX Acceptor應用。

2、FIX通信

FIX應用業務是通過在initiator與acceptor間建立一個FIX Session并交換消息來進行的。FIX業務消息有一系列預定義類型與格式,目前標準的消息類型有5、60個,函蓋了交易、行情、結算等投資管理的各個環節。FIX應用開發基本上是對FIX消息的編程。

Fix Session可以由一個或多個Fix連接組成,即Fix Session可以多次登陸。Fix Session通常使用幾個重要標識區分,如Fix版本號字符串(如:FIX.4.2),發送者ID,接收者ID,Fix Session每發送一條消息時,消息頭的BeginString、SenderCompID、TargetCompID都會被賦值。當消息通過FIX連接到達對等方時,對等方可以根據消息頭中的的標識找到本地端的Fix Session去處理消息。

FIX通信雙方包括Initiator和Acceptor,會各自維護2個遞增的序列號(發送消息序列號–每發送一個消息加1,接收消息序列號–每收到一個消息加1)。
(1)通信首先由Initiator開始發起TCP連接請求, Acceptor接收網絡連接請求,建立TCP連接。
(2)Initiator發起登錄消息請求。
(3)Acceptor收到登錄請求后,經過一系列消息檢查,合格后,返回登錄確認。

(4)Initiator收到登錄確認后,經過一系列消息檢查,合格后,雙方FIX Session連接成功。
(5)Initiator和Acceptor交換消息。
(6)Initiator和Acceptor任何一方發出退出消息。

3、FIX Session配置

QuickFix中initiator或acceptor會維護多個Fix Session。QuickFix中使用BeginString(Fix版本號)、SenderCompID、TargetCompID的組合標識一個Session,Session標識用于區分其它不同的Session。

Session配置文件包含[DEFAULT]和[SESSION]兩種分節,[SESSION]分節表示QuickFix中定義一個Session,[DEFAULT]表示所有Session默認使用的配置項,如果不提供QuickFix所需的配置,QuickFix會拋出ConfigError異常,表示配置缺失或格式不正確。

如果[DEFAULT]和[SESSION]分區中都包含相同的配置項,則[SESSION]分區的配置項會覆蓋[DEFAULT]分區相應的配置項。

QuickFix配置文件sessions.ini如下:

[DEFAULT] ConnectionType=initiator ReconnectInterval=60 FileLogPath=log FileStorePath=store StartTime=00:00:00 EndTime=23:59:59 HeartBtInt=30 ResetOnDisconnect=Y ResetOnLogout=Y ResetOnLogon=Y[SESSION] BeginString=FIX.4.2 SenderCompID=CLIENT TargetCompID=SERVER SocketConnectPort=6666 SocketConnectHost=127.0.0.1 DataDictionary=FIX42.xml

三、QuickFIX核心類

1、FIX::Application

FIX應用需要實現FIX::Application接口:

class?Application { public:virtual?~Application()?{};///?Notification?of?a?session?begin?createdvirtual?void?onCreate(?const?SessionID&?)?=?0;///?Notification?of?a?session?successfully?logging?onvirtual?void?onLogon(?const?SessionID&?)?=?0;///?Notification?of?a?session?logging?off?or?disconnectingvirtual?void?onLogout(?const?SessionID&?)?=?0;///?Notification?of?admin?message?being?sent?to?targetvirtual?void?toAdmin(?Message&,?const?SessionID&?)?=?0;///?Notification?of?app?message?being?sent?to?targetvirtual?void?toApp(?Message&,?const?SessionID&?)EXCEPT?(?DoNotSend )?=?0;///?Notification?of?admin?message?being?received?from?targetvirtual?void?fromAdmin(?const?Message&,?const?SessionID&?)EXCEPT?(?FieldNotFound,?IncorrectDataFormat,?IncorrectTagValue,?RejectLogon?)?=?0;///?Notification?of?app?message?being?received?from?targetvirtual?void?fromApp(?const?Message&,?const?SessionID&?)EXCEPT?(?FieldNotFound,?IncorrectDataFormat,?IncorrectTagValue,?UnsupportedMessageType?)?=?0; };

onCreate:當一個Fix Session建立時調用。

onLogon:當一個Fix Session登錄成功時調用。

onLogout:當一個Fix Session退出時調用。

fromAdmin:當收到一個消息,經過一系列檢查,合格后,屬于Admin類型時調用。

fromApp:當收到一個消息,經過一系列檢查,合格后,不屬于Admin 類型時候調用。

toAdmin:當發送一個admin類型消息調用。

toApp:當發送一個非admin(業務類型)消息調用。

如果需要使用QuickFIX開發FIX應用,則需要實現FIX::Application接口,并重載不同FIX協議版本的MessageCracker::OnMessage接口,如FIX42::MessageCracker。

FIX業務都是異步方式處理的,而業務處理的基本對象是消息。OnMessage是消息接收回調函數,有多個重載版本,開發者只需要使重載一個FIX版本即可。

對于支持交易業務的FIX Initiator應用,通常要重寫4個基本消息,即OnMessage(NewOrderSingle)、OnMessage(CancelRequest)、 OnMessage(ExecutionReport)、 OnMessage(CancelReject),分別用于做委托、撤單、執行回報(包括對委托的拒絕)和對撤單的拒絕等4項業務。

#include?"quickfix/Application.h" #include?"quickfix/MessageCracker.h"class?FIXApplication:?public?FIX::Application,?public?FIX::MessageCracker { public:/***************************************************??reimplementation?from?Application*?***********************************************////?Notification?of?a?session?begin?createdvirtual?void?onCreate(?const?SessionID&?){}///?Notification?of?a?session?successfully?logging?onvirtual?void?onLogon(?const?SessionID&?){}///?Notification?of?a?session?logging?off?or?disconnectingvirtual?void?onLogout(?const?SessionID&?){}///?Notification?of?admin?message?being?sent?to?targetvirtual?void?toAdmin(?Message&,?const?SessionID&?){}///?Notification?of?app?message?being?sent?to?targetvoid?fromApp(?const?FIX::Message&?message,?const?FIX::SessionID&?sessionID?)throw(?FIX::FieldNotFound&,?FIX::IncorrectDataFormat&,?FIX::IncorrectTagValue&,FIX::UnsupportedMessageType&?){crack(message,?sessionID);}///?Notification?of?admin?message?being?received?from?targetvirtual?void?fromAdmin(?const?Message&,?const?SessionID&?)throw?(?FIX::FieldNotFound,?FIX::IncorrectDataFormat,?FIX::IncorrectTagValue,FIX::RejectLogon?){}///?Notification?of?app?message?being?received?from?targetvirtual?void?fromApp(?const?Message&,?const?SessionID&?)throw?(?FIX::FieldNotFound,?FIX::IncorrectDataFormat,?FIX::IncorrectTagValue,FIX::UnsupportedMessageType?){}/***************************************************??reimplementation?from?FIX42::MessageCracker*?***********************************************/virtual?void?onMessage(?const?FIX42::NewOrderSingle&?message,?const?FIX::SessionID&?){}virtual?void?onMessage(?const?FIX42::OrderCancelRequest&?message,?const?FIX::SessionID&?){}virtual?void?onMessage(?ExecutionReport&,?const?FIX::SessionID&?){}virtual?void?onMessage(?OrderCancelReject&,?const?FIX::SessionID&?){} };

2、FIX::SessionSettings

FIX應用配置使用FIX::SessionSettings讀取FIX Session配置文件并傳遞給QuickFIX框架。一個FIX應用可以管理多個FIX?Session,每個Session可以采用相同的FIX協議版本,也可以采用不同的版本。即使采用的是相同的FIX協議版本,不同FIX Session間也可以有FIX協議細節的差異,通過綁定FIX Session與FIX協議字典的方式來實現,即在Session配置文件中[Session]配置項中使用DataDictionary選項指定相應FIX字典文件來實現。

FIX::SessionSettings?settings("sessionConfig.ini");

3、FIX::FileStoreFactory

QuickFIX提供了存儲消息到文件的類FIX::FileLogFactory。消息文件存儲的路徑在Session配置中指定。

FIX::FileStoreFactory?storeFactory(settings);

4、FIX::MessageStoreFactory

QuickFIX提供了給Fix Session持久化類型(如文件存儲、數據存儲,存儲內容包括狀態、創建時間、消息及其自己維護的發送序列號和接收序列號等)。

如果開發者要自定義持久化方式,可以自己定義MessageStoreFactory實現,并且自定義一種MessageStore。

5、FIX::FileLogFactory

QuickFIX提供了存儲所有日志事件到文件的類FIX::FileLogFactory。

6、FIX::ScreenLogFactory

QuickFIX中提供了顯示所有消息事件到標準輸出的類ScreenLogFactory。

FIX::ScreenLogFactory?logFactory(settings);

7、FIX::Message

QuickFIX中定義了不同FIX協議版本消息的基類FIX::Message,用于定義FIX消息的通用結構,不同的FIX消息版本的消息定義在不同的FIX命名空間內定義,如FIX42::Message。FIX::MessageCracker則繼承了所有不同FIX協議版本的MessageCracker類,接收消息后生成具體FIX協議Message對象實現對消息進行處理。

8、FIX::Session

無論是FIX Initiator應用還是FIX Acceptor應用,在Fix Session初始化時,即在FIX::SessionFactory創建Fix Session后都會檢查Fix Session時間范圍。如果Fix Session啟動不是當天有效的Session,則會重置Fix Session的發送序列號和接收序列號。(FIX規定一個Fix Session一般不超過24小時)。

FIX::Session部分接口定義如下:

class?Session { public:static?bool?sendToTarget(?Message&?message,const?std::string&?qualifier?=?""?)EXCEPT?(?SessionNotFound );static?bool?sendToTarget(?Message&?message,const?SessionID&?sessionID?)EXCEPT?(?SessionNotFound );static?bool?sendToTarget(?Message&,const?SenderCompID&?senderCompID,const?TargetCompID&?targetCompID,const?std::string&?qualifier?=?""?)EXCEPT?(?SessionNotFound );static?bool?sendToTarget(?Message&?message,const?std::string&?senderCompID,const?std::string&?targetCompID,const?std::string&?qualifier?=?""?)EXCEPT?(?SessionNotFound );bool?send(?Message&?);void?next();void?next(?const?UtcTimeStamp&?timeStamp?);void?next(?const?std::string&,?const?UtcTimeStamp&?timeStamp,?bool?queued?=?false?);void?next(?const?Message&,?const?UtcTimeStamp&?timeStamp,?bool?queued?=?false?); };

next()方法是定時運行的一個方法,主要用于檢測是否需要發心跳消息,是否需要發TEST消息,是否需要斷開連接,是否需要產生LOGON(Initiator)。

next( const Message&)方法用于處理Session收到的FIX消息。

9、FIX::Acceptor

FIX::Acceptor用于從Session配置文件讀取信息創建和管理本Acceptor支持的FIX Session,具體FIX Session的TCP連接管理、數據讀寫由具體的SocketAcceptor、SSLSocketAcceptor、ThreadedSocketAcceptor、ThreadedSSLSocketAcceptor實現。

FIX::Acceptor*?acceptor?=?new?FIX::SocketAcceptor(application,?storeFactory,?settings,?logFactory);

10、FIX::Initiator

FIX::Initiator用于從Session配置文件讀取信息創建和管理本Initiator支持的FIX Session,具體FIX Session的TCP連接管理、數據讀寫由具體的SocketInitiator、SSLSocketInitiator、ThreadedSocketInitiator、ThreadedSSLSocketInitiator實現。

FIX::Initiator?*?initiator?=?new?FIX::SocketInitiator(application,?storeFactory,?settings,?logFactory);

四、FIX Acceptor應用開發

1、FIX Acceptor應用簡介

FIX Acceptor應用通常用于FIX網關,部署在賣方側。

2、FIX Acceptor應用創建

(1)創建FIX Session配置對象

FIX::SessionSettings settings(sessionFile);

(2)創建FIX應用:

Application application;

創建日志工廠:

LogFactory logFactory(settings);

創建消息存儲文件工廠:

FIX::FileStoreFactory storeFactory(settings);

創建Acceptor服務端:

FIX::Acceptor* acceptor = new SocketAcceptor(application, storeFactory, settings, logFactory);

啟動SocketAcceptor:

acceptor->start();

3、FIX Acceptor應用示例

Executor示例演示了接收訂單請求并返回成交回執的FIX Acceptor應用。

Application.h文件:

#ifndef?EXECUTOR_APPLICATION_H #define?EXECUTOR_APPLICATION_H#include?"quickfix/Application.h" #include?"quickfix/MessageCracker.h" #include?"quickfix/Values.h" #include?"quickfix/Utility.h" #include?"quickfix/Mutex.h"#include?"quickfix/fix40/NewOrderSingle.h" #include?"quickfix/fix41/NewOrderSingle.h" #include?"quickfix/fix42/NewOrderSingle.h" #include?"quickfix/fix43/NewOrderSingle.h" #include?"quickfix/fix44/NewOrderSingle.h" #include?"quickfix/fix50/NewOrderSingle.h"class?Application :?public?FIX::Application,?public?FIX::MessageCracker { public:Application()?:?m_orderID(0),?m_execID(0)?{}//?Application?overloadsvoid?onCreate(?const?FIX::SessionID&?);void?onLogon(?const?FIX::SessionID&?sessionID?);void?onLogout(?const?FIX::SessionID&?sessionID?);void?toAdmin(?FIX::Message&,?const?FIX::SessionID&?);void?toApp(?FIX::Message&,?const?FIX::SessionID&?)EXCEPT(?FIX::DoNotSend?);void?fromAdmin(?const?FIX::Message&,?const?FIX::SessionID&?)EXCEPT(?FIX::FieldNotFound,?FIX::IncorrectDataFormat,?FIX::IncorrectTagValue,?FIX::RejectLogon?);void?fromApp(?const?FIX::Message&?message,?const?FIX::SessionID&?sessionID?)EXCEPT(?FIX::FieldNotFound,?FIX::IncorrectDataFormat,?FIX::IncorrectTagValue,?FIX::UnsupportedMessageType?);//?MessageCracker?overloadsvoid?onMessage(?const?FIX40::NewOrderSingle&,?const?FIX::SessionID&?);void?onMessage(?const?FIX41::NewOrderSingle&,?const?FIX::SessionID&?);void?onMessage(?const?FIX42::NewOrderSingle&,?const?FIX::SessionID&?);void?onMessage(?const?FIX43::NewOrderSingle&,?const?FIX::SessionID&?);void?onMessage(?const?FIX44::NewOrderSingle&,?const?FIX::SessionID&?);void?onMessage(?const?FIX50::NewOrderSingle&,?const?FIX::SessionID&?);std::string?genOrderID()?{std::stringstream?stream;stream?<<?++m_orderID;return?stream.str();}std::string?genExecID()?{std::stringstream?stream;stream?<<?++m_execID;return?stream.str();} private:int?m_orderID,?m_execID; };#endif

Application.cpp文件:

#include?"config.h" #include?"Application.h" #include?"quickfix/Session.h"#include?"quickfix/fix40/ExecutionReport.h" #include?"quickfix/fix41/ExecutionReport.h" #include?"quickfix/fix42/ExecutionReport.h" #include?"quickfix/fix43/ExecutionReport.h" #include?"quickfix/fix44/ExecutionReport.h" #include?"quickfix/fix50/ExecutionReport.h"void?Application::onCreate(?const?FIX::SessionID&?sessionID?)?{} void?Application::onLogon(?const?FIX::SessionID&?sessionID?)?{} void?Application::onLogout(?const?FIX::SessionID&?sessionID?)?{} void?Application::toAdmin(?FIX::Message&?message,const?FIX::SessionID&?sessionID?)?{} void?Application::toApp(?FIX::Message&?message,const?FIX::SessionID&?sessionID?) EXCEPT(?FIX::DoNotSend?)?{}void?Application::fromAdmin(?const?FIX::Message&?message,const?FIX::SessionID&?sessionID?) EXCEPT(?FIX::FieldNotFound,?FIX::IncorrectDataFormat,?FIX::IncorrectTagValue,?FIX::RejectLogon?)?{}void?Application::fromApp(?const?FIX::Message&?message,const?FIX::SessionID&?sessionID?) EXCEPT(?FIX::FieldNotFound,?FIX::IncorrectDataFormat,?FIX::IncorrectTagValue,?FIX::UnsupportedMessageType?) {?crack(?message,?sessionID?);?}void?Application::onMessage(?const?FIX40::NewOrderSingle&?message,const?FIX::SessionID&?sessionID?) {FIX::Symbol?symbol;FIX::Side?side;FIX::OrdType?ordType;FIX::OrderQty?orderQty;FIX::Price?price;FIX::ClOrdID?clOrdID;FIX::Account?account;message.get(?ordType?);if?(?ordType?!=?FIX::OrdType_LIMIT?)throw?FIX::IncorrectTagValue(?ordType.getField()?);message.get(?symbol?);message.get(?side?);message.get(?orderQty?);message.get(?price?);message.get(?clOrdID?);FIX40::ExecutionReport?executionReport?=?FIX40::ExecutionReport(?FIX::OrderID(?genOrderID()?),FIX::ExecID(?genExecID()?),FIX::ExecTransType(?FIX::ExecTransType_NEW?),FIX::OrdStatus(?FIX::OrdStatus_FILLED?),symbol,side,orderQty,FIX::LastShares(?orderQty?),FIX::LastPx(?price?),FIX::CumQty(?orderQty?),FIX::AvgPx(?price?)?);executionReport.set(?clOrdID?);if(?message.isSet(account)?)executionReport.setField(?message.get(account)?);try{FIX::Session::sendToTarget(?executionReport,?sessionID?);}catch?(?FIX::SessionNotFound&?)?{} }void?Application::onMessage(?const?FIX41::NewOrderSingle&?message,const?FIX::SessionID&?sessionID?) {FIX::Symbol?symbol;FIX::Side?side;FIX::OrdType?ordType;FIX::OrderQty?orderQty;FIX::Price?price;FIX::ClOrdID?clOrdID;FIX::Account?account;message.get(?ordType?);if?(?ordType?!=?FIX::OrdType_LIMIT?)throw?FIX::IncorrectTagValue(?ordType.getField()?);message.get(?symbol?);message.get(?side?);message.get(?orderQty?);message.get(?price?);message.get(?clOrdID?);FIX41::ExecutionReport?executionReport?=?FIX41::ExecutionReport(?FIX::OrderID(?genOrderID()?),FIX::ExecID(?genExecID()?),FIX::ExecTransType(?FIX::ExecTransType_NEW?),FIX::ExecType(?FIX::ExecType_FILL?),FIX::OrdStatus(?FIX::OrdStatus_FILLED?),symbol,side,orderQty,FIX::LastShares(?orderQty?),FIX::LastPx(?price?),FIX::LeavesQty(?0?),FIX::CumQty(?orderQty?),FIX::AvgPx(?price?)?);executionReport.set(?clOrdID?);if(?message.isSet(account)?)executionReport.setField(?message.get(account)?);try{FIX::Session::sendToTarget(?executionReport,?sessionID?);}catch?(?FIX::SessionNotFound&?)?{} }void?Application::onMessage(?const?FIX42::NewOrderSingle&?message,const?FIX::SessionID&?sessionID?) {FIX::Symbol?symbol;FIX::Side?side;FIX::OrdType?ordType;FIX::OrderQty?orderQty;FIX::Price?price;FIX::ClOrdID?clOrdID;FIX::Account?account;message.get(?ordType?);if?(?ordType?!=?FIX::OrdType_LIMIT?)throw?FIX::IncorrectTagValue(?ordType.getField()?);message.get(?symbol?);message.get(?side?);message.get(?orderQty?);message.get(?price?);message.get(?clOrdID?);FIX42::ExecutionReport?executionReport?=?FIX42::ExecutionReport(?FIX::OrderID(?genOrderID()?),FIX::ExecID(?genExecID()?),FIX::ExecTransType(?FIX::ExecTransType_NEW?),FIX::ExecType(?FIX::ExecType_FILL?),FIX::OrdStatus(?FIX::OrdStatus_FILLED?),symbol,side,FIX::LeavesQty(?0?),FIX::CumQty(?orderQty?),FIX::AvgPx(?price?)?);executionReport.set(?clOrdID?);executionReport.set(?orderQty?);executionReport.set(?FIX::LastShares(?orderQty?)?);executionReport.set(?FIX::LastPx(?price?)?);if(?message.isSet(account)?)executionReport.setField(?message.get(account)?);try{FIX::Session::sendToTarget(?executionReport,?sessionID?);}catch?(?FIX::SessionNotFound&?)?{} }void?Application::onMessage(?const?FIX43::NewOrderSingle&?message,const?FIX::SessionID&?sessionID?) {FIX::Symbol?symbol;FIX::Side?side;FIX::OrdType?ordType;FIX::OrderQty?orderQty;FIX::Price?price;FIX::ClOrdID?clOrdID;FIX::Account?account;message.get(?ordType?);if?(?ordType?!=?FIX::OrdType_LIMIT?)throw?FIX::IncorrectTagValue(?ordType.getField()?);message.get(?symbol?);message.get(?side?);message.get(?orderQty?);message.get(?price?);message.get(?clOrdID?);FIX43::ExecutionReport?executionReport?=?FIX43::ExecutionReport(?FIX::OrderID(?genOrderID()?),FIX::ExecID(?genExecID()?),FIX::ExecType(?FIX::ExecType_FILL?),FIX::OrdStatus(?FIX::OrdStatus_FILLED?),side,FIX::LeavesQty(?0?),FIX::CumQty(?orderQty?),FIX::AvgPx(?price?)?);executionReport.set(?clOrdID?);executionReport.set(?symbol?);executionReport.set(?orderQty?);executionReport.set(?FIX::LastQty(?orderQty?)?);executionReport.set(?FIX::LastPx(?price?)?);if(?message.isSet(account)?)executionReport.setField(?message.get(account)?);try{FIX::Session::sendToTarget(?executionReport,?sessionID?);}catch?(?FIX::SessionNotFound&?)?{} }void?Application::onMessage(?const?FIX44::NewOrderSingle&?message,const?FIX::SessionID&?sessionID?) {FIX::Symbol?symbol;FIX::Side?side;FIX::OrdType?ordType;FIX::OrderQty?orderQty;FIX::Price?price;FIX::ClOrdID?clOrdID;FIX::Account?account;message.get(?ordType?);if?(?ordType?!=?FIX::OrdType_LIMIT?)throw?FIX::IncorrectTagValue(?ordType.getField()?);message.get(?symbol?);message.get(?side?);message.get(?orderQty?);message.get(?price?);message.get(?clOrdID?);FIX44::ExecutionReport?executionReport?=?FIX44::ExecutionReport(?FIX::OrderID(?genOrderID()?),FIX::ExecID(?genExecID()?),FIX::ExecType(?FIX::ExecType_TRADE?),FIX::OrdStatus(?FIX::OrdStatus_FILLED?),side,FIX::LeavesQty(?0?),FIX::CumQty(?orderQty?),FIX::AvgPx(?price?)?);executionReport.set(?clOrdID?);executionReport.set(?symbol?);executionReport.set(?orderQty?);executionReport.set(?FIX::LastQty(?orderQty?)?);executionReport.set(?FIX::LastPx(?price?)?);if(?message.isSet(account)?)executionReport.setField(?message.get(account)?);try{FIX::Session::sendToTarget(?executionReport,?sessionID?);}catch?(?FIX::SessionNotFound&?)?{} }void?Application::onMessage(?const?FIX50::NewOrderSingle&?message,const?FIX::SessionID&?sessionID?) {FIX::Symbol?symbol;FIX::Side?side;FIX::OrdType?ordType;FIX::OrderQty?orderQty;FIX::Price?price;FIX::ClOrdID?clOrdID;FIX::Account?account;message.get(?ordType?);if?(?ordType?!=?FIX::OrdType_LIMIT?)throw?FIX::IncorrectTagValue(?ordType.getField()?);message.get(?symbol?);message.get(?side?);message.get(?orderQty?);message.get(?price?);message.get(?clOrdID?);FIX50::ExecutionReport?executionReport?=?FIX50::ExecutionReport(?FIX::OrderID(?genOrderID()?),FIX::ExecID(?genExecID()?),FIX::ExecType(?FIX::ExecType_TRADE?),FIX::OrdStatus(?FIX::OrdStatus_FILLED?),side,FIX::LeavesQty(?0?),FIX::CumQty(?orderQty?)?);executionReport.set(?clOrdID?);executionReport.set(?symbol?);executionReport.set(?orderQty?);executionReport.set(?FIX::LastQty(?orderQty?)?);executionReport.set(?FIX::LastPx(?price?)?);executionReport.set(?FIX::AvgPx(?price?)?);if(?message.isSet(account)?)executionReport.setField(?message.get(account)?);try{FIX::Session::sendToTarget(?executionReport,?sessionID?);}catch?(?FIX::SessionNotFound&?)?{} }

main.cpp文件:

#include?"config.h" #include?"quickfix/FileStore.h" #include?"quickfix/SocketAcceptor.h" #include?"quickfix/Log.h" #include?"quickfix/SessionSettings.h" #include?"Application.h" #include?<string> #include?<iostream> #include?<fstream>void?wait() {std::cout?<<?"Type?Ctrl-C?to?quit"?<<?std::endl;while(true){FIX::process_sleep(1);} }int?main(?int?argc,?char**?argv?) {if?(?argc?<?2?){std::cout?<<?"usage:?"?<<?argv[?0?]<<?"?FILE."?<<?std::endl;return?0;}std::string?file?=?argv[?1?];FIX::Acceptor?*?acceptor?=?0;try{FIX::SessionSettings?settings(?file?);Application?application;FIX::FileStoreFactory?storeFactory(?settings?);FIX::ScreenLogFactory?logFactory(?settings?);acceptor?=?new?FIX::SocketAcceptor?(?application,?storeFactory,?settings,?logFactory?);acceptor->start();wait();acceptor->stop();delete?acceptor;return?0;}catch?(?std::exception?&?e?){std::cout?<<?e.what()?<<?std::endl;delete?acceptor;return?1;} }

五、FIX Initiator應用開發

1、FIX Initiator應用簡介

FIX Initiator應用通常用于交易客戶端,部署在買方側。

2、FIX Initiator應用創建

(1)創建FIX Session配置對象

FIX::SessionSettings settings(sessionFile);

(2)創建FIX應用:

Application application;

創建日志工廠:

LogFactory logFactory(settings);

創建消息存儲文件工廠:

FIX::FileStoreFactory storeFactory(settings);

創建Acceptor服務端:

FIX::Initiator* client= new SocketInitiator(application, storeFactory,settings, logFactory);

啟動SocketInitiator:

client->start();

3、FIX Initiator應用示例

tradeclient交易客戶端

Application.h文件:

#ifndef?TRADECLIENT_APPLICATION_H #define?TRADECLIENT_APPLICATION_H#include?"quickfix/Application.h" #include?"quickfix/MessageCracker.h" #include?"quickfix/Values.h" #include?"quickfix/Mutex.h"#include?"quickfix/fix40/NewOrderSingle.h" #include?"quickfix/fix40/ExecutionReport.h" #include?"quickfix/fix40/OrderCancelRequest.h" #include?"quickfix/fix40/OrderCancelReject.h" #include?"quickfix/fix40/OrderCancelReplaceRequest.h"#include?"quickfix/fix41/NewOrderSingle.h" #include?"quickfix/fix41/ExecutionReport.h" #include?"quickfix/fix41/OrderCancelRequest.h" #include?"quickfix/fix41/OrderCancelReject.h" #include?"quickfix/fix41/OrderCancelReplaceRequest.h"#include?"quickfix/fix42/NewOrderSingle.h" #include?"quickfix/fix42/ExecutionReport.h" #include?"quickfix/fix42/OrderCancelRequest.h" #include?"quickfix/fix42/OrderCancelReject.h" #include?"quickfix/fix42/OrderCancelReplaceRequest.h"#include?"quickfix/fix43/NewOrderSingle.h" #include?"quickfix/fix43/ExecutionReport.h" #include?"quickfix/fix43/OrderCancelRequest.h" #include?"quickfix/fix43/OrderCancelReject.h" #include?"quickfix/fix43/OrderCancelReplaceRequest.h" #include?"quickfix/fix43/MarketDataRequest.h"#include?"quickfix/fix44/NewOrderSingle.h" #include?"quickfix/fix44/ExecutionReport.h" #include?"quickfix/fix44/OrderCancelRequest.h" #include?"quickfix/fix44/OrderCancelReject.h" #include?"quickfix/fix44/OrderCancelReplaceRequest.h" #include?"quickfix/fix44/MarketDataRequest.h"#include?"quickfix/fix50/NewOrderSingle.h" #include?"quickfix/fix50/ExecutionReport.h" #include?"quickfix/fix50/OrderCancelRequest.h" #include?"quickfix/fix50/OrderCancelReject.h" #include?"quickfix/fix50/OrderCancelReplaceRequest.h" #include?"quickfix/fix50/MarketDataRequest.h"#include?<queue>class?Application?:public?FIX::Application,public?FIX::MessageCracker { public:void?run();private:void?onCreate(?const?FIX::SessionID&?)?{}void?onLogon(?const?FIX::SessionID&?sessionID?);void?onLogout(?const?FIX::SessionID&?sessionID?);void?toAdmin(?FIX::Message&,?const?FIX::SessionID&?)?{}void?toApp(?FIX::Message&,?const?FIX::SessionID&?)EXCEPT(?FIX::DoNotSend?);void?fromAdmin(?const?FIX::Message&,?const?FIX::SessionID&?)EXCEPT(?FIX::FieldNotFound,?FIX::IncorrectDataFormat,?FIX::IncorrectTagValue,?FIX::RejectLogon?)?{}void?fromApp(?const?FIX::Message&?message,?const?FIX::SessionID&?sessionID?)EXCEPT(?FIX::FieldNotFound,?FIX::IncorrectDataFormat,?FIX::IncorrectTagValue,?FIX::UnsupportedMessageType?);void?onMessage(?const?FIX42::ExecutionReport&,?const?FIX::SessionID&?);void?onMessage(?const?FIX42::OrderCancelReject&,?const?FIX::SessionID&?);void?queryEnterOrder();void?queryCancelOrder();void?queryReplaceOrder();FIX42::NewOrderSingle?queryNewOrderSingle42();FIX42::OrderCancelRequest?queryOrderCancelRequest42();FIX42::OrderCancelReplaceRequest?queryCancelReplaceRequest42();void?queryHeader(?FIX::Header&?header?);char?queryAction();int?queryVersion();bool?queryConfirm(?const?std::string&?query?);FIX::SenderCompID?querySenderCompID();FIX::TargetCompID?queryTargetCompID();FIX::TargetSubID?queryTargetSubID();FIX::ClOrdID?queryClOrdID();FIX::OrigClOrdID?queryOrigClOrdID();FIX::Symbol?querySymbol();FIX::Side?querySide();FIX::OrderQty?queryOrderQty();FIX::OrdType?queryOrdType();FIX::Price?queryPrice();FIX::StopPx?queryStopPx();FIX::TimeInForce?queryTimeInForce(); };#endif

Application.cpp文件:

#include?"config.h" #include?"Application.h" #include?"quickfix/Session.h" #include?<iostream>void?Application::onLogon(?const?FIX::SessionID&?sessionID?) {std::cout?<<?std::endl?<<?"Logon?-?"?<<?sessionID?<<?std::endl; }void?Application::onLogout(?const?FIX::SessionID&?sessionID?) {std::cout?<<?std::endl?<<?"Logout?-?"?<<?sessionID?<<?std::endl; }void?Application::fromApp(?const?FIX::Message&?message,?const?FIX::SessionID&?sessionID?) EXCEPT(?FIX::FieldNotFound,?FIX::IncorrectDataFormat,?FIX::IncorrectTagValue,?FIX::UnsupportedMessageType?) {crack(?message,?sessionID?);std::cout?<<?std::endl?<<?"IN:?"?<<?message?<<?std::endl; }void?Application::toApp(?FIX::Message&?message,?const?FIX::SessionID&?sessionID?) EXCEPT(?FIX::DoNotSend?) {try{FIX::PossDupFlag?possDupFlag;message.getHeader().getField(?possDupFlag?);if?(?possDupFlag?)?throw?FIX::DoNotSend();}catch?(?FIX::FieldNotFound&?)?{}std::cout?<<?std::endl<<?"OUT:?"?<<?message?<<?std::endl; }void?Application::onMessage (?const?FIX42::ExecutionReport&,?const?FIX::SessionID&?)?{}void?Application::onMessage (?const?FIX42::OrderCancelReject&,?const?FIX::SessionID&?)?{}void?Application::run() {while?(?true?){try{char?action?=?queryAction();if?(?action?==?'1'?)queryEnterOrder();else?if?(?action?==?'2'?)queryCancelOrder();else?if?(?action?==?'3'?)queryReplaceOrder();else?if?(?action?==?'5'?)break;}catch?(?std::exception?&?e?){std::cout?<<?"Message?Not?Sent:?"?<<?e.what();}} }void?Application::queryEnterOrder() {int?version?=?queryVersion();std::cout?<<?"\nNewOrderSingle\n";FIX::Message?order;switch?(?version?)?{case?42:order?=?queryNewOrderSingle42();break;default:std::cerr?<<?"No?test?for?version?"?<<?version?<<?std::endl;break;}if?(?queryConfirm(?"Send?order"?)?)FIX::Session::sendToTarget(?order?); }void?Application::queryCancelOrder() {int?version?=?queryVersion();std::cout?<<?"\nOrderCancelRequest\n";FIX::Message?cancel;switch?(?version?)?{case?42:cancel?=?queryOrderCancelRequest42();break;default:std::cerr?<<?"No?test?for?version?"?<<?version?<<?std::endl;break;}if?(?queryConfirm(?"Send?cancel"?)?)FIX::Session::sendToTarget(?cancel?); }void?Application::queryReplaceOrder() {int?version?=?queryVersion();std::cout?<<?"\nCancelReplaceRequest\n";FIX::Message?replace;switch?(?version?)?{case?42:replace?=?queryCancelReplaceRequest42();break;default:std::cerr?<<?"No?test?for?version?"?<<?version?<<?std::endl;break;}if?(?queryConfirm(?"Send?replace"?)?)FIX::Session::sendToTarget(?replace?); }FIX42::NewOrderSingle?Application::queryNewOrderSingle42() {FIX::OrdType?ordType;FIX42::NewOrderSingle?newOrderSingle(queryClOrdID(),?FIX::HandlInst(?'1'?),?querySymbol(),?querySide(),FIX::TransactTime(),?ordType?=?queryOrdType()?);newOrderSingle.set(?queryOrderQty()?);newOrderSingle.set(?queryTimeInForce()?);if?(?ordType?==?FIX::OrdType_LIMIT?||?ordType?==?FIX::OrdType_STOP_LIMIT?)newOrderSingle.set(?queryPrice()?);if?(?ordType?==?FIX::OrdType_STOP?||?ordType?==?FIX::OrdType_STOP_LIMIT?)newOrderSingle.set(?queryStopPx()?);queryHeader(?newOrderSingle.getHeader()?);return?newOrderSingle; }FIX42::OrderCancelRequest?Application::queryOrderCancelRequest42() {FIX42::OrderCancelRequest?orderCancelRequest(?queryOrigClOrdID(),queryClOrdID(),?querySymbol(),?querySide(),?FIX::TransactTime()?);orderCancelRequest.set(?queryOrderQty()?);queryHeader(?orderCancelRequest.getHeader()?);return?orderCancelRequest; }FIX42::OrderCancelReplaceRequest?Application::queryCancelReplaceRequest42() {FIX42::OrderCancelReplaceRequest?cancelReplaceRequest(queryOrigClOrdID(),?queryClOrdID(),?FIX::HandlInst(?'1'?),querySymbol(),?querySide(),?FIX::TransactTime(),?queryOrdType()?);if?(?queryConfirm(?"New?price"?)?)cancelReplaceRequest.set(?queryPrice()?);if?(?queryConfirm(?"New?quantity"?)?)cancelReplaceRequest.set(?queryOrderQty()?);queryHeader(?cancelReplaceRequest.getHeader()?);return?cancelReplaceRequest; }void?Application::queryHeader(?FIX::Header&?header?) {header.setField(?querySenderCompID()?);header.setField(?queryTargetCompID()?);if?(?queryConfirm(?"Use?a?TargetSubID"?)?)header.setField(?queryTargetSubID()?); }char?Application::queryAction() {char?value;std::cout?<<?std::endl<<?"1)?Enter?Order"?<<?std::endl<<?"2)?Cancel?Order"?<<?std::endl<<?"3)?Replace?Order"?<<?std::endl<<?"4)?Market?data?test"?<<?std::endl<<?"5)?Quit"?<<?std::endl<<?"Action:?";std::cin?>>?value;switch?(?value?){case?'1':?case?'2':?case?'3':?case?'4':?case?'5':?break;default:?throw?std::exception();}return?value; }int?Application::queryVersion() {char?value;std::cout?<<?std::endl<<?"1)?FIX.4.0"?<<?std::endl<<?"2)?FIX.4.1"?<<?std::endl<<?"3)?FIX.4.2"?<<?std::endl<<?"4)?FIX.4.3"?<<?std::endl<<?"5)?FIX.4.4"?<<?std::endl<<?"6)?FIXT.1.1?(FIX.5.0)"?<<?std::endl<<?"BeginString:?";std::cin?>>?value;switch?(?value?){case?'1':?return?40;case?'2':?return?41;case?'3':?return?42;case?'4':?return?43;case?'5':?return?44;case?'6':?return?50;default:?throw?std::exception();} }bool?Application::queryConfirm(?const?std::string&?query?) {std::string?value;std::cout?<<?std::endl?<<?query?<<?"?:?";std::cin?>>?value;return?toupper(?*value.c_str()?)?==?'Y'; }FIX::SenderCompID?Application::querySenderCompID() {std::string?value;std::cout?<<?std::endl?<<?"SenderCompID:?";std::cin?>>?value;return?FIX::SenderCompID(?value?); }FIX::TargetCompID?Application::queryTargetCompID() {std::string?value;std::cout?<<?std::endl?<<?"TargetCompID:?";std::cin?>>?value;return?FIX::TargetCompID(?value?); }FIX::TargetSubID?Application::queryTargetSubID() {std::string?value;std::cout?<<?std::endl?<<?"TargetSubID:?";std::cin?>>?value;return?FIX::TargetSubID(?value?); }FIX::ClOrdID?Application::queryClOrdID() {std::string?value;std::cout?<<?std::endl?<<?"ClOrdID:?";std::cin?>>?value;return?FIX::ClOrdID(?value?); }FIX::OrigClOrdID?Application::queryOrigClOrdID() {std::string?value;std::cout?<<?std::endl?<<?"OrigClOrdID:?";std::cin?>>?value;return?FIX::OrigClOrdID(?value?); }FIX::Symbol?Application::querySymbol() {std::string?value;std::cout?<<?std::endl?<<?"Symbol:?";std::cin?>>?value;return?FIX::Symbol(?value?); }FIX::Side?Application::querySide() {char?value;std::cout?<<?std::endl<<?"1)?Buy"?<<?std::endl<<?"2)?Sell"?<<?std::endl<<?"3)?Sell?Short"?<<?std::endl<<?"4)?Sell?Short?Exempt"?<<?std::endl<<?"5)?Cross"?<<?std::endl<<?"6)?Cross?Short"?<<?std::endl<<?"7)?Cross?Short?Exempt"?<<?std::endl<<?"Side:?";std::cin?>>?value;switch?(?value?){case?'1':?return?FIX::Side(?FIX::Side_BUY?);case?'2':?return?FIX::Side(?FIX::Side_SELL?);case?'3':?return?FIX::Side(?FIX::Side_SELL_SHORT?);case?'4':?return?FIX::Side(?FIX::Side_SELL_SHORT_EXEMPT?);case?'5':?return?FIX::Side(?FIX::Side_CROSS?);case?'6':?return?FIX::Side(?FIX::Side_CROSS_SHORT?);case?'7':?return?FIX::Side(?'A'?);default:?throw?std::exception();} }FIX::OrderQty?Application::queryOrderQty() {long?value;std::cout?<<?std::endl?<<?"OrderQty:?";std::cin?>>?value;return?FIX::OrderQty(?value?); }FIX::OrdType?Application::queryOrdType() {char?value;std::cout?<<?std::endl<<?"1)?Market"?<<?std::endl<<?"2)?Limit"?<<?std::endl<<?"3)?Stop"?<<?std::endl<<?"4)?Stop?Limit"?<<?std::endl<<?"OrdType:?";std::cin?>>?value;switch?(?value?){case?'1':?return?FIX::OrdType(?FIX::OrdType_MARKET?);case?'2':?return?FIX::OrdType(?FIX::OrdType_LIMIT?);case?'3':?return?FIX::OrdType(?FIX::OrdType_STOP?);case?'4':?return?FIX::OrdType(?FIX::OrdType_STOP_LIMIT?);default:?throw?std::exception();} }FIX::Price?Application::queryPrice() {double?value;std::cout?<<?std::endl?<<?"Price:?";std::cin?>>?value;return?FIX::Price(?value?); }FIX::StopPx?Application::queryStopPx() {double?value;std::cout?<<?std::endl?<<?"StopPx:?";std::cin?>>?value;return?FIX::StopPx(?value?); }FIX::TimeInForce?Application::queryTimeInForce() {char?value;std::cout?<<?std::endl<<?"1)?Day"?<<?std::endl<<?"2)?IOC"?<<?std::endl<<?"3)?OPG"?<<?std::endl<<?"4)?GTC"?<<?std::endl<<?"5)?GTX"?<<?std::endl<<?"TimeInForce:?";std::cin?>>?value;switch?(?value?){case?'1':?return?FIX::TimeInForce(?FIX::TimeInForce_DAY?);case?'2':?return?FIX::TimeInForce(?FIX::TimeInForce_IMMEDIATE_OR_CANCEL?);case?'3':?return?FIX::TimeInForce(?FIX::TimeInForce_AT_THE_OPENING?);case?'4':?return?FIX::TimeInForce(?FIX::TimeInForce_GOOD_TILL_CANCEL?);case?'5':?return?FIX::TimeInForce(?FIX::TimeInForce_GOOD_TILL_CROSSING?);default:?throw?std::exception();} }

main.cpp文件:

#include?"config.h" #include?"quickfix/FileStore.h" #include?"quickfix/SocketInitiator.h" #include?"quickfix/SessionSettings.h" #include?"quickfix/Log.h" #include?"Application.h" #include?<string> #include?<iostream> #include?<fstream>int?main(?int?argc,?char**?argv?) {if?(?argc?<?2?){std::cout?<<?"usage:?"?<<?argv[?0?]<<?"?FILE."?<<?std::endl;return?0;}std::string?file?=?argv[?1?];FIX::Initiator?*?initiator?=?0;try{FIX::SessionSettings?settings(?file?);Application?application;FIX::FileStoreFactory?storeFactory(?settings?);FIX::ScreenLogFactory?logFactory(?settings?);initiator?=?new?FIX::SocketInitiator(?application,?storeFactory,?settings,?logFactory?);initiator->start();application.run();initiator->stop();delete?initiator;return?0;}catch?(?std::exception?&?e?){std::cout?<<?e.what();delete?initiator;return?1;} }

總結

以上是生活随笔為你收集整理的交易系统开发(十一)——QuickFIX简介的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。