本系列力求手把手教你怎样利用 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 讲解(三)客户端的搭建与解析相关推荐

  1. 基于java的ftp客户端_基于Java的FTP客户端软件的设计

    基于的FTP客户端软件的设计(含选题审批表,任务书,开题报告,中期检查表,毕业论文8600字,答辩记录) 摘 要:FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中 ...

  2. java容器三:HashMap源码解析

    前言:Map接口 map是一个存储键值对的集合,实现了Map接口的主要类有以下几种 TreeMap:用红黑树实现 HashMap:数组和链表实现 HashTable:与HashMap类似,但是线程安全 ...

  3. java版mosquitto客户端使用SSL功能的具体操作总结

    在开发java版mosquitto客户端程序时需要使用paho库,如果开发的java客户端要用ssl功能,则需要Bouncy Castle库:在使用ssl功能时,需要证书文件进行进行身份认证,但在测试 ...

  4. java使用bks双向认证_客户端与服务器SSL双向认证(客户端:Android

    客户端与服务器SSL双向认证(客户端Android-服务端vc)-含源码(一)服务端已经生成了client.p12.server.p12.ca.p12:主要实现客户端过程(二)目录结构(三)客户端注 ...

  5. Java中利用socket实现简单的服务端与客户端的通信(中级)——实现任意双向通信

    本文计划采用socket实现客户端和服务端的任意双向通信,即客户端可以随时给服务端发消息,服务端也可以随时给客户端发消息,最终结果就是一个类似与QQ的聊天软件的功能. 以下代码可以直接拷贝到Eclip ...

  6. Java中利用socket实现简单的服务端与客户端的通信(基础级)

    在上一篇文章中,简单的介绍了java中入门级的socket编程,简单的实现了客户端像服务器端发送数据,服务器端将数据接收并显示在控制台,没有涉及多线程.上一篇文章的链接:Java中利用socket实现 ...

  7. 客户端是选择Java Swing还是C# Winform

    登录 | 注册 mentat的专栏 目录视图 摘要视图 订阅 [专家问答]韦玮:Python基础编程实战专题     [知识库]Swift资源大集合     [公告]博客新皮肤上线啦     快来领福 ...

  8. java后端获取客户端(用户)真实ip,原理

    java后端获取客户端真实ip,原理: 一般都是下面代码中的做法:但很多人只知道这样能拿到,稍微有改动就不知道怎么办了 看看网上的各种说法,接下来容我一一讲解,如有纰漏,敬请指正. public st ...

  9. 利用自定义的 ClassLoader 加密 Java Class 文件

    本文演示利用自定义的 ClassLoader 加密 Java Class 文件 首先,我们定义一个需要被加密的java Class: classload.MyClassBase. 为了让客户端使用,需 ...

最新文章

  1. linux下类似chkconfig的命令,Linux系统下chkconfig命令使用详解
  2. xcopy 跳过已经存在的_《天官赐福》舍不得跳过的片头片尾,无别,不散唱出花城心声...
  3. PLSQL 使用技巧汇总贴(一个坑)
  4. HanLP二元核心词典详细解析
  5. 搞懂这四个问题,企业数字化转型才可能成功
  6. numpy(3)-numpy.random.random() ,random_sample()连续均匀分布
  7. 【Linux网络编程】原始套接字实例:MAC 头部报文分析
  8. websphere内存设置_WebSphere Classloader内存泄漏预防
  9. pytorch 语义分割loss_vedaseg:基于pytorch的开源语义分割工具库,更多模型支持,更易拓展...
  10. 怎么判断linux22端口是否通,在Linux环境下使用SSH判断端口是否通(示例代码)
  11. 数字图像处理 空间域锐化 MATLAB实验
  12. 23亿美元大市场,NFV做好了准备吗?
  13. .NET生成静态页面并分页
  14. 关于pdf转html的个人方法,pdf转html的另类方法
  15. 安卓html 750px,移动端750px页面适配
  16. Gazbo下的无人车集群导航仿真
  17. react项目—单击按钮返回上一页
  18. 博客设计展示:25个优秀博客设计
  19. 谷雨主题的微信公众号图文排版有哪些技巧?
  20. AirSim学习(1)-介绍,安装,unity测试

热门文章

  1. 基于Axis服务端的webservice客户端实现
  2. 【整理】Linux常用命令
  3. iOS App如何连接外设
  4. MySQL主从复制(Master-Slave)与读写分离(MySQL-Proxy)实践
  5. OpenI部署二——转载
  6. DataList之数据操作
  7. 2008年最新的100条经典句子
  8. 技巧心得:Linux技巧小总结
  9. 如何在eclipse中使用分支合并功能
  10. 网络协议基础:“工作中模模糊糊的概念,这次终于理顺了!”