Fix协议的开源实现QuickFIX_J(上)

192次阅读

共计 4196 个字符,预计需要花费 11 分钟才能阅读完成。

01 QuickFIX/ J 背景

1.1Fix 协议

金融信息交换协议(Fix)是适用于证券、期货等金融领域的国际标准化通信协议,具有数据结构标准化、语法简单、定义灵活、易于拓展的特点。作为金融信息交换的公有协议,够降低金融机构连接的成本及复杂性,降低软硬件成本等。

Fix 协议在国外使用情况:CME 在市场数据、交易、清算等等大部分的业务场景都提供了 Fix 协议的接入接口。

Fix 协议在国内使用情况: 目前有两个典型场景,一个是深交所在 Fix 基础上经过本地化后的 Setp 协议,另一个是上海证券交易所在 Fix 基础上经过本地化后的 FAST 协议。

1.2 QuickFIX/J

 QuickFIX 引擎是世界上第一个实现 FIX 协议的开源实现,开发语言 C ++。
 官网地址: http://www.quickfixengine.org
 QuickFix/ J 是实现了 FIX 协议所有版本及其功能的开源软件,100% 使用 JAVA 实现。
 除了 JAVA 之外,QuickFIX 引擎还支持 QuickFIX/N(.net 实现),QuickFIX/GO(GO 实现) 等等。
 本文主要介绍的是 QuickFIX 的 JAVA 实现 QuickFIX/J。

02 QuickFIX/ J 基本概念

2.1 Initiator

发起者,作为信息的发送方 (CLIENT),负责建立通信连接 (类似于会员的交易柜台)。

2.2 Acceptor

接收者,作为信息的接收方 (SERVER),负责接收通信连接 (类似于交易所的前置机)。

2.3 FIX IOSession

网络层 Session,负责管理 Initiator 和 Acceptor 网络层,主要包括设置网络连接属性、建立连接、断开连接、收发信息等。

2.4 FIX Session

应用层 Session,应用程序使用网络的接口,提供应用程序对网路的管理,主要包括登陆、注销、心跳、消息编号、消息重发、Application interface 接口回调等。

2.5 Fix Connection

Initiator:作为客户端在应用程序启动时,建立 FIX Session,接着这个 FIX Session 会创建 FIX IOSession,发送连接请求。

Acceptor:监听到 Initiator 的连接请求后,经过检查可以连接的话,建立服务端 FIX IOSession 和 FIX Session。这样便建立了一个 Fix Connection

2.6 Fix Application interface

 QuickFIX/ J 提供给应用程序的接口,所有信息最终都会流入该接口的回调方法中。业务层的开发主要基于该接口实现。

03 QuickFIX/ J 结构 (Acceptor/Initiator)

Fix 协议的开源实现 QuickFIX_J(上)

网络层:TCP/IP

传输层:Apache Mina。

会话层:QuickFIX/J IOSession  

应用层:QuickFIX/J Session 和 Application

3.1 Apache Mina

Apache Mina 是一个能够帮助用户开发高性能和高伸缩性网络应用程序的框架,通过 Java nio 技术基于 TCP/IP 和 UDP/IP 协议提供了抽象的、事件驱动的、异步的 API。
是对 NIO 框架进行了一层封装的 Socket 库。基本功能同国内互联网公司常用的 Netty 框架类似。QuickFIX/ J 里的核心组件 IoSession 就是通过 Mina 提供的接口并对其进行封装后作为网络层基础。

3.2 IOSession

IOSession 是 QuickFIX/ J 的核心通讯组件,底层使用 MINA。网络的属性经过应用层 session,将 Settings 配置传递给 IOSession 来设置。具体属性参考下表:

Fix 协议的开源实现 QuickFIX_J(上)

Fix 协议的开源实现 QuickFIX_J(上)

3.3 Session

应用层 session,负责处理所有的消息,包括登陆、注销、心跳、消息编号、消息重发、消息验证、并将消息提供给具体的业务模块进行处理。

消息编号:所有的消息都由一个唯一的序列号进行标示,序列号在每一个会话开始时被初始化为 1,在会话期间递增。每个会话将建立一个发送序号和一个接收序号。
心跳:在消息交互期间,周期性发送 Heartbeat 心跳消息。该心跳消息可以监控通信链路状态及识别接收序列号间隙。
断线重连:监听网络,当出现网络断开、心跳超时等情况进行重连处理,CLIENT 可以进行简单的故障转移,连接新的 SERVER。
消息重发:每次处理消息时,通过对比收发两端的消息编号,确定消息是否丢失,如果丢失进行重新发送,保证消息可靠性。
消息验证:如果配置了 DataDictionary,则除了对消息的格式符合 FIX 语义进行检查外,还验证消息中的内容是否符合数据字典中定义的规则

3.3.1.    Settings

Settings 是应用层 session 依赖的配置组件,解析 cfg 文件所配置的系统运行需要的信息并存储起来,提供给系统其他组件使用。

3.3.2.    LogFactory

日志组件,支持多种方式。包括:SLF4JLog、FileLog、ScreenLog、JdbcLog。

3.3.3.    MessageFactory

消息工厂,负责创建具体 FIX message。例如:登录消息

Message logon = messageFactory.create(sessionID.getBeginString(), MsgType.LOGON);

3.3.4.    MessageStore

消息的存储组件,支持非持久化的内存存储 MemoryStore 和持久化的文件存储 FileStore、数据库存储 JdbcStore 三种方式。
持久化存储可以进行故障恢复,通常情况 Acceptor 和 Initiator 都会采用文件存储消息。文件存储使用 RandomAccessFile 可以根据配置进行同步或异步刷盘。

3.4 Appication

3.4.1.   EventHandlingStrategy

FIX 消息的事件处理器,所有收到的消息均交给该事件处理器进行处理。内部使用队列缓存和分发消息,将消息提供给应用程序进行业务处理。

支持单线程模式的 SingleThreadedEventHandlingStrategy 和多线程模式的 ThreadPerSessionEventHandlingStrategy。通常客户端采用单线程模式,服务端采用多线程模式。

3.4.2.   Application Interface

应用程序的编程接口,在此处对消息进行业务上的处理。QuickFIX/ J 提供给业务的编程接口十分简洁,目前仅 7 个方法,具体见下表:

Fix 协议的开源实现 QuickFIX_J(上)

注: QuickFIX/ J 将所有消息分为两类,管理消息和应用消息。管理消息包括登录、注销、心跳、测试、拒绝、重发、同步消息编号,其他的为应用消息。

3.5 消息收发流程

Fix 协议的开源实现 QuickFIX_J(上)

3.5.1  消息接收流程

  1. 机器网卡上接收到来自网络的 TCP/IP 消息,发送给 MINA

  2. MINA 内部的 IoService 对接收消息的消息建立异步的消息事件, 发送给 IoFilterChain 过滤器链

3.IoFilterChain 的中先通过 SSLFilter 使用对消息进行 ssl 解密, 然后通过 FixProtocolCodecFilter 对消息按照 Fix 格式解包得到 Fix 消息,再将 Fix 消息发送给 IoHandler

4.IoHandler 收到消息后, 经过简单处理后, 派发给事件处理器 EventHandlingStrategy 的队列中

5.EventHandlingStrategy 从队列中取出消息, 找到对应的 session 进行调用

6.Session 处理消息, 并回调应用程序 Application Interface, Application Interface 根据不同的消息来进行业务处理

3.5.2 消息接收流程

  1. 应用程序 Application Interface 产生消息后通过 session 发送该消息

  2. Session 将消息发送给 IoFilterChain

  3. IoFilterChain 的中先通过 FixProtocolCodecFilter 对消息按照 Fix 格式封包,然后通过 SSLFilter 使用对消息进行 ssl 加密, 将经过 ssl 加密的消息发送给 MINA

  4. MINA 内部将消息通过 TCP/IP 发送到网络上

04 QuickFIX/ J 消息

4.1 消息格式

Fix 协议的结构有两种类型,一种是基于“< 标记 >=< 值 >”的二进制字节流,用 SOH(0x01) 进行分割。

二进制字节流例子:登陆请求

8=FIX.4.4SOH9=85SOH35=ASOH34=1SOH49=CLIENT1SOH52=20200405-13:22:21.659SOH56=SERVER1SOH98=SOH0108=30SOH553=zykSOH554=321SOH10=162

< 标记 >8 表示协议版本 FIX.4.4,< 标记 >9 表示消息的长度 85,< 标记 >35 消息类型 A(登陆请求),< 标记 >34 表示消息编号为 1,< 标记 >49 表示消息发送方为 CLIENT…。

 每个 < 标记 > 代表不同的含义,其中 Fix 协议规定了 0~5000 的标记含义,5000 值 9999 的标记号可以由使用者自定义,这部分标记值用于企业联盟的信息交换,可以通过 Fix 网站进行注册。10000 以上保留用于企业内部使用,不需要注册。

另一种是采用 XML 描述的 FIXML 结构。

FIXML 例子:Sample Sec Def for a Regular Future

Fix 协议的开源实现 QuickFIX_J(上)

由于 XML 结构冗余信息较多,带宽的占用率较高,所有一般采用基于“< 标记 >=< 值 >”的二进制字节流。本文以下主要介绍第一种基于“< 标记 >=< 值 >”的二进制字节流。

4.2 消息结构

一个 Fix 消息由消息头、消息体、消息尾三个部分组成。

4.2.1.  消息头

消息头记录了消息类型、消息体长度、发送目的地、消息序号、发送起始点和发送时间等等。

Fix 协议的开源实现 QuickFIX_J(上)

4.2.2.  消息体

消息体记录具体的数据内容。消息体内容在 Fix 规范中通过 xml 定义。以下是 FIX4.4 中登陆消息的定义。每个 field 对应一个 < 标记 >

Fix 协议的开源实现 QuickFIX_J(上)

4.2.3.  消息尾

消息尾记录数字签名内容和校验和。

Fix 协议的开源实现 QuickFIX_J(上)

4.3 消息扩展

QuickFIX/ J 中的 Fix 所有消息是通过标准的 FIX.xml 生成的,因此自定义扩展消息十分方便。如果要扩展消息,只需要修改 FIX.xml,然后重新生成即可。

扩展消息例子:在 xml 中增加以下内容

Fix 协议的开源实现 QuickFIX_J(上)

执行 MessageCodeGenerator.generate() 方法即可重新生成消息的代码。

正文完
扫码关注公众学习更多内容
post-qrcode
   
jiajianfa007
版权声明:本站原创文章,由 jiajianfa007 2025-02-26发表,共计4196字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。