作者:姜永念
宜信技术学院
定义
FIX协议是由国际FIX协会组织提供的一个开放式协议,目的是推动国际贸易电子化的进程,在各类参与者之间,包括投资经理、经纪人,买方、卖方建立起实时的电子化通讯协议。FIX协议的目标是把各类证券金融业务需求流程格式化,使之成为一个个可用计算机语言描述的功能流程,并在每个业务功能接口上统一交换格式,方便各个功能模块的连接。
协议工作原理
通信模型及基本概念
通信模型
- Initiator :发起者,建立通信连路,通过发送初始Logon消息发起会话的参与方。
- Acceptor :接收方 FIX会话的接收方。负责执行第一层次的认证和通过传输Logon消息的确认正式声明连接请求被接受。
- 原则:先发起者为Initiator ,接受者为Acceptor 。
- 标准模式以网关为Acceptor,客户端为Initiator做为常用模式。
Fix connection
- FIX连接 由3部分组成:logon登录,message exchange消息传输,logout注销。
- logon登录
- logout注销
- logon登录
Fix session
- FIX会话由一个或多个FIX Connection FIX连接组成。一个FIX会话可以有多次登录。
序列号
- 所有的FIX消息都由一个唯一的序列号进行标示。序列号在每一个FIX会话开始时被初始化为1,并在整个会话期间递增。监控序列号可以使会话参与者识别和处理丢失的消息,当在一个FIX会话中重新连接时能够快速进行应用程序同步。
- 每个会话将建立一组互不依赖的接受和发送序列。会话参与者将维护一个赋予发送消息的序列和一个监控接受消息的消息块间隙序列号。
心跳
- 在消息交互期间,FIX应用程序将周期性产生Heartbeat心跳消息。该心跳消息可以监控通信链路状态及识别接收序列号间隙。发送Heartbeat的周期间隔由会话发起者使用在Logon消息中HeartBtInt域进行定义。
- Heartbeat心跳消息的时间间隔应当在每一个消息发送后复位,即发送一个消息后,在间隔给定的时间内无其它消息发送则发送一个Heartbeat心跳消息。HeartBtInt的值应当被会话双方认同,由会话发起方定义并由会话接收者通过Logon消息进行确认。同一个HeartBtInt被会话双方——登录的发起者和登录的接受者共同使用。
数据完整校验
- 消息数据内容的完整性可以参用两种方式来验证:消息长度和效验码检查。
- 程序通过计算BodyLength域到CheckSum标记(“10=”)分界符的字符数,域BodyLength标示的消息长度进行比较来完成完整性效验。
- ChekSum完整性检查,通过计算从域“8=” 中“8”开始,包括紧跟在CheckSum标记域的分界符每个字符的2进制和同CheckSum进行比较得到。
- 一个FIX消息校验和通过计算到ChechSum域(但不包括)的消息的每个字节和得到。然后,校验和被转换为模256的数字用于传送和比较。校验和在所有加密操作之后被计算。
- 校验代码:
样例:8=FIX.4.29=7335=A34=149=CLIENT52=20181119-10:42:48.76856=SERVER98=0108=30141=Y10=208
1、消息长度:9=73
35=A34=149=CLIENT52=20181119-10:42:48.76856=SERVER98=0108=30141=Y(这段长度)
2、效验码检查
char *GenerateCheckSum( char *buf, long bufLen ) {
static char tmpBuf[ 4 ]; long idx;
unsigned int cks;
for( idx = 0L, cks = 0; idx < bufLen; cks += (unsigned int)buf[ idx++ ] ); sprintf( tmpBuf, “%03d”, (unsigned int)( cks % 256 ) );
return( tmpBuf );
}
消息确认
- FIX协议不支持单个消息的确认。采用的是监控消息时隙的方法来进行消息恢复和验证。
- 普通的数据传送(无单个消息确认)通过消息序列间隙进行错误识别。每个消息由一个唯一的序列号进行标示。接收端应用程序负责监控接收消息序列号以识别消息间隙并产生重传请求。
- 每个FIX参与方必须为FIX会话维护两个序列号,一个是接收序列号,一个是发送序列号,两者都在建立FIX会话开始时初始化为1。每个消息被赋予一个唯一的序列号值,并在消息发送后递增。此外,每个收到的消息都有一个唯一的序列号,接收序列号计数器在收到每个消息后将会被递增。
- 当接收序列号与所希望得到的的正确序列号不必配时,必须采取纠错处理。
加密
- 加密算法由连接双方共同协商。
- 一个消息的任何一个域可以被加密并放在SecureData域中。然而,一些显示的标志域必须采用明文进行传输。为确保完整性,明文域可以在SecureData域中重复。
- 当使用加密时,建议但不是必须,所有的消息体都进行加密。如果一个消息中的重复组数据中的部分数据要加密,这个重复组必须全部进行加密。
- 预先协商好的加密算法在Logon消息中进行声明。
自定义域
- FIX为给用户提供最大的灵活性,FIX协议允许用户自定义域。这些域在认同的参与者之间实现、应用,并且应注意避免冲突。
- Tag数在5000 到9999保留用于用户自定义域。这些tag值用于企业联盟的信息交换。可以通过FIX网站进行注册。
- 10000以上保留用于单一企业内部使用。不用注册。
消息格式
数据类型
整数int,浮点数float,单个字符char,布尔Boolean,字符串String,数据data
域
常见域
Tag(标记) | FieldName(域名) | 备注 |
---|---|---|
8 | BeginString | 起始串,FIX协议版本 |
9 | BodyLength | 消息长度 |
35 | MsgType | 消息类型:例如F=Order Cancel Request,取消订单 |
11 | ClOrdID | 客户端订单ID |
37 | OrderID | 服务端订单ID |
41 | OrigClOrdID | 原始客户端订单ID |
54 | Side | 买卖类型。例如:1 = Buy,2 = Sell |
55 | Symbol | 股票代码。例如:YRD |
10 | CheckSum | 校验码 |
域语法
- 开始部分应是消息头,随后是正文,最后是消息尾;
- 消息头的前 3 个域的次序不能改变:起始串(Tag =8)、消息体长度(Tag =9)、消息类型(Tag
=35); - 消息尾的最后一个域应是校验和域(Tag=10);
- 重复组中,域出现的顺序应遵循该重复组在消息或组件中定义时的次序;
- 在一条消息中,除重复组域外任何其他域不能重复出现。
安全与加密
- 由于消息有可能在公网或不安全的网络上传输交换,因此需要对相关的敏感数据加密处理。
- 具体加密的方法由连接双方达成的协议而定。
- 消息内除某些需要公开识别的域以明文传输外其他任何域都可以加密放置密文数据域
(SecureData)内。当然,这些被加密的域也可以同时保留明文的表示方式。 - 当决定使用加密方案时,可以对消息正文内所有的域加密。如果消息的重复组内有部分需要加密的,那么要求对整个重复组加密。
- 本协议还提供的一些域用以支持数字签名、密钥交换和正文加密等安全技术。
消息
消息头
每一个会话或应用消息有一个消息头,该消息头指明消息类型、消息体长度、发送目的地、消息序号、发送起始点和发送时间。
Tag | 域名 | 必需 | 说明 |
---|---|---|---|
8 | BeginString | Y | 起始串,取值:FIX.4.2(不可加密,消息的第一个域) |
9 | BodyLength | Y | 消息体长度(不可加密,消息的第二个域) |
35 | MsgType | Y | 消息类型(不可加密,消息的第三个域) |
49 | SenderCompID | Y | 发送方代码(不可加密,发送方标识符) |
56 | TargetCompID | Y | 接收方代码(不可加密,接收方标识符) |
115 | OnBehalfOfCompID | N | 最初发送方标识符(可加密),用于经第三方发送。 |
128 | DeliverToCompID | N | 最终接收方标识符(可加密),用于经第三方发送。 |
90 | SecureDataLen | N | 密文数据长度 |
91 | SecureData | N | 密文数据(紧跟密文数据长度域) |
34 | MsgSeqNum | Y | 消息序号(可加密),如果交易双方不采用 FIX 会话 机制,可将该 tag 置为一个固定的值,例如 0。 |
50 | SenderSubID | N | 发送方子标识符(可加密) |
142 | SenderLocationID | N | 发送方方位标识符(可加密) |
57 | TargetSubID | N | 接收方子标识符(可加密) |
143 | TargetLocationID | N | 接收方方位标识符(可加密) |
116 | OnBehalfOfSubID | N | 最初发送方子标识符(可加密) |
144 | OnBehalfOfLocationID | N | 最初发送方方位标识符(可加密) |
129 | DeliverToSubID | N | 最终接收方子标识符(可加密) |
145 | DeliverToLocationID | N | 最终接收方方位标识符(可加密) |
43 | PossDupFlag | N | 可能重复标志,重复发送时,作此标记。(可加密) |
97 | PossResend | N | 可能重发标志。(可加密) |
52 | SendingTime | Y | 发送时间(可加密) |
122 | OrigSendingTime | N | 原始发送时间(可加密) |
347 | MessageEncoding | N | 消息中 Encoded 域的字符编码类型(非 ASCII 码) |
369 | LastMsgSeqNumProcesse d | N | 最后处理消息序号(可加密) |
370 | OnBehalfOfSendingTime | N | 最初发送时间(用 UTC 表示时间) |
消息尾
每一个消息(会话或应用消息)有一个消息尾,并以此终止。消息尾可用于分隔多个消息,包含有 3 位数的校验和值。
Tag | 域名 | 必需 | 说明 |
---|---|---|---|
93 | SignatureLength | N | 数字签名长度(不可加密) |
89 | Signature | N | 数字签名(不可加密) |
10 | CheckSum | Y | 校验和,消息的最末域。(不可加密) |
新订单消息(MsgType=D)
对于在消息头中设置了 PossResend 标志的订单消息,应当使用交易客户方订单编号(ClOrdID)核
实是否已收到该订单,具体实现时还应检查订单参数(买卖方向、证券代码、数量等)进行核实。如果 之前收到该订单,应以执行报告消息回应订单状态。如果之前未收到,则以执行报告消息回应订单确认。
Tag | 域名 | 必需 | 说明 |
---|---|---|---|
标准消息头 | Y | MsgType=D | |
11 | ClOrdID | Y | 交易客户方订单编号,在订单有效交易日内必需 |
109 | ClientID | Y | 客户资金帐号 |
1 | Account | Y | 客户交易编码 |
110 | MinQty | N | 最小成交量。 |
55 | Symbol | Y | 期货合约代码 |
167 | SecurityType | N | FUT = 期货 |
200 | MaturityMonthYear | N | 用于指定期货到期的年和月 |
205 | MaturityDay | N | 用于期货的到期日期,并被与到期年月 (MaturityMonthYear)联合使用 |
207 | SecurityExchange | Y | 用于指定交易所 |
77 | OpenClose | Y | 指明开仓,平仓 |
8009 | HedgeFlag | Y | 投机套保标志 |
8010 | TouchCondition | N | 触发条件 |
54 | Side | Y | 买卖方向 |
38 | OrderQty | N | 委托手数 |
60 | TransactTime | Y | 订单发起时间 |
40 | OrdType | Y | 订单类型 |
44 | Price | N | 价格(限价订单时有效) |
423 | PriceType | N | 价格类型 |
99 | StopPx | N | 停止价 |
15 | Currency | N | 币种 |
59 | TimeInForce | N | 新订单生效时间,默认为当日有效 |
168 | EffectiveTime | N | 用于指定定单有效的时间 |
432 | ExpireDate | N | 有条件地用于在生效时间(TimeInForce)=在某 日前有效(GTD),而没有指定截止时间 (ExpireTime)的情况之下 |
126 | ExpireTime | N | 有条件地用于生效时间(TimeInForce) = 在某 日前有效(GTD)和到期日没有被指定的情况之 下 |
8096 | MacNetInfo | N | 委托方的机器网络信息 |
标准消息尾 | Y |
执行报告消息(MsgType=8)
- 订单确认
- 订单状态变化确认(如撤单确认)
- 发送订单的成交回报
- 订单拒绝
Tag | 域名 | 必需 | 说明 |
---|---|---|---|
标准消息头 | Y | MsgType=8 | |
37 | OrderID | Y | 期货公司委托号,同个交易日必需保证唯一 |
11 | ClOrdID | N | 交易客户方订单编号。如果是强平回报,则该值 取值为以”NONE”开头的当天交易日唯一的字符 串标识 |
41 | OrigClOrdID | N | 原始交易客户方订单编号,指示被撤消订单的 ClOrdID |
17 | ExecID | Y | 期货公司的执行编号,在订单有效交易日内应保 证唯一 |
150 | ExecType | Y | 执行类型 |
39 | OrdStatus | Y | 订单状态 |
103 | OrdRejReason | N | 订单拒绝时需要 |
109 | ClientID | Y | 客户资金帐号 |
1 | Account | Y | 客户交易 |