怎样利用超图客户端打点_QuickFix Java 讲解(三)客户端的搭建与解析
本系列力求手把手教你怎樣利用 QuickFix Java 搭建自己的 FIX 協議收法平臺,以及其中的注意事項。
所有源碼的地址(免費):
https://github.com/zongzhec/QuickFixPractise
這次我們討論怎樣搭建Initiator端。
4. Initiator 端的搭建
Initiator,也可以稱作為 Client,就是分散在各個地方的交易機。業務員在上面操作以后,客戶端會向服務器發送請求。請求多種多樣,基本常用的有:行情請求(35=V),新建訂單(35=D),撤銷訂單(35=F)。
搭建一個客戶端非常的簡單,只需要兩個類:一個類負責初始化、啟動和關停服務(起個名字叫FixInitiator);另一個類負責服務,即收發消息(起個名字叫FixInitiatorApplication)。
結構框架如下,詳細的在這里:https://github.com/zongzhec/QuickFixPractise/tree/master/FixInitiator
?
4.1. Property設置
Property在上一節已經做了大致講解,在這里先貼上源碼:
#quickfix-server.properties [default] # 這些字段記得改成你的設置 FileStorePath=fileStore SocketConnectHost=10.176.125.79 SocketConnectPort=10003 TargetCompID=QUICKFIX_ACCEPTOR# 以下字段可以不改 ConnectionType=initiator HeartBtInt=30 ReconnectInterval=10 FileLogPath=log UseDataDictionary=N DataDictionary=src/main/resources/FIX44.modified.xml ContinueInitializationOnError=Y BeginString=FIX.4.4 StartTime=00:00:00 EndTime=23:00:00 ResetOnLogon=Y ResetSeqNumFlag=Y MaxMessagesInResendRequest=1[session] SenderCompID=QUICKFIX_INITIATOR1[session] SenderCompID=QUICKFIX_INITIATOR2對于Initiator 來說,一定要寫ConnectionType=initiator,否則在啟動的時候會報錯,因為對應的session setting 沒有找到。
4.2. FixInitiator
這個類也是Initiator程序的主入口。除了標準化的startServer 和 stopServer,關鍵部分就是對SocketInitiator 的聲明和初始化,初始化需要上面提到的property文件,如果沒有的話會報錯。
另外需要注意的是在quickfix 包 和quickfix.fix44 里有一些名字相同的包,不要導錯了。有時候他們是extend 關系,編譯不會報錯,但是運行會突然報錯。
package foo.zongzhe.quickfix.initiator;import quickfix.*;public class FixInitiator {private static SocketInitiator initiator;private static SessionSettings settings;private static FixInitiatorApplication application;public static SocketInitiator getInitiator() {return initiator;}public FixInitiator() {try {settings = new SessionSettings("src/main/resources/quickfix.properties");} catch (ConfigError configError) {System.out.println("Warning: config error!" + configError);}application = new FixInitiatorApplication();MessageStoreFactory storeFactory = new FileStoreFactory(settings);LogFactory logFactory = new FileLogFactory(settings);MessageFactory messageFactory = new DefaultMessageFactory(); // 不是quickfix.fix44.MessageFactorytry {initiator = new SocketInitiator(application, storeFactory, settings, logFactory, messageFactory);} catch (ConfigError configError) {System.out.println("Warning: config error! " + configError);}}private void startServer() {try {initiator.start();} catch (ConfigError configError) {configError.printStackTrace();}}private void stopServer() {initiator.stop();}public static void main(String[] args) {FixInitiator fixInitiator = new FixInitiator();fixInitiator.startServer();// 啟動一個Session,記得參考你的quickfix.properties設定SessionID sessionID = new SessionID("FIX.4.4", "QUICKFIX_INITIATOR1", "QUICKFIX_ACCEPTOR");// 開始發點消息try {application.sendMarketDataRequest(sessionID);Thread.sleep(5000);application.sendNewOrderRequest(sessionID);Thread.sleep(5000);} catch (SessionNotFound | InterruptedException exception) {exception.printStackTrace();}}}4.3. FixInitiatorApplication
這里就是用來收發消息、解析消息的具體服務類。一方面要extends MessageCracker, 用來解析消息。另一方面要 implements Application,用來收法消息。
一旦implements Application,就要實現固定的幾個功能,里面可以什么也不寫,打印輸出,有個概念即可。
在extends MessageCracker后,可以重寫onMessage方法,針對不同的消息做不同的本地化處理。
詳見以下源碼:
package foo.zongzhe.quickfix.initiator;import quickfix.*; import quickfix.field.*; import quickfix.fix44.ExecutionReport; import quickfix.fix44.MarketDataRequest; import quickfix.fix44.MessageCracker; import quickfix.fix44.NewOrderSingle;import java.time.LocalDateTime;public class FixInitiatorApplication extends MessageCracker implements Application {// 以下是Application的固定七件套@Overridepublic void onCreate(SessionID sessionId) {System.out.println("onCreate is called");}@Overridepublic void onLogon(SessionID sessionId) {System.out.println("onLogon is called");}@Overridepublic void onLogout(SessionID sessionId) {System.out.println("onLogout is called");}@Overridepublic void toAdmin(Message message, SessionID sessionId) {System.out.println("toAdmin is called");}@Overridepublic void fromAdmin(Message message, SessionID sessionId) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon {System.out.println("fromAdmin is called");}@Overridepublic void toApp(Message message, SessionID sessionId) throws DoNotSend {System.out.println("toApp is called: " + message);}@Overridepublic void fromApp(Message message, SessionID sessionId) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType {System.out.println("fromApp is called");}// 以下是你可以自定義的消息接收器,來自MessageCracker@Overridepublic void onMessage(ExecutionReport message, SessionID sessionID) throws FieldNotFound, UnsupportedMessageType, IncorrectTagValue {System.out.println("Received ExecutionReport: " + message + ", sessionID: " + sessionID);// 收都收了,解析一下System.out.println(String.format("clOrderID: %s, symbol: %s, side: %s",message.getClOrdID().getValue(),message.getSymbol().getValue(),message.getSide().getValue()));}// 以下是發消息的功能/*** 訂閱行情消息** @param sessionID* @throws SessionNotFound*/public void sendMarketDataRequest(SessionID sessionID) throws SessionNotFound {// 具體set哪些字段,參考你的FIX44.modified.xmlMarketDataRequest req = new MarketDataRequest();req.set(new MDReqID("mockedMDReqID"));req.set(new SubscriptionRequestType('1'));// 重復組的設置MarketDataRequest.NoRelatedSym symGroup1 = new MarketDataRequest.NoRelatedSym();symGroup1.set(new Symbol("mockedSymbol1"));req.addGroup(symGroup1);MarketDataRequest.NoRelatedSym symGroup2 = new MarketDataRequest.NoRelatedSym();symGroup2.set(new Symbol("mockedSymbol2"));req.addGroup(symGroup2);System.out.println("Sending MarketDataRequest");Session.sendToTarget(req, sessionID);}/*** 下單* @param sessionID* @throws SessionNotFound*/public void sendNewOrderRequest(SessionID sessionID) throws SessionNotFound {NewOrderSingle order = new NewOrderSingle();LocalDateTime date = LocalDateTime.now();order.set(new ClOrdID("mockedClOrdID"));order.set(new Account("mockedAccount"));order.set(new HandlInst('1'));order.set(new OrderQty(45.00));order.set(new Price(25.88));order.set(new Symbol("mockedSymbol"));order.set(new Side(Side.BUY)); // 對于枚舉型對象也可以這么設置order.set(new OrdType(OrdType.LIMIT));Session.sendToTarget(order, sessionID);} }4.4. 運行及結果
運行以后,如果看到“onCreate is called”的字樣,就說明已經通了,準備開始給服務器發消息了。
而“toApp is called” 標明你已經向服務器發送了消息,正在等回應。(注意上節文章說的要修改的配置,比如IP地址!)
?
下節講怎么搭建服務器端,下課。
總結
以上是生活随笔為你收集整理的怎样利用超图客户端打点_QuickFix Java 讲解(三)客户端的搭建与解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: fputc会覆盖吗_墨粉寿命和打印的文件
- 下一篇: 人生永无止境的意思是什么_什么是莫比乌斯