随着网络的使用,目前所有大型的金融机构都已经实现了自动化和数字化。当中肯定少不了互联网的加入,那么在这当中,我们主要介绍一下FIX协议。它是由国际FIX协会组织提供的一个开放式协议,目的是推动国际贸易电子化的进程,在各类参与者之间,包括投资经理、经纪人,买方、卖方建立起实时的电子化通讯协议。Fix协议的目标是把各类证券金融业务需求流程格式化,使之成为一个个可用计算机语言描述的功能流程,并在每个业务功能接口上统一交换格式,方便各个功能模块的连接。
FIX协议结构
当前,FIX协议的格式存在着两种结构:"标记(Tag)〉=〈值(Value)"域结构和 FIXML 结构。下面针对域结构模式对FIX协议的组成,连接建立、信息交换方法等进行简要说明,以便于了解FIX协议的概念。
FIX信息格式
(1) 信息格式
一条FIX协议信息的基本格式是:
《标准头》+《信息正文域》+《标准尾》
每条信息都是由一系列带有〈标记(Tag)〉=〈值(Value)〉的域组成的。在每个域之间通过"< >"分开。除了一些特殊规定外,信息中的域可按照任意顺序排列。所有域在都以"定界符"(#001;0x01H,文档中写为<SOH>)表示终止。
(2) 标准的信息标题
每条命令或应用信息都有一个标准的标题。标题表明了信息类型、长席、目的地、序号、起始点和时间。
(3) 标准的信息尾部
所有的信息,无论是命令类的,还是应用类的,以一个标准结尾终止。尾部被用来把信息分离,并包括含有3位数的"检验和"值。
(4) 数据类型
各域所使用的数据类型包括以下几种:整数、浮点数、布尔数、字符串、多元值串、货币、交易所字符串域、国际标准时时间戳、国际标准时时间、本地市场日期等。
(5) 数据完整性
信息数据内容是否完整可以通过"检查信息长度"和字符的简单"检验和"两个方法进行检查。
(6) 加密
为了保证信息安全,对传递的信息需要加密,加密方法的选择由传送中的有关双方协议而定。任何域都可被加密并被添加于"密码"的域内,不过,被确信可被清楚识别的域必须以非加密方式进行传送,这些公开的域(非加密)能在密码的域内被重复以完整地检验公开的数据。
FIX协议的连接建立
建立一个FIX连接包括:电信层面连接的创立、经由接收方对发起方的确认、信息同步三个步骤。
FIX信息交换过程的实施
FIX信息交换过程的定义为:
在两方之间,一个连续的序号系列范围内的双向定单信息传送。每条信息都有独特的序号识别。在每次FIX交换过程开始时,就是序号的开始,首先从1开始,并依次增加直至贯穿整个交换过程。当在FIX交换过程中重新进行连接的时候,监控序号将能使各方能识别错过的信息,并能做出反应,来使应用方达到一致地同步。
在整个信息没有被激活的时期里,信息交换方将在有规则的时间间隔里产生"心跳信息"。通过"心跳信息"可监控通信连接的状况,识别进入的序号缺口,并确认是否接收到最后的信息串。"心跳间隔"是由交换过程发起人使用"心跳指令"域在"登录"信息中宣布的。
当信息交换连接的任何一方在"心跳指令"的时间内都不发送任何数据的时候,"心跳信息"将被传送。当连接的任何一方在"心跳指令"+"合理的传输时间"的时间内仍没有收到"心跳信息",那么,可以认为此次连接失败,而且需开始实施修正操作。如果"心跳指令"被设置为零,将不会生成定期的"心跳信息"。
FIX的连接注销
信息交换过程的正常结束是通过双方互相发送"注销"(Logout)信息来完成。"注销"信息是开始或确认一个FIX过程终止的信息,未经"注销"信息的交换而断开的连接是反常情况,并应按错误来处理。
FIX通信协议的应用
针对国内的证券交易模式的分布式结构,即证券公司的各营业部、分支机构数据分布存放,各自独立,直接与交易所联系,国内券商正在探讨并逐步推出集中交易系统,集中交易系统可以带来集中风险控制、提高系统效率等优势,可以在集中交易系统的构建、规划过程中,借鉴应用FIX标准化协议,构建具有数据层、核心业务层+FIX通信层、应用层的广义三层结构。用FIX金融信息交换协议包取代过去的文件或通信包交换的模式。
在FIX协议的应用过程中应该注意到,由于亚洲地区的证券交易方式与FIX协议的主导地区美洲和欧洲国家有一定的差异,因此直接利用现有的FIX协议,特别是证券业务流程上的规范有一定的困难。
例如FIX协议在日本证券行业的应用就遇到了信息定义内容和信息流程顺序上的问题。因此国内的FIX的开展首先要关注FIX及其在中国的适用性,吸收其它市场的经验,将国内外不同的交易程序加以比较,分析协议的使用方法以及协议使用环境,结合国内证券市场的实际,使得该项协议既能成为一项标准又能为中国证券市场服务,为中国证券交易的标准化过程中发挥作用。
| 消息类型 | 序列号不必陪时的处理 | 
| Logon | 必须是传送的第一个消息。认证和接受连接。如果一个消息间隙在logon序列号中被检测到,那么在返回一个Logon确认消息后,发送一个ResendRequest | 
| Logout | 如果一个消息间隙被检测到,在确认Logout消息发送之后再发起一个ResendRequest以补偿所有丢失消息。不要终止会话。Logout消息的发起方负责终止会话。这样可以允许Logout发起者对任何ResendRequest消息进行响应。 如果是Logout的发起方,那么这是一个Logout确认消息,必须在收到之后立即终止会话。 唯一一个“不终止会话”的例外是无效的Logout尝试。会话接收者有权发送一个Logout消息并立即终止会话。这样可以减少未经授权的连接尝试。 | 
| ResendRequest | 首先执行重传处理,接着按照自己的顺序发送ResendRequest消息用以填充接收消息间隙。 | 
| SeqReset-Reset | 忽略接收序列号。SeqReset消息的NewSeqNo将包含下一个传送消息的序列号。 | 
| SeqReset-GapFill | 发送一个返回ResendRequest。间隙填充消息行为与SeqReset消息相似。然而,确认没有消息被连续地跳过是非常重要的。这意味着GapFill消息必须按顺序接收。一个无序的GapFill消息时则表明一种异常情况。 | 
| 所有的其他类型消息 | 执行间隙填充操作。 | 
| SenderCompID | OnBehalfOfCompID | TartgetCompID | DelivrToCompID | |
| A 到B | A | B | ||
| B 到 A | B | A | 
| SenderCompID | OnBehalfOf CompID | TargetCompID | DeliverTo CompID | DeliverTo CompID | HopSendingTime | |
| 从A通过Q到B | ||||||
| 1 A到Q | A | Q | B | |||
| 2 Q到B | Q | A | B | Q | A的发送时间 | |
| B通过Q响应A | ||||||
| 1 B到Q | B | Q | A | |||
| 2 Q到A | Q | B | A | Q | B的发送时间 | |
| A通过Q发送到B和C | ||||||
| 1A到Q | A | Q | B | |||
| 2Q到B | Q | A | B | Q | A的发送时间 | |
| 3A到Q | A | Q | C | |||
| 4Q到C | Q | A | C | Q | A的发送时间 | |
| B和C通过Q发送到A | ||||||
| 1B到Q | B | Q | A | |||
| 2Q到A | Q | B | A | Q | B的发送时间 | |
| 3C到Q | C | Q | A | |||
| 4Q到A | Q | C | A | Q | C的发送时间 | |
| Tag (标记) | FieldName (域名) | Req’d (必选) | 备注 | |
| 8 | BeginString | Y | FIXT.1.1(不能加密,必须是消息的第一个域) | |
| 9 | BodyLength | Y | (不能加密,必须是消息的第二个域) | |
| 35 | MsgType | Y | (不能加密,必须是消息的第三个域) | |
| 1128 | ApplVerID | N | 使用SP标示方法标明应用版本。ApplVerID用于一个特定消息的场景 | |
| 1129 | CstmApplVerID | N | 用于支持客户共同协商认可的功能 | |
| 49 | SenderCompID | Y | (不能被加密) | |
| 56 | TargetCompID | Y | (不能被加密) | |
| 115 | OnBehalfOfCompID | N | 通过第三方发送消息时交易参与者企业ID(可以内置于坚密数据部分) | |
| 128 | DeliverToCompID | N | 通过第三方发送消息时交易参与者企业ID(可以内置于坚密数据部分) | |
| 90 | SecureDataLen | N | 用于标示消息加密部分的长度时必选(不能加密) | |
| 91 | SecureData | N | 消息体加密时必选。总紧跟在SercureDataLen域之后 | |
| 34 | MsgSeqNum | Y | (可以内置于坚密数据部分) | |
| 50 | SenderSubID | N | (可以内置于坚密数据部分) | |
| 142 | SenderLocationID | N | 发送者的LocationID(如,地理位置和或席位(desk))(可以内置于坚密数据部分) | |
| 57 | TargetSubID | N | 为管理消息保留,不针对一个特定用户。(可以内置于坚密数据部分) | |
| 143 | TargetLocationID | N | 交易参与者LocationID(如,地理位置和或席位(desk))(可以内置于坚密数据部分) | |
| 116 | OnBehalfOfSubID | N | 交易参与者SubID,用于通过第三方传送消息。(可以内置于坚密数据部分) | |
| 144 | OnBehalfOfLocation | N | 交易参与者的LocationID(如,地理位置和或席位(desk))(可以内置于坚密数据部分) | |
| 129 | DeliverToSubID | N | 交易参与者SubID,用于通过第三方传送消息。(可以内置于坚密数据部分) | |
| 145 | DeliverToLocationID | N | 交易参与者的LocationID(如,地理位置和或席位(desk))(可以内置于坚密数据部分) | |
| 43 | PossDupFlag | N | 当重传消息时总是必选,无论是由发送方系统提示,还是作为重传请求的响应结果。(可以内置于坚密数据部分) | |
| 97 | PossResend | N | 当消息可能是另一个消息的复制消息且使用一个不同的序列号时必选。(可以内置于坚密数据部分) | |
| 52 | SendingTime | Y | (可以内置于坚密数据部分) | |
| 122 | OrigSendingTime | N | 当作为一个ResendRequest的返回结果重传消息时必选。如果数据不可用,则与SendingTime值相同(可以内置于坚密数据部分) | |
| 212 | XmlDataLen | N | 当标示XmlData消息体长度时必选。(可以内置于坚密数据部分) | |
| 213 | XmlData | N | 包含XML格式的消息块(如FIXML)。总紧跟在XmlDataLen后。(可以内置于坚密数据部分) | |
| 347 | MessageEncoding | N | 在消息的“Encode”域中使用的消息编码格式(非ASCII编码)。使用编码域时必选。 | |
| 369 | LastMsgSeqNumProcessed | N | FIX引擎到收到、下游应用(如交易系统、指令路由系统)处理过的的最后一个MsgSeqNum值。在每个消息发送时确定。用于参与方侦测消息积压(未被处理?)。 | |
| 627 | NoHops | N | ||
| -〉 | 628 | HopCompID | N | |
| 629 | HopSendingTime | N | ||
| -〉 | 630 | HopRefID | N | |
| Tag (标记) | FieldName (域名) | Req’d (必选) | 备注 | 
| 93 | SignatureLength | N | 如果尾部包含签名则必选。注意,不能包含在SecureData域中。 | 
| 89 | Signature | N | 注意,不能包含在SecureData域中。 | 
| 10 | CheckSum | Y | (不能加密,总是消息的最后一个域) | 
| Tag (标记) | FieldName (域名) | Req’d (必选) | 备注 | 
| StandardHeader标准头部 | Y | MsgType=0 | |
| 112 | TestReqID | N | 当Heartbeat消息是Test Request消息的响应时必选 | 
| StandartTrailer | Y | 
| Tag (标记) | FieldName (域名) | Req’d (必选) | 备注 | 
| StandardHeader标准头部 | Y | MsgType=A | |
| 98 | EncryptMethod | Y | 不能加密 | 
| 108 | HearBtInt | Y | 双方使用同一个值 | 
| 95 | RawDataLength | N | 由一些认证方法使用 | 
| 96 | RawData | N | 由一些认证方法使用 | 
| 141 | ResetSeqNumFlag | N | 表示FIX会话双方应复位序列号 | 
| 789 | NextExpectedMsgSeqNum | N | 可选,双方检测和恢复消息间隙的候选协商方法参照“Logon消息NextExpectedMsgSeqNum ” | 
| 383 | MaxMessageSize | N | 能用于指定所支持接收消息的最大字节数 | 
| 384 | NoMsgTypes | N | 指定RefMsgTypes的重复次数 | 
| -〉 | 372 RefMsgType | N | 制定一个特定的、被支持的MsgType。如果NoMsgTypes大于0时必选。从Logon消息的发送者角度应当被指定。 | 
| -〉 | 385 MsgDirection | N | 表明所支持MsgType的接收或发送方向。当NoMsgTypes大于0时必选。从Logon消息的发送者角度应当被指定。 | 
| -〉 | 1130 RefApplVerID | N | 在会话层指定一个消息的应用SP发行版本。SP发行时付值的枚举域。 | 
| -〉 | 1131 RefCstmApplVerID | N | 再会话层指定一个用户扩展消息的应用。 | 
| 464 | TestMessageIndicator | N | 用于指定此FIX会话将发送、接收 “Test” “production”消息。 ? | 
| 553 | Username | N | |
| 554 | Password | N | 注意,没有传输层加密时存在最小安全性。 | 
| 1137 | DefaultApplVerID | Y | 由FIXT承载的FIX的默认版本。 | 
| StandartTrailer | Y | 
| Tag (标记) | FieldName (域名) | Req’d (必选) | 备注 | 
| StandardHeader标准头部 | Y | MsgType=A | |
| 112 | TestReqID | Y | 不能加密 | 
| StandartTrailer | Y | 
| Tag (标记) | FieldName (域名) | Req’d (必选) | 备注 | 
| StandardHeader标准头部 | Y | MsgType=2 | |
| 7 | BeginSeqNo | Y | 不能加密 | 
| 16 | EndSeqNo | Y | |
| StandartTrailer | Y | 
| SessionRejectReason | 
| 0=Invalid tag number无效的tag编号 | 
| 1=Required tag missing  tag丢失 | 
| 2=Tag not defined for this message type 这类消息的Tag没有被定义 | 
| 3=Undefined Tag未知Tag | 
| 4=Tag specified without a value 缺少Tag值 | 
| 5=Value is incorrect (out of range) for this tag tag值错误(超界) | 
| 6=Incorrect data format for value错误值数据 | 
| 7=Decryption problem解密错误 | 
| 8=Signature problem签名错误 | 
| 9=CompID problem企业ID错 | 
| 10=SendingTime accuracy problem 发送时间不正确 | 
| 11=Invalid MsgType无效的MsgType  | 
| 12=XML Validation errorXML语法验证错误 | 
| 13=Tag appears more than onceTag重复出现 | 
| 14=Tag specificed out of required order 指定的Tag顺序错误 | 
| 15=Repeating group fields out of order 重复组域顺序错误 | 
| 16=Incorrect NumInGroup count for repeating group 重复组NumInGroup错误 | 
| 17=Non “data” value includes field delimiter(SOH character) 包含了SOH分界符的错误数据 | 
| 99=Other 其它错误 | 
| 注意:其他的会话级规则冲突可能存在,SessionRejectReason值为99(Other),并在Text域中进行详细描述。 | 
| Tag (标记) | FieldName (域名) | Req’d (必选) | 备注 | 
| StandardHeader标准头部 | Y | MsgType=3 | |
| 45 | RefSeqNum | Y | 被驳回消息的MsgSeqNum | 
| 371 | RefTagID | N | 被参照的FIX域tag值 | 
| 372 | RefMsgType | N | 被参照的FIX消息MsgType值 | 
| 373 | SessionRejectReason | N | 会话级驳回消息错误代码 | 
| 58 | Text | N | 解释驳回原因的文本信息 | 
| 354 | EncodedTextLen | N | 如果使用EncodeText域,必选,且EncodeText必须紧跟在该域之后 | 
| 355 | EncodedText | N | 使用MessageEncoding 域制定的编码规则对Text域内容的编码数据(非ASCII码) | 
| StandartTrailer | Y | 
| Tag (标记) | FieldName (域名) | Req’d (必选) | 备注 | 
| StandardHeader标准头部 | Y | MsgType=4 | |
| 123 | GapFillFlag | N | |
| 36 | NewSeqNo | Y | |
| StandartTrailer | Y | 
| Tag (标记) | FieldName (域名) | Req’d (必选) | 备注 | 
| StandardHeader标准头部 | Y | MsgType=5 | |
| 58 | Text | N | |
| 354 | EncodedTextLen | N | 如果使用EncodeText域,必选,且EncodeText必须紧跟在该域之后 | 
| 355 | EncodedText | N | 使用MessageEncoding 域制定的编码规则对Text域内容的编码数据(非ASCII码) | 
| StandartTrailer | Y | 
| Precedence 次序 | State 状体 | Initiator 发起者 | Acceptor 接收者 | Descriptioin 描述 | 
| 1 | 断开 当天未连接 | Y | Y | 当前处于断开状态,当日未进行连接尝试。没有MsgSeqNum被使用(下一个当日的连接的MsgSeqNum值为1)。 | 
| 2 | 断开 当日开始连接 | Y | Y | 当前处于断开状态,尝试建立当日连接,这样,MsgSeqNum开始被消耗(下一个当日连接时,MsgSeqNum将从其(last+1)开始) | 
| 3 | 检测到网络连接的中断 | Y | Y | 处于连接状态时,检测到一个网络连接中断(如TCP socket关闭)。断开网络连接并关闭该会话的配置。 | 
| 4 | 等待连接 | N | Y | 会话登陆消息接收者等待对端的连接。 | 
| 5 | 初始话(发起)连接 | Y | N | 会话登陆消息发起者同对端建立连接。 | 
| 6 | 网络连接建立 | Y | Y | 双方建立网络连接。 | 
| 7 | 发送Logon发起消息 | Y | N | 会话登陆发起者发送Logon 消息。 ***异常:24小时会话 | 
| 8 | 收到Logon发起消息 | N | Y | 会话登陆接收者收到对端的Logon消息 ***异常:24小时会话 | 
| 9 | Logon发起消息响应 | N | Y | 会话登陆接收者使用Logon消息与对端握手,响应对端Logon消息。 | 
| 10 | 处理ResendRequest | Y | Y | 接收和响应对端发送的对消息的ResendRequeset消息,和(或)对MsgSeqNum所请求范围的SequenceReset-Gap Fill消息。修改以驳回接收到的MsgSeqNum小于LastSeqNum的Resend Request消息。 | 
| 11 | 收到MsgSeqNum过大 | Y | Y | 从对端接收到过大的MsgSeqNum,将消息排队暂存,发送ResendRequest消息 | 
| 12 | 等待/处理ResendRequest响应 | Y | Y | 处理请求的MsgSeqNum请求的、PossDupFlag=’Y’的消息,和/或从对端进行的SequenceRset-Gap Fill消息。将MsgSeqNu过高的接收消息排队暂存。 | 
| 13 | 在实践间隔后未收到消息 | Y | Y | 没有非混乱消息在HeartBeatInt+响应时间内被接收,发送TestRequest消息。 | 
| 14 | 等待/处理TestRequest消息响应 | Y | Y | 处理接收消息。当接收到非混乱消息后,复位心跳间隔时间。 | 
| 15 | 接收Logout消息 | Y | Y | 从对端接收到发起注销/连接断开的Logout消息。如果MsgSeqNum过高,发送RsendRequest。如果发送,等待一定周期,以完成ResendRequest的响应处理。注意,依据Logout的原因,对端可能不能执行该请求。 发送Logout消息作为响应并等待一定时间让对端断开网络连接。注意,对端可能发送ResendRequest消息,如果Logout响应消息的MsgSeqNum过高并重新发起Logout操作。 | 
| 16 | 发起Logout处理 | Y | Y | 识别优雅断开连接的条件和原因(如:日终,多个未响应的TestRequest消息发送后,MsgSeqNum过高等)。发送Logout效益给对端。等待一个时间周期以接收Logout响应。在这期间,如有可能,处理新接收的消息和/或ResendRequest。注意,一些注销/终止条件(如数据库/消息存储失败),可能要求紧接在初始沪Logout消息发送后立即止网络连接。断开该会话的网络连接并关闭该会配置。 | 
| 17 | 活动/正常会话 | Y | Y | 网络连接建立后,Logon消息成果交换完成,接收和发送的MsgSeqNum都是所期望的顺序,并且Heartbeat 或其他消息在(HeartBeatInt +响应周期)内被接收。 | 
| 18 | 等待Logon确认 | Y | N | 会话发起者等待会话接收者发送Logon确认消息。 | 
| Session Initiator(e.g. buyside)Action 会话发起者(如,买方)行为 | Session Acceptor(e.g. sellside)Action会话接收者(如,卖方)行为 | Session Initiator(e.g.buyside)State会话发起者(如,买方)状态 | Session Acceptor(e.g. sellside)State会话接收者(如,卖方)状态 | 
| 开始 | 未连接-当日未连接 未连接-当日连接 | 等待连接 | |
| 连接 | 发起连接 (可能)检测到网络连接中断 | 等待连接 | |
| 接受连接 | 建立网络连接 | 建立网络连接 | |
| 发起登陆 | 发送发起登陆消息Logout | 建立网络连接 | |
| 收到发起登陆消息Logout | 发送发起登陆消息Logout | 收到发起登陆消息Logout | |
| 发送发起登陆消息响应 | 发送发起登陆消息Logout | 发起Logon的响应 (可能)发起 Logout处理 (可能)接收到的MsgSeqNum过高 | |
| (可能)发送ResendRequest | 发起Logon响应 (可能)接收到的MsgSeqNum过高 | ||
| 接收发起登陆消息的响应 | (可能)活动/正常的会话 (可能)发起 Logout处理(如,MsgSeqNum过高) | 发起Logon的响应 | |
| (可能)发送RsendRequest | (可能)活动/正常的会话 (可能)接收的MsgSeqNum过高 | (可能)活动/正常的会话 (可能)处理ResendRequest | |
| 活动/正常的会话 | 活动/正常的会话 | 
| Logout Initiator: Action Logout发起者行为ie | Logout Acceptor Action Logout接收者行为 | Logout Initiator State Logout发起者状态 | Logout Acceptor State Logout接收者状态 | 
| 开始 | 1.        活动/正常的会话 2.        没有在时间间隔内收到消息 3.        等待/处理响应TestRequest | ||
| Ref ID参考号 | Pre- Condi- tion 前置 条件 | Test  case 测试 用例 | Mandaory /Optional 强制 /可选 | Condition /Stimulus 状态 /激发 | Expected Beheavior期望行为 | 
| 1B | 连接并发送Logon消息 | Mandatory 强制 | a 建立网络连接 | 同对端成功创建TCP socket连接 | |
| b 发送Logon消息 | 发送Logon消息 | ||||
| c 收到有效Logon响应消息 | 如果MsgSeqNum过高,则发送Resend Request消息 | ||||
| d 收到无效Logon消息 | 1.         在测试输出上产生一个错误状态。 2.         (可选)发送Reject驳回消息,其RefMsgSeqNum 参照Logon消息的MsgSeqNum的值,在Text 域填写错误状态。 3.         发送Logout消息,在其Text域填写错误状态。 4.         断开连接。 | ||||
| e 收到任何非Logon消息 | 1.         记录日志:第一个消息不是Logon。 2.         同上 3.         同上 4.         同上 | 
| Ref ID参考号 | Pre- Condi- tion 前置 条件 | Test  case 测试 用例 | Mandaory /Optional 强制 /可选 | Condition /Stimulus 状态 /激发 | Expected Beheavior期望行为 | 
| 1S | 收到Logon消息 | Mandatory 强制 | a收到有效Logon响应消息 | 1.         用Logon响应消息进行响应 2.         如果MsgSeqNum过高,则发送Resend Request消息 | |
| b 收到带有重复特性的Logon消息(如,当存在连接时的同样的IP,Port,SenderCompID,TargetCompID,等) | 1.         产生,并测试输出一个错误状态。 2.         不发送任何消息,断开连接。(注意,发送Reject消息,或Logout消息将消耗MsgSeqNum) | ||||
| c 收到Logon消息,带有未认证/未配置特性(如,同系统配置比较,无效SendCompID,无效TargetCompID,无效源IP等) | 1.         产生,并测试输出一个错误状态。 2.         不发送任何消息,断开连接。(注意,发送Reject消息,或Logout消息将消耗MsgSeqNum) | ||||
| d 收到无效Logon消息 | 1.         在测试输出上产生一个错误状态。 2.         (可选)发送Reject驳回消息,其RefMsgSeqNum 参照Logon消息的MsgSeqNum的值,在Text 域填写错误状态。 3.         发送Logout消息,在其Text域填写错误状态。 4.         断开连接。 | ||||
| 收到任何非Logon消息 | Mandatory 强制 | 第一个消息不时一个Logon消息 | 1.         记录日志:第一个消息不是Logon。 2.         断开连接 | 
| Ref ID参考号 | Pre- Condi- tion 前置 条件 | Test  case 测试 用例 | Mandaory /Optional 强制 /可选 | Condition /Stimulus 状态 /激发 | Expected Beheavior期望行为 | 
| 2 | 收到消息标准头 | Mandatory 强制 | A收到期望的MsgSeqNum | 接受该消息的MsgSeqNum | |
| b 收到比期望值大的MsgSeqNum | 用Resend Request消息作为响应 | ||||
| c 收到比期望值小的MsgSeqNum且PossDupFlag不为‘Y’ 列外:SeqReset-Reset | 1.         推荐FIX引擎尝试发送一个Logout,并带有Text的值为“MsgSeqNum too low,expecting X but receiced Y” 2.         (可选)等待Logout消息的响应(注意:可能会出现的错误的MsgSeqNum)或者等待2秒无论什么先到达 3.         断开连接 4.         产生、输出错误报告 | ||||
| d 收到混乱消息 | 1.         当做混乱消息并忽略消息(不增加输入MsgSeqNum),继续接收消息。 2.         产生并输出“警告”测试信息。 3.         发送Logout消息,在其Text域填写错误状态。 4.         断开连接。 | ||||
| e PossDupFlag值为‘Y’;OrigSendingTime值小于或等于SendingTime且MsgSeqNum比期望值小。 注意:OrigSendingTime应遭遇SendingTime除非该消息在同一秒内重传。 | 1.         检查是否该MsgSeqNum值消息已经被接收。 2.         如果已经收到,忽略该消息,否则接收并处理该消息。 | ||||
| f PossDupFlag值为‘Y’,OrigSendingTime比SendingTime大,且MsgSeqNum等于期望值 注意:OrigSendingTime应遭遇SendingTime除非该消息在同一秒内重传。 | 1.         发送Reject驳回消息,参照不准确的发送时间(>=FIX4.2:SessionRejectReason = “SendingTime 准确性问题”) 2.         增加接收MsgSeqNum值 3.         可选: a)         发送Logtout消息,参照不准确的SendingTime值 b)        (可选)等待Logout响应(注意有可能有不准确的SendingTime)或者等待2秒无论什么消息先到达。 c)        断开连接。 产生、输出一个“错误”测试信息。 | ||||
| g PossDupFlag值为‘Y’,OrigSendingTime没有指定 注意:在响应Resen Request消息时,始终将OrigSendingTime设置为消息最开始发送的时间,不是当前SendingTime时间,并且PossDuFlag=‘Y’ | 1.         发送Reject驳回消息,参照不准确的发送时间(>=FIX4.2:SessionRejectReason = “tag丢失”) 2.         增加接收MsgSeqNum值 | ||||
| h 收到在测试Profile中指定的期望的BeginString值,并且匹配发送消息的BeginString值 | 接受该消息的BeginString | ||||
| i收到不是在测试Profile中指定的期望的BeginString值,并且匹配发送消息的BeginString值 | 1.         发送Logout消息参照错误的BeginString值。 2.         (可选)等待Logout响应消息(注意可能有错误的BeginString)或者等待2秒无论什么先到达 3.         断开连接。 4.         产生、输出“错误“测试信息。 | ||||
| j收到在测试Profile中指定的期望的SenderCompID和TargetCompID值 | 接受该消息的SenderCompID和TargetCompID | ||||
| k收到不是在测试Profile中指定的期望的SenderCompID和TargetCompID值 | 1.         发送Reject驳回消息,参照无效的SenderCompID和TargetCompID。(>=FIX4.2:SessionRejectReason = “CompID错误”) 2.         增加接收MsgSeqNum值。 3.         参照错误的SenderCompID或TargetCompID值发送Logout消息。 4.         (可选)等待Logout响应消息(注意可能有错误的SenderCompID或TargetCompID值)或者等待2秒无论什么先到达 5.         断开连接 6.         产生、输出“错误”测试信息。 | ||||
| l 收到正确的BodyLength值 | 接受该消息的BodyLength | ||||
| m收到正确的BodyLength值 | 1.         当做混乱消息并忽略(不增加接收MsgSeqNum值),继续接收消息。 2.         产生、输出“警告”测试信息。 | ||||
| N SendingTime值使用UTC格式并在一个基于原子时间的合理范围内(如,2秒) | 接受该消息的SendingTime | ||||
| O收到的SendingTime值即不使用UTC格式也不是在一个基于原子时间的合理范围内(如,2秒) | 1.         发送Reject驳回消息,参照无效的SendingTim。(>=FIX4.2:SessionRejectReason = “SendingTime精确性问题”) 2.         增加接收MsgSeqNum值 3.         参照不精确的SendingTime发送Logout消息。 4.         (可选)等待Logout响应消息(注意可能有不精确的SendingTime)或者等待2秒无论什么先到达 5.         断开连接 6.         产生、输出“错误”测试消息。 | ||||
| P 收到有效MsgType值(在规范中定义或用户自定义文档中定义) | 接受该消息的MsgType | ||||
| 收到无效MsgType值(没有在规范中定义或用户自定义文档中定义) | 1.         发送Reject驳回消息,参照无效的MsgType。(>=FIX4.2:SessionRejectReason = “无效的MsgType”) 2.         增加接收MsgSeqNum值 3.         产生、输出“警告”测试消息 | ||||
| R收到有效MsgType值(在规范中定义或用户自定义文档中定义)但不被测试Profile支持,或没再其中注册。 | 1.         if < FIX 4.2 参照有效的但不被支持的MsgType发送Reject驳回消息。 2.         if >=FIX4.2 a)         发送Business Message Reject驳回消息,参照有效但不被支持的MsgType。(>=FIX4.2:BusinessRejectReason = “不支持的MsgType” 3.         增加接收MsgSeqNum值 4.         产生、输出“警告”测试消息 | ||||
| S 收到的BeginStirng,BodyLength,和MsgType是消息的前三个域 | 接受该消息 | ||||
| t 收到的BeginStirng,BodyLength,和MsgType是消息的前三个域 | 1.         当做混乱消息并忽略(不增加接收MsgSeqNum值),继续接收消息。 2.         产生、输出“警告”测试消息 | ||||
| 3 | 接收标准消息尾 | 强制 | a 有效CheckSum | 1.         接受消息 | |
| B 无效CheckSum | 1.         当做混乱消息并忽略(不增加接收MsgSeqNum值),继续接收消息。 2.         产生、输出“警告”测试消息 | ||||
| C 混乱消息 | 1.         当做混乱消息并忽略(不增加接收MsgSeqNum值),继续接收消息。 2.         产生、输出“警告”测试消息 | ||||
| D CheckSum为消息的最后一个域,长度为3,并由分界符<SOH>分隔 | 接受该消息 | ||||
| E CheckSum不是消息的最后一个域,长度不为3,或不是由分界符<SOH>分隔 | 1.         当做混乱消息并忽略(不增加接收MsgSeqNum值),继续接收消息。 2.         产生、输出“警告”测试消息 | ||||
| 4 | 发送Heartbeat消息 | 强制 | A 当前心跳时间间隔内无数据发送(HeartBearInt域) | 发送Heartbeat消息 | |
| B接收到一个Test Request消息 | 发送Heartbeat消息,附带Test Request消息的TestReqID | ||||
| 5 | 接收Heartbeat消息 | 强制 | 有效的Heartbeat消息 | 接受Heartbeat消息。 | |
| 6 | 发送Test Request | 强制 | 当前心跳时间间隔+某个时间周期(20%的HeartBeatInt值)内无数据接收 | 1.         发送Test Request消息 2.         跟踪确认一个使用TestReqID的Heartbeat被接收(可以不是下一个消息)。 | |
| 7 | 接收Reject驳回消息 | 强制 | 有效的Reject消息 | 1.         增加接收MsgSeqNum值 2.         继续接收消息 | |
| 8 | 接收Resend Request消息 | 强制 | 有效的Resend Request消息 | 使用应用层消息,和按照“消息恢复”规则在请求范围内使用SequenceReset-Gap Fill消息进行响应 | |
| 9 | 同步序列号 | 可选 | 应用程序故障 | 发送Sequence Reset-Reset消息或手动复位 | |
| 10 | 接收Sequence Reset(Gap Fill) | 强制 | A 收到Sequence Reset(Gap Fill)消息,NewSeqNo > MsgSeqNum 且 MsgSeqNum > 期望序列号 | 发送Resend Request,在最后一个期望MsgSeqNum到接收到的MsgSeqNum范围内填冲消息间隙。 | |
| B收到Sequence Reset(Gap Fill)消息,NewSeqNo > MsgSeqNum 且 MsgSeqNum = 期望序列号 | 设置下一个期望序列号为NewSeqNo | ||||
| C收到Sequence Reset(Gap Fill)消息,NewSeqNo > MsgSeqNum 且 MsgSeqNum < 期望序列号且 PossDupFlag = “Y” | 忽略消息 | ||||
| D收到Sequence Reset(Gap Fill)消息,NewSeqNo > MsgSeqNum 且 MsgSeqNum < 期望序列号且 没有PossDupFlag = “Y” | 1.         如果可能,在断开FIX会话前,发送带有Text域为“MsgSeqNum too low, expecting X received Y,”的Logout消息 2.         (可选)等待Logout响应(注意可能有不精确的MsgSeqNum)或者等待2秒无论什么先到达) 3.         断开连接 4.         产生、输出“错误”测试信息。 | ||||
| E收到Sequence Reset(Gap Fill)消息,NewSeqNo <= MsgSeqNum 且 MsgSeqNum = 期望序列号 | 发送Reject(会话层)驳回消息,携带信息“attempt to lower sequnce number, invalid value NewSeqNum=<x>” | ||||
| 11 | 接收Sequence Reset(Reset) | 强制 | A 收到Sequence Reset(Gap Fill)消息,NewSeqNo> 期望序列号 | 1.         接受该Sequence Reset消息,忽略其MsgSeqNum 2.         将期期望序列号设置为NewSeqNo | |
| B收到Sequence Reset(Gap Fill)消息,NewSeqNo= 期望序列号 | 1.         接受该Sequence Reset消息,忽略其MsgSeqNum 2.         产生、输出“警告”测试信息。 | ||||
| C收到Sequence Reset(Gap Fill)消息,NewSeqNo< 期望序列号 | 1.         接受该Sequence Reset消息,忽略其MsgSeqNum 2.         发送Reject会话层驳回消息,参照无效的MsgType。(>=FIX4.2:SessionRejectReason = “此tag值错误(超界)”) 3.         不增加接收MsgSeqNum值 4.         产生、输出“错误”测试消息。 5.         不能减小序列号。 | ||||
| 12 | 发起注销过程 | 强制 | 发起Logout | 1.         发送Logout消息 2.         10秒内等待Logtout响应(注意,可能由于出现的通信问题不能收到)。如果没有收到,产生输出“警告”测试消息 3.         断开连接。 | |
| 13 | 接收Logtout消息 | 强制 | A 收到有效的Logout消息作为请求注销处理过程的响应 | 断开连接,不发送消息。 | |
| B 接收到有效的非请求的Logout消息 | 1.         发送Logout响应消息。 2.         10秒内等待对端断开连接。如果超过等待时间,断开连接,产生输出“错误”测试消息 | ||||
| 14 | 接收应用消息或管理消息 | 强制 | A收到的域识别符(tag值)未在规范文档中定义 例外:未在规范文档中定义,但在测试Profile中作为用户定义的tag | 1.         发送Reject会话层驳回消息,参照无效的tag。(>=FIX4.2:SessionRejectReason = “无效的tag”) 2.         增加接收MsgSeqNum。 3.         产生、输出“错误”测试消息 | |
| B 接收消息中必选Tag丢失 | 1.         发送Reject会话层驳回消息,参照丢失的必选tag。(>=FIX4.2:SessionRejectReason = “必选tag丢失”) 2.         增加接收MsgSeqNum。 3.         产生、输出“错误”测试消息 | ||||
| C 接收消息tag在规范文档中定义,但不是为该消息类型定义的 | 1.         发送Reject会话层驳回消息,参照丢不是为该消息类型定义的tag。(>=FIX4.2:SessionRejectReason = “该消息未定义此Tag”) 2.         增加接收MsgSeqNum。 3.         产生、输出“错误”测试消息 | ||||
| D 接收消息tag在规范文档中定义,但为空值(如55=<SOH>) | 1.         发送Reject会话层驳回消息,参照已定义但值为空的tag。(>=FIX4.2:SessionRejectReason = “指定的Tag值为空”) 2.         增加接收MsgSeqNum。 3.         产生、输出“错误”测试消息 | ||||
| E 接受消息特定tag值取值、取值范围错误,或不是有效的枚举值。 例外:在测试Profile中作为用户自定义的未在规范文档中定义的枚举值 | 1.         发送Reject会话层驳回消息,参照取值错误的tag。(>=FIX4.2:SessionRejectReason = “Tag值错误(超界)”) 2.         增加接收MsgSeqNum。 3.         产生、输出“错误”测试消息 | ||||
| F接受消息特定tag值格式(语法)错误 | 1.         发送Reject会话层驳回消息,参照取值格式错误的tag。(>=FIX4.2:SessionRejectReason = “值格式错误”) 2.         增加接收MsgSeqNum。 3.         产生、输出“错误”测试消息 | ||||
| G 消息结构不是和ader+body+trailer | 1.         发送Reject会话层驳回消息,参照不正确地消息结构。(>=FIX4.2:SessionRejectReason = “指定的Tag顺序错误”) 2.         增加接收MsgSeqNum。 3.         产生、输出“错误”测试消息 | ||||
| H 消息中一个tag不是重复组的组成部分,但被多次指定 | 1.         发送Reject会话层驳回消息,参照重复的tag。(>=FIX4.2:SessionRejectReason = “Tag重复出现”) 2.         增加接收MsgSeqNum。 3.         产生、输出“错误”测试消息 | ||||
| I 消息中重复组count域值错误 | 1.         发送Reject会话层驳回消息,参照错误的count域。(>=FIX4.2:SessionRejectReason = “重复组无效的NumInGroup计数”) 2.         增加接收MsgSeqNum。 3.         产生、输出“错误”测试消息 | ||||
| J 重复组域顺序未匹配规范 | 1.         发送Reject会话层驳回消息,参照重复组错误的域顺序。(>=FIX4.2:SessionRejectReason = “重复组域顺序错误”) 2.         增加接收MsgSeqNum。 3.         产生、输出“错误”测试消息 | ||||
| K 域的tag标识中含有多个<SOH>(非域数据) | 1.         发送Reject会话层驳回消息,参照域的含有多个<SOH>的tag标识。(>=FIX4.2:SessionRejectReason = “非域数据包含分界符号(SOH 字符)”) 2.         增加接收MsgSeqNum。 3.         产生、输出“错误”测试消息 | ||||
| L 当应用曾处理或系统无效收到消息 | 1.         if <FIX 4.2 a)         发送Reject会话层驳回消息,参考应用处理无效。 2.         if >=FIX 4.2 a)         发送Business Message Reject消息,参考域参考应用处理无效。(>=FIX4.2:BusinessRejectReason = “应用程序无效”) 4.         增加接收MsgSeqNum。 5.         产生、输出“警告”测试消息 | ||||
| M 消息中常规必选域丢失 | 1.         if <FIX 4.2 b)        发送Reject会话层驳回消息,参考丢失的常规必选域。 2.         if >=FIX 4.2 a)         发送Business Message Reject消息,参考丢失的常规必选域。(>=FIX4.2:BusinessRejectReason = “常规必选域丢失”) 3.         增加接收MsgSeqNum。 4.         产生、输出“错误”测试消息 | ||||
| N 在明文中出现的Tag数与密文中出现的相同,但Tag值不同 | 1.         发送Reject会话层驳回消息,参照明文和密文中具有相tag数,但值不同的域。(>=FIX4.2:SessionRejectReason = “解密问题/错误”) 2.         增加接收MsgSeqNum。 3.         产生、输出“错误”测试消息 | ||||
| 15 | 发送应用或管理消息以测试正常和异常的行为/响应 | 发送多个消息同类消息,其头部和数据体域顺序不同,以验证消息接受(排除有顺序限制的) | 消息被接受并且其后续消息的MsgSeqNum被接受。 | ||
| 16 | 排队待发送消息 | 强制 | A 当处于连接断开时待发消息排队 | 排队待发送消息。注意,有2种方法: 1.         排队消息,不考虑MsgSeqNum a)         存储消息数据。 2.         使用下一个MsgSeqNum值,排队每一个消息 a)         采用消耗下一个MsgSeqNum值的方式,存储消息数据。 注意:SendingTime(Tag#52):必须包是消息发送的时间,而不是消息进入排队的时间。 | |
| B 带有排队消息的重连。 | 1.         完成登陆过程(连接,交换Logon消息) 2.         如可能,完成MsgSeqNum恢复过程。 3.         推荐短暂延迟或使用TestRequest/Heartbeat确认MsgSeqNum恢复完成。 4.         注意,这里有2种有效的排队方法: a)         排队消息,不考虑MsgSeqNum                          i.              使用新MsgSeqNum发送排队消息(大于Logon消息的MsgSeqNum)。 b)        使用下一个MsgSeqNum值,排队每一个消息                          i.              (注意,)Logon消息的MsgSeqNum大于排队消息的MsgSeqNum。                        ii.              对端将发起ResendRequest请求这个范围内丢失的消息                       iii.              重发每个排队消息,将PossDupFlag设置为‘Y’ 注意:SendingTime(Tag#52):必须包是消息发送的时间,而不是消息进入排队的时间。 | ||||
| 17 | 加密支持 | 可选 | A 接收Logon消息,带有有效的北支持的EncryptMethod | 1.         接受该消息 2.         执行适当的解密或加密方法。 3.         使用同一个EncryptMethod方法响应Logon消息。 | |
| B 收到Logon消息,带有无效的或不支持的EncryptMethod | 1.         发送Reject会话层驳回消息,参照无效的或不支持EncryptMethod。(>=FIX4.2:SessionRejectReason = “解密问题”) 2.         增加接收MsgSeqNum值。 3.         发送Logout消息,参照无效的或不支持EncryptMethod 4.         (可选)等待Logout响应(注意可能有解密问题)或者等待2秒无论什么先到达) 5.         断开连接 6.         产生、输出“错误”测试消息。 | ||||
| C 收到消息,带有SignatureLength和Signature值 | 接受该消息 | ||||
| D 收到消息,带有无效的SigntureLength值 | 1.         发送Reject会话层驳回消息,参照无效的SignatureLength值。(>=FIX4.2:SessionRejectReason = “签名问题”) 2.         增加接收MsgSeqNum值。 3.         产生、输出“错误”测试消息。 | ||||
| E收到消息,带有无效的Signture值 | 1.         发送Reject会话层驳回消息,参照无效的Signature值。(>=FIX4.2:SessionRejectReason = “签名问题”) 2.         增加接收MsgSeqNum值。 3.         产生、输出“错误”测试消息。 或者,考虑解密错误或顺序错误的消息,忽略消息(不增加接收MsgSeqNum值)并继续接收消息。 | ||||
| F 收到消息,有有效的SecureDataLen和SecureData值,且能被解密为有效的,能接戏的明文 | 接收消息。 | ||||
| G 接收消息SecureDataLen值无效 | 1.         当做解密错误或消息顺序错,忽略消息(不增加接收MsgSeqNum值)并继续接收消息。 2.         产生、输出“警告”测试消息。 | ||||
| H 接收消息带有不能被解密为有效、能被解析的明文 | 1.         发送Reject会话层驳回消息,参照无效的SecureData值。(>=FIX4.2:SessionRejectReason = “解密问题”) 2.         增加接收MsgSeqNum值。 3.         产生、输出“错误”测试消息。 | ||||
| I 接收消息中一个或多个域本应按规范不能被加密的,未出现在非加密部分 | 1.         发送Reject会话层驳回消息,参照不能加密的丢失域的Tag值。(>=FIX4.2:SessionRejectReason = “解密问题”) 2.         增加接收MsgSeqNum值。 3.         产生、输出“错误”测试消息。 | ||||
| J 接收消息有按照指定的Encryp他Method有错误的“left over”字符处理(如,当密文前的明文长度部位8的倍数时) | 1.         发送Reject会话层驳回消息,参照错误的“left over”字符处理。(>=FIX4.2:SessionRejectReason = “解密问题”) 2.         增加接收MsgSeqNum值。 3.         产生、输出“错误”测试消息 | ||||
| 18 | 支持第三方寻址 | 可选 | A 接收消带有OnBehalfOfCompI和DeliverToCompID值,同测试Profile中指正确用法相符 | 接收消息 | |
| B接收消带有OnBehalfOfCompI和DeliverToCompID值,同测试Profile中指正确用法不相符 | 1.         发送Reject会话层驳回消息,参照无效的OnBehalfOfCompI和DeliverToCompID。(>=FIX4.2:SessionRejectReason = “CompID问题”) 2.         增加接收MsgSeqNum值。 3.         产生、输出“错误”测试消息 | ||||
| 19 | 测试PossResend处理 | 强制 | A 接收消息带有PossResend=‘Y’且应用层消息ID检查显示其已经在本次会话中出现过 | 1.         忽略该消息 2.         产生、输出“警告”测试消息。 | |
| B接收消息带有PossResend=‘Y’且应用层消息ID检查显示其已经在本次会话中没有出现过 | 接受并正常处理该消息。 | ||||
| 20 | 同时Resend 请求测试 | 强制 | 当已经发送和等待一个Resend Request消息的所有响应后,接收到一个Resend Request消息 | 1.         执行请求被请求消息的重传。 2.         发送Resend Request消息请求丢失消息重发。 | |