随着网络的使用,目前所有大型的金融机构都已经实现了自动化和数字化。当中肯定少不了互联网的加入,那么在这当中,我们主要介绍一下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及其在中国的适用性,吸收其它市场的经验,将国内外不同的交易程序加以比较,分析协议的使用方法以及协议使用环境,结合国内证券市场的实际,使得该项协议既能成为一项标准又能为中国证券市场服务,为中国证券交易的标准化过程中发挥作用。
1 简介
FIX会话协议与选择用于电子数据传递的物理介质(铜缆,光纤,卫星传输等)及传输协议规范(X.25,同步,TCP/IP等)无关。它提供了一个消息传递的可靠数据流。直到2006年10月,FIX会话协议与FIX应用协议一道,为用户提供了一个可靠的传输FIX应用消息的传输机制。
FIX会话层与数据传输相关,而FIX应用层则定义了商业相关的数据内容。
2006年10月,FPL’s Global Techenical Committee 引入了一个新的框架,将FIX会话层协议从FIX应用层协议分离开来。这就使应用协议消息可以使用任何适的会话传输技术进行传送,而FIX会话层协议是这些可选的协议中的一个。在新的框架下,GTC引入了一个新的别名,之后FIX会话层协议版本为FIXT.x.y,第一个版本为FIXT1.1。
2 FIXML及其它基于XML数据的传输
尽管FIX会话协议的标准头(Standard Header),标准尾部(Standard Trailer)和管理消息是基于“tag=value”语法的,但它能够支持传输FIXML及其它基于XML的数据。FIXML及其它XML数据被夹在FIX标准头与FIX标准尾部中间,并通过标准头的XmlDataLen域指定其内容长度,XmlData域包含其具体的数据。这样,FIX引擎可以通过多年使用的,可靠的,实时地异步传输机制传送FIXML及其它XML数据。当MsgType域值为’n’时,代表传输的数据为FIX未在MsgType中定义的XML数据。
3 FIX消息传送
3.1 Sequence Numbers 序列编号
所有的FIX消息都由一个唯一的序列号进行标示。序列号在每一个FIX会话开始时被初始化为1,并在整个会话期间递增。监控序列号可以使会话参与者识别和处理丢失的消息,当在一个FIX会话中重新连接时能够优雅地进行应用程序同步。
每个会话将建立一组互不依赖的接受和发送序列。会话参与者将维护一个赋予发送消息的序列和一个监控接受消息的消息块间隙序列号。
3.2 Heartbeats 心跳信号
在消息交互期间,FIX应用程序将周期性产生Heartbeat心跳消息。该心跳消息可以监控通信链路状态及识别接受序列号间隙。发送Heartbeat的周期间隔由会话发起者使用在Logon消息中HeartBtInt域进行定义。Heartbeat心跳消息的时间间隔应当在每一个消息发送后复位,即发送一个消息后,在间隔给定的时间内无其它消息发送则发送一个Heartbeat心跳消息。HeartBtInt的值应当被会话双方认同,由会话发起方定义并由会话接收者通过Logon消息进行确认。同一个HeartBtInt被会话双方——登录的发起者和登录的接受者共同使用。
3.3 Ordered Message Processing 消息序列处理
FIX协议假设消息在所有参与者间完全按照顺序进行传输。协议的实现者在设计消息间隙填充处理时应当考虑这个假设。有两种方式处理消息间隙。每一个都要求所有的消息时最后一个接收消息的后续消息或在维护一个所有新消息有序序列时,请求特定丢失消息。比如:接收方丢失了5个消息块中的第二个,程序能忽略第3到第5个消息,产生一个对消息2到消息5的重传请求,或者从消息2到无穷大消息编号的重传请求。另外的方式是暂时存储消息3到消息5,仅要求重传消息2。对于这两种方式,消息3到消息5都不应该先于消息2进行处理。
3.4 Possible Duplicates 可能的复制
当一个FIX引擎对一个消息是否成功地被指定的目标接收或者当对一个重传请求进行响应时,将会产生一个可能的消息复制。这个消息将用同样的序列进行重新传送,此时在头部的PossDupFlag域将会被设置为‘Y’。接收端程序负责处理该重发消息,可以作为一个新消息进行处理,或者根据实际情况忽略该消息。所有重传请求的响应消息都将包含其值为‘Y’的PossDupFlag域。没有PossDupFlag域或者PossDupFlag域为‘N’的消息应被当作初始传送消息。注意,一个PossDupFlag值为‘Y’的重传消息需要重新计算其CheckSum值。一个可能的复制消息里发生变化的域包括:CheckSum,OrigSendingTime,SendingTime,BodyLength和PossDupFlag。加密相关域(SecureDataLen和SecureData)也必须被重新构造。
3.5 Possible Resends 可能的重传
模糊的应用层消息可能随同PossResend标志被重传。当一个指令没有在规定时间长度内进行确认或者终端用户挂起该指令没有进行传送时这种方法非常有用。接收程序必须识别此标志,并质疑其内部域以确定该指令是否在之前已经被接收过。注意,可能的重传消息将包含与原始消息相同的数据体,但包含PossResend标志和一个新的序列号。此外,CheckSum和与加密相关的域值需要重构。
3.6 Data Integrity 数据完整性
消息数据内容的完整性可以参用两种方式来验证:消息长度和效验码检查。
程序通过计算BodyLength域到(并包含)在CheckSum标记(“10=”)后的分界符的字符数与在BodyLength中标示的消息长度进行比较来完成完整性效验。
ChekSum完整性检查,通过计算从域“8=” 中“8”开始,包括紧跟在CheckSum标记域的分界符<SOH>每个字符的2进制和同CheckSum进行比较得到。
3.7 Message Acknowledgment 消息确认
FIX会话协议基于一个优化模型。普通的数据传送(无单个消息确认)被假设为通过消息序列间隙进行错误识别。每个消息由一个唯一的序列号进行标示。接收端应用程序负责监控接收消息序列号以识别消息间隙并产生重传请求。
FIX协议不支持单个消息的确认。然而,多数应用消息需要显示地应用层接收和拒绝。
3.8 Encryption 加密
敏感数据在公众网络上的传输建议采用数据加密技术来掩饰应用消息。
加密算法由连接双方共同协商。
一个消息的任何一个域可以被加密并放在SecureData域中。然而,一些显示的标志域必须采用明文进行传输。为确保完整性,明文域可以在SecureData域中重复。
当使用加密时,建议但不是必须,所有的消息体都进行加密。如果一个消息中的重复组数据中的部分数据要加密,这个重复组必须全部进行加密。
预先协商好的加密算法在Logon消息中进行声明。
4 SESSION PROTOCOL会话协议
一个FIX会话定义为一个在连接双方间的的带有连续序列号的有序消息双向传输流。 单个FIX会话能够跨越多个连续(不是并行的)的物理连接。在一个维持的,单独的FIX会话中,参与方能够多次连接和断开连接。连接的参与方必须根据单个系统及时间区域需求,公共协商会话的开始和结束。无论什么原因,重新设置接收和发送序列号为1,意味着一个新的FIX会话的开始。
建议一个新的FIX会话在每24小时期间建立一次。可以维持24小时的连接和通过设置在Logon消息中的ResetSeqNumFlag建立一套新的序列号。
FIX会话协议基于一个优化模型。普通的数据传送(无单个消息确认)被假设为通过消息序列间隙进行错误识别。这个部分详细介绍了FIX会话层和消息序列间隙的实现。
以下术语将在这部分使用:
Valid FIX Message 有效FIX消息 是按照协议正确生成,包含有效消息体长度和效验域的消息。
Initiator 发起者 建立通信连路,通过发送初始Logon消息发起会话的参与方。
Acceptor 接收方 FIX会话的接收方。负责执行第一层次的认证和通过传输Logon消息的确认正式声明连接请求被接受。
FIX Connection FIX连接 由3部分组成:logon登录,message exchange消息传输,和logout注销。
FIX Session FIX 会话 由一个或多个FIX Connection FIX连接组成。意思是一个FIX会话可以有多次登录。4.1
4.1 Logon 登录
建立一个FIX连接,分别包含3个操作:创建通信层链路,接收者认证/接受发起者和消息同步(初始化)。连接流程如下:
l 会话发起者同会话接收者建立通信链路。
l 发起者发送一个Logon消息。接收者检查Logon消息,认证发起者身份。Logon消息包含支持之前双方协商好的认证方法所必须的数据。如果发起者被成功认证,接收者用一个Logon消息进行响应。如果认证失败,会话接收者将关闭链接,之前可以选择发送一个Logout消息以提示认证失败的原因。这个Logout消息不时必须发送的,如果这样做将会占用该会话的一个序列号,在某些情况下会有问题,如:在会话期进行多次Logon时。发起者可以在Logon消息后紧接着开始发送消息。然而,接收者可能没有准备好接收它们。发起者必须等待接收者发送的Logon确认消息才能认为完全建立回话。
在发起者认证通过之后,接收者立即响应一个Logon确认消息。依据会话使用的加密方法,这个Logon消息可以,也可以不报还同样的会话密钥。发起者方将把接收方反悔的Logon确认消息视为一个FIX会话建立的标志。如果会话接收方选择干边会话加密密钥,会话的发起方必须发送一个Logon消息到对方以确认密钥改变请求。这样,能让会话接收者知道发起者何时开始使用新的会话密钥。双方有责任诊断和避免在此阶段出现无限循环。
l 认证完成之后,发起方和接收方必须在发送任何查询或新消息之前通过询问MsgSeqNum域来同步其消息。将Logon消息中的MsgSeqNum同内部监控的下一个希望的序列号进行比较可以指示任何的消息间隙。此外,发起方能通过比较确认Logon消息的MsgSeqNum及下一个期望值来侦测消息的间隙。后面的消息恢复部分文当将介绍如何进行消息间隙的处理。
l 推荐引擎应当在一个临时的队列中存储发送消息系列,在消息间隙关闭时处理它们。这样可以阻止对n->m,n->m 1,n->m 2,…的重发请求,这些请求能导致许多PossDupFlag=’Y’的消息。
l 当使用ResetSeqNumFlag来维持24小时连接和建立一套新的序列号时,应该按照下面的方式进行处理。双方应当协商一个复位时间以及此过程的发起方。注意,ResetSeqNum过程的发起方可以与Logon过程的发起方不是同一个。一方通过发送一个TestRequest初始化此过程,并等待一个Heartbeat的响应以确认没有序列号间隙。一旦收到Hearbeat,发起者应当发送一个带有ResetSeqNumFlag值为‘Y’和MsgSeqNum为1的Logon消息。接收方应当发送一个带有ResetSeqNumFlag值为‘Y’和MsgSeqNum为1的Logon消息作为响应。此时,任何一方发送的新的消息可以从MsgSeqNum编号为2开始计数。应当注意,一旦发起方发送设置了ResetSeqNumFlag的Logon消息,接收者必须遵守这个请求,并且作为最后一个序列号发送的消息的“yesterday”值不再可用。如果此过程的初始化未被正确执行,链接应当被关闭,手动关闭方式将会被介入。
4.2 Message exchange 消息交换
初始化过程之后,正常德的消息交换将开始。所有有效的消息格式的细节将在“Adminitrative Message ”管理消息和“Application Messages”应用消息部分介绍。
4.3 Logout
正常的消息交换的终止将通过交换Logout消息来完成。换句话说,通信的终止应被看作异常并作为一个错误进行处理。没有接收到Logout消息的会话终止应当作参与方的注销。
推荐发送一个TestRequest消息强制请求从对方获取Heartbeat。这样可以帮助判断没有序列间隙。
在实际的会话关闭前,Logout的发起者应等待对方响应一个Logout确认消息。这种方式给接收者在需要时一个执行任何间隙填充错作的机会。一旦ResendRequest消息被接收,接收者应发起Logout操作。会话可以终止,如果接收者在适当的时间表内没有响应。
注意:注销不会影响任何指令的状态。左右活动的指令将继续有机会在注销后被执行。
4.4 Message Recovery 消息恢复
在FIX会话初始化过程及会话过程中,通过跟踪接收序列号,消息间隙的出现将会被侦测到。以下部分介绍了如何恢复消息。
如前所述,每个FIX参与方必须为FIX会话维护两个序列号,一个是接收序列号,一个是发送序列号,两者都在建立FIX会话开始时初始化为1。每个消息被赋予一个唯一的序列号值,并在消息发送后递增。此外,每个收到的消息都有一个唯一的序列号,接收序列号计数器在收到每个消息后将会被递增。
当接收序列号与所希望得到的的正确序列号不必配时,必须采取纠错处理。注意,SeqReset-Reset消息(对比正常德重传请求处理,仅用于从严重灾难中进行恢复)对于这个规则来说是个例外,它应当被处理,而不用考虑其MsgSeqNum值。如果接收消息的序列号小于期望接收的序列号,并且PossDupFlag值未被设置,这表示出现一个严重错误。强烈推荐终止会话,启用手动干预。如果接收消息的序列号大于期望值,这表明有丢失消息,并通过Resend Request 重传请求这些消息的重新传输。
注意:后续的请求者(requester)指为请求发送方;重传者(resender)指请求的响应方。消息重传和消息同步叫做“间隙填充”(gap filling)。
再收到重传请求的情况下,重传者可以用三种方式之一进行响应:
1、按照原先序列号,顺序重新传输请求消息,并将PossDupFlag设置成‘Y’(除管理消息不被重传,并需要一个SeqReset-GapFill外)。
2、发出一个SeqReset-GapFill和一个PossDupFlag值为‘Y’的消息代替管理和应用消息的重传。
3、发出一个SeqReset-GapFill和一个PossDupFlag值为‘Y’的消息强制进行序列号的同步。
通常情况下使用1,2的组合。而3则仅用于从灾难中,且不能通过间隙填充模式进行数据恢复的场景。
在间隙填充过程中,一些管理消息应不被重传。取而代之的是一个特殊的SeqReset-GapFill消息将被产生。不能被重传的消息有:Logon,Logout,ResendRequest,Heartbeat,TestRequest和SeqReset-Reset,SeqRest-GapFill。
所有的FIX协议的实现,都必须监控接收消息以侦测管理消息的重传(PossDupFlag值标示冲传)。当接收到这些消息时,应当仅对序列号完整性进行处理,而商业/应用消息应被跳过(如,不处理基于ResendRequest请求的重传间隙填充)。
如果有连续的管理消息需要重发,推荐只发送一个SeqRest-GagFill消息。SeqRest-GapFill消息的序列号为下一个希望发送的序列号。GapFill消息的NewSeqNo域包含了这些管理消息中的最高序列号值加上1。如,在一个重传错作中,有7个顺序的管理消息等待重发。它们的序列号从9到15。替代7个间隙填充消息,一个SeqReset-GapFill消息将会被发送。此间隙填充消息的序列号被设置为9,因为远端把序列号9作为下一个期望接收的消息。GapFill消息的NewSeqNo的值为16,表示下一个发送消息的序列号。
序列号检查是FIX会话管理最重要的部分。然而,一些FIX消息的序列号处理存在一些不同,下表列出了接收序列号比期望接收序列号大时的处理方法。
注意:除了Reset消息外的所有情况,如果接收序列号小于期望接收序列号,且PossDupFlag未被设置,FIX会话应被终止。在关闭会话前,一个Logout消息和一些描述性文本应被发送给对端。
4.5 Logon消息的NextExpectedMsgSeqNum处理
NextExpectedMsgSeqNum (789)域从FIX4.4开始加入到Logon消息中,用以支持一个FIX会话的重同步。这个新方法是可选的。其适用必须得到参与方的共同同意。
NextExpectedMsgSeqNum (789)的使用如下:
在Logout的请求阶段,会话发起者把期望从会话接收者的下一个MsgSeqNum(34)的值赋于NextExpectedMsgSeqNum (789)。通常,Logon请求发送头部MsgSeqNum(34)的值表示下一个序列号值。
会话接收者校验Logout请求,包括NextExpectedMsgSeqNum (789),确认没有间隙存在。然后,构建一个Logout响应,其NextExpectedMsgSeqNum (789)值包含了期望从会话发起者接收到的MsgSeqNum(34)值。如果那是一个期望的序列号,MsgSeqNum(34)会被递加。发送头部MsgSeqNum(34)按照常规进行构造。
会话发起者等待发送应用消息直到接收到Logon响应。当接收到Logon响应,发起者要校验该响应和NextExpectedMsgSeqNum (789)以确认没有消息间隙。
会话双方采用以下方式对收到的NextExpectedMsgSeqNum (789)进行处理:
1、如果等于下一个期望序列号值,则从该编号开始发送新消息。
2、如果小于下一个期望序列号值,从之前最后传送的消息到NextExpectedMsgSeqNum (789)按顺序恢复所有丢失消息,然后间隙填充将跨过Logon使用的序列号,使用比原Logon大1的序列号继续发送新的排队消息。
3、如果大于下一个期望序列号值,发送Logout终止会话。
除了希望自动进行那个间隙填充外,任何一方应给予接收的Logon消息的MsgSeqNum(34)产生一个ResendRequest。如果间隙由Logon消息的MsgSeqNum(34)导致,接收逻辑应希望自动填充间隙以恢复间隙的任何消息序列。
4.6 Standard Message Header标准消息头
任何管理和应用消息都紧跟在一个标准头部之后。头部标示了消息的类型、长度、目标、序列号,来源及创建时间。
两个域用于协助重发消息。PossDupFlag为‘Y’表明一个会话级事件导致的消息重传(如,使用同一个序列号重传一个消息)。PossResend为‘Y’表明使用新的序列号重新发出一个消息(如,重新发送一个Order指令)。接收程序应按下述方法进行处理:
PossDupFlag 如果一个消息的序列号表明之前已经收到,忽略该消息;如果没有,进行正常处理。
PossResend 将消息传递给应用程序以判断是否之前已经收到(如,验证Order的ID号和参数)。
Message Routing Details – One Firm-to-One Firm (point-to-point)
Message Routing Details – One Firm-to-One Firm(Point-to-point)消息路由-点对点
下表展示了使用SenderCompID,TargetCompID,DeliverToCompID,和OnBehalfOfCompID在两个企业间的一个单一的FIX会话。假设A为卖方,B为买方
Message Routing Details-Third Party Message Routing消息路由-第三方消息路由
FIX会话协议具备支持一个FIX会话包含多个参与这者的能力。包括1对多,对对1,或者1对1的形式。此外,一些第三方可以与其它第三方连接,在消息发起者和最终的接收者间形成一个多跳的链。SenderCompID,TargetCompID,DeliverToCompID,和OnBehalfOfCompID域用于路由消息。
当一个第三方在另一个企业中间发送一个消息时(使用OnBehalfOfCompID),可以选择在NoHops重复组中加入它的细节信息。这个重复组构建了消息在第三方重新发送的的一个历史列表。NoHops重复组不用于协助路由,而是为接收消息方对参与的第三方进行审计时提供痕迹。当一个第三方转发一个消息给下一跳(可能是最终接收者,或另一个第三方)时,此第三方可以将其跳信息加到NoHops重复组中(如,将其SenderCompID作为HopCompID,其SendingTime作为HopSendingTime,将接收消息的MsgSeqNum或其他引用数据作为HopRefID
)。
注意:如果OnBeHalfOfCompID或DeliverToCompID消息源识别/路由方法在一个FIX会话中使用,那么该方法必须在通过此会话传送的所有消息中使用。
下表提供了在单一FIX会话中表名多个企业参与时SenderCompID,TargetCompID,DeliverToCompID和OnBehalfOfCompID的使用方法。假设A=卖方,B和C表示买方,Q=第三方。
注意,由于在一个给定的FIX会话中,一些域(如在一个新Order指令中的ClOrdID)必须是唯一的。因此,当使用OnBehalfOfCompI(或DeliverToCompID)进行寻址时,推荐的做法是在OnBehalfOfCompI(或DeliverToCompID)之后加上源地址。这样,如果A发送消息到Q的ClOrdID为“123”,那么Q将“A-123”作为ClOrdID的值发送到C,以确保唯一性。
标准消息头部如下
Standerd Message Header
4.7 Standard Message trailer标准消息尾部
每个消息,管理或应用消息,以一个标准尾部结束。该尾部用于分割消息并包含描述Checksum值的3个数字字符。
Standard Message Trailer
5 ADMINISTRATIVE MESSAGES管理消息
管理消息强调协议的应用需求。以下部分内容描述了每个管理消息,提供消息的图表。
管理消息由连接各方产生。
5.1 Heartbeat 心跳消息
心跳消息监控通信链路的状态,用于识别一连串消息中最后没有收到的消息。
当如果一个FIX连接的任何一方在超过HeartBtInt规定的时间间隔后没有收到任何数据,将发送一个Hearbeat消息。当如果一个FIX连接的任何一方在超过HeartBtInt规定的时间间隔加上一些传输时间后没有收到任何数据,将发送一个Test Request测试请求消息。如果在超过HeartBtInt规定的时间间隔加上一些传输时间后仍然没有收到Heartbeat消息,那么应视为连接断开并应采取纠错处理。如果HearBtInt设置为0,则不会产生常规的Heartbeat消息。注意,一个测试请求消息能够不间隔HeartBtInt的值被发送,用于强制请求一个Heartbeat消息。
Heartbeat消息作为测试请求消息的响应,必须包含在请求测试消息中的TestReqID值,用于验证Heartbeat消息是测试请求消息的响应而不是常规超时的响应。
Heatbeat消息格式如下:
Heartbeat
5.2 Logon 登陆消息
Logon消息认证一个连接到一个远程系统的用户。Logon消息必须是应用程序用于请求初始化一个FIX会话的第一个消息。
HeartBtInt(108)域用于申明产生心跳消息的时间间隔,连接双方使用形同的HeartBtInt值。其值应被双方企业一致同意,由Logon消息发起者初始化,并被Logon接收者回应。
当接收到Logon消息,会话接收者将认证参与者的连接请求,并发出一个Logon消息确认连接请求被接受。这个确认Logon消息也能用于发起者验证连接已经与对端正确建立。
在接收到Logon消息后会话接收者必须立即准备好开始处理消息。会话发起者可以选择在收到Logon确认消息前传输FIX消息,但推荐在收到返回的Logon消息后,完成加密秘要协商后进行正常的消息传输。
确认Logon消息可以用于加密秘要协商。如果一个会话密钥被认为是弱秘要,一个推荐的新的更加强状的会话秘要将在Logon消息中返回。这仅在加密协议允许秘要协商时有效。
Logon消息能用于确定支持的消息最大长度MaxMessageSize(能用于控制将大消息进行分节的规则)。也能用于确定双方接收和发送所支持的消息的类型MsgType。
下表是Logon消息的格式:
Logon
5.3 Test Request 测试请求消息
测试请求消息强制对方发送一个Heartbeat消息。测试请求消息检查序列号或验证通信线路状态。对端应用程序响应一个包含TestReqID的Heartbeat消息。
TestReqID用于检查对端应用是依据测试请求消息产生的Heartbeat消息,而不是通常的超时。对端应用程序将TestReqID包含在响应Heartbeat消息中。任何字符串可以被用于TestReqID(一个建议是使用时间戳字符串)。
测试请求消息格式如下:
Test Request
5.4 Resend Request 重传请求消息
重传请求消息由接收用用程序发送用于开始消息的重传。这个功能在序列号间隙被侦测到时,在接受应用程序丢失消息时,或者作为一个初始化处理功能时非常实用。
重传请求消息能用于请求一个单一消息,一定范围内的消息,或者一个特定消息的所有后续消息。
注意:发送应用程序可能希望考虑重传消息的消息类型。如:如果在重传序列中的一个新指令消息在其最初发送后经过一段相当长的时间,那么发送方可能不希望重传该消息以提供改变市场条件的潜在可能性。(Seqence Reset-GapFill消息用于发送方不希望发送二跳过这类消息。)
注意:接收程序必须按照顺序处理消息。如:如果收到消息8和9,消息7丢失,程序应忽略消息8和9,并要求重传消息7到9,或者最好重传消息7到0(0表示序列号无穷大)。后者,作为当序列号出现混乱,双方同时尝试恢复一个间隙时,从当前的某些竞争条件下快速恢复的推荐方法。
1. 为请求一个单一消息, BeginSeqNo=EndSeqNo
2. 为请求一定范围内的消息,BeginSeqNo=请求范围内第一个消息,EndSeqNo=请求范围内最后一个消息。
3. 请求特定消息的所有后续消息:BeginSeqNo=请求范围内第一个消息,EndSeqNo=0。
重传请求消息格式如下:
Resend Request
5.5 Reject(session-level)驳回消息
当一个接收消息由于违背会话层规则,不能被正确的处理,应发送驳回消息。一个例子是:当一个接收消息通过解密,效验和检查,及数据体长度检查后没有有效的基础数据(如,MsgType=&),将产生一个驳回消息。结果是,这些消息将传递给交易应用程序,如果需要,将产生商业逻辑级的驳回。
驳回消息应记录到日志中,且接收序列号应增加。
注意:接收应用程序应忽略任何干扰消息,不能被解析的及未通过数据完整性检查的消息。处理下一个FIX消息将导致检测到一个序列号间隙并产生一个Resend Request消息。FIX引擎应包含处理在此情况下的无限重传循环。
生成和接收到一个驳回消息表明一个接收或发送程序的逻辑错误导致的严重的错误。
如果发送程序选择重传驳回消息,该消息应赋予一个新的序列号值,且PossResend设置为‘Y’。
无论何时,强烈推荐将描述失败原因在Text 域中描述(如,INVALID DATA(35))。
如果接收到的一个应用级消息满足所有会话级规则,该消息应在商业消息级被处理。如果在处理过程中检测到规则冲突,将产生发送一个商业绩驳回。许多商业级消息都有自己特定的驳回消息。如果没有,则产生发送一个Business Message Reject消息。
注意,在收到一个商业消息,满足会话级规则,但不能被传送给商业级处理系统时,一个带有BusinessRjectReason=“Application not available at this time”的Business Message Reject消息将被发出。
会话级驳回消息场景:
驳回消息格式:
Reject
5.6 Sequence Reset(Gap Fill)序列号复位(间隙填充)消息
序列号复位消息有两种模式:Gap Fill模式和Reset模式。
5.6.1Gap Fill 模式
在下列情况下,Gap Fill模式用于响应当出现一个或多个消息必须被跳过时的Resend Request消息
1. 在常规的重传处理过程中,发送应用程序可以选择不发送消息(如,一个过期的指令)。
2. 在常规的重传处理过程中,大量的管理消息将跳过而不重传(如:Heartbeat, TestRequest 消息)。
GapFillFlag(123)域为‘Y’时,为Gap Fill模式。
如果GapFillFlag(123)域设置为‘Y’,MsgSeqNum应同标准消息序列号规则保持一致(如,序列号Reset GapFill模式消息的MsgSeqNum应为GapFIll消息的最开始的MsgSeqNum,因为其值为远端程序希望接收的消息序列号)。
5.6.2Reset Mode 复位模式
复位模式包括了指定一个任意的、数值更大的、接收者期望的Reset-Reset消息序列号,并用于在出现不可恢复的应用程序错误时重新建立一个FIX会话。
复位模式由GapFillFlag为‘N’时,或被忽略时被指定。
如果GapFillFlag没有出现,或其值为‘N’,可以认为Sequence Reset消息的目标是从序列号混乱时的恢复。在序列号的Reset-Reset模式中,在消息头中的MsgSeqNum将被忽略(如,当接受到带有错误的MsgSeqNum序列号的Sequence Reset-Reset模式消息时,不产生重传请求)。序列号复位的Reset消息不应被当作揖个重传请求的常规响应(使用序列号复位的Gap Fill模式)。序列号复位的Reset模式仅在当使用序列号复位的Gap Fill模式无法恢复时进行灾难恢复。注意,使用序列号复位模式时有可能造成消息丢失。
5.6.3Rules for processing all Sequence Reset messages处理所有序列号复位消息的规则
发送程序将启动序列号复位。所有情况下,这个消息指定NewSeqNo以作为消息接收方期望接收的下一个消息的序列号的复位,紧接在消息和/或被挑过的序列号 ?
序列号复位,近能增加序列号。如果一个序列号复位消息尝试减小期望接收消息的序列号时,应被当作揖个严重错误而被拒绝。多个Resend Request重传请求可能在接连着被发起(如,5道10,接着5到11)。如果序列号8,10,11是应用消息而5到7和9是管理消息,那么重传请求的结果为:序列号复位GapFill模式下的NewSeqNo为8,消息8;序列号复位GapFill模式下的NewSeqNo为10,消息10。也可以是序列号复位GapFill模式下的NewSeqNo为8,消息8;序列号复位GapFill模式下的NewSeqNo为10,消息10,和消息11。必须小心地忽略尝试减少期望序列号值的复制的序列号复位GapFill模式消息。可以通过检查MsgSeqNum是否小于期望值来检查。如果是,那么该序列号复位GapFill模式消息为复制消息,应被忽略。
序列号复位消息格式:
Sequence Reset
5.7 Logout注销消息
Logout消息发起或确认一个FIX会话的终止。没有Logout消息交换的连接断开应被视为一个异常情况。
在实际的关闭会话前,Logout发起者应等待对端的Logout确认消息的响应。这样可以给远端在必要时执行一些Gap Fill操作的机会。如果远端在规定的时间间隔后没有响应,会话可以终止。
在发送Logout消息后,注销发起者不应发送任何消息,除非注销的接收者通过ResendRequest消息请求发送消息。
注销消息格式如下:
Logout
5.8 CheckSum Calculation 校验和计算
一个FIX消息校验和通过计算到ChechSum域(但不包括)的消息的每个字节和得到。然后,校验和被转换为模256的数字用于传送和比较。校验和在所有加密操作之后被计算。
为了便于传输,校验和必须以可打印字符形式进行传输,因此,校验和被转换位3个ASCII数字。
比如:如果消息的校验和为274,则模256后为18(256 18 = 274)。这个值将采用|10=018|进行传输,其中“10=”是校验和域的标签。
产生校验和的代码示列如下:
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 );
}
6 FIX 会话层测试用例和期望行为
6.1 Applicability 适用性
本文档在2002年9月20日最后被修订,当时的FIX协议的最新版本为带有20020930的扩展的FIX 4.3 。此文当适用于FIX4.X,除非特别说明。
6.2When to send a Logout vs. when to just disconnect何时发送Logout与仅断开连接
一般情况下,一个Logout消息应在关闭一个连接前发送。如果这个Logout消息是源于一个错误条件,Logout的Text域应提供错误原因的描述,为远端FIX系统提供问题诊断的操作支持。这里有2个例外,推荐不发送Logout消息:
1、在登陆阶段,如果会话发起者的SenderCompID,TargetCompID或IP其中一个无效时,推荐立即终止会话,不发送Logout消息。这个登陆尝试有可能使一个未经授权的破坏系统的未认证尝试,因此,企业不希望泄露其FIX系统的任何信息,如,哪个SenderCompID,TargetCompID是有效的,或所支持的FIX版本。
2、在登陆阶段,当一个有效的FIX会话已经被一个企业使用时,该企业的第2次连接尝试的Logon消息被接受时,推荐会话接收者立即中断该第2次连接尝试,不发送Logout消息。发送一个Logout消息将冒着妨碍和影响当前FIX连接的风险。例如:在一些FIX实现系统中,发送一个Logout消息可能会消耗一个序列号,这样将会导致在一个已经建立的FIX会话中的序列号混乱。
在其他情况下,如果发送一个Logout消息不产生风险和安全冲突,Logout消息应随同描述信息一起发送。
6.3 When to send a Session Reject vs. when to ignore the message 何时发送会话驳回与何时忽略消息
以下内容从FIX协议规范中的Reject消息定义中摘抄:
注意:接收程序应忽略任何文本混乱,不能被解析以及数据完整性检查失败的消息。处理下一个右下的FIX消息将导致检测到一个序列号间隙并产生一个重传请求消息Resend Request。这种情况下,FIX引擎应包含识别重传无限循环的逻辑。
FIX协议采取乐观的观点。它假设一个混乱的消息是由于传输中出现的错误,而不是FIX系统的问题。因此,如果发送一个重传请求消息(Resend Request),该混乱消息将被正确得重传。如果一个消息没被认为是混乱的,那么,推荐发送一个会话级驳回消息。
6.4 What constitutes a garbled message 什么样的情况认为是一个混乱消息
1. BeginString(tag#8)不是一个消息中的第一个tag或不是8=FIXT.n.m.的格式。
2. BogyLength(tag#9)不是一个消息中的第二个tag或没有包含正确的字节数。
3. MsgType(tag#35)不是一个消息中的第三个tag。
4. Checksum(tag#10)不适最后一个tag或没有包含正确的值。
如果丢失MsgSeqNum(tag#34),一个Logout消息将被发送以终止FIX连接。因为这种情况意味着一个严重的应用程序错误。
6.5 FIX Session-level State Matrix FIX会话层状态举证
6.6 FIX Logon Process State Transition Diagram FIX登陆消息处理状态转换图
6.7 FIX Logout Process State Transition Diagram FIX Logout处理状态转换图
7 Test cases 测试用例
这些测试用例来自进行测试的FIX系统。FIX系统达到某种状态,或激发条件,被期望采取由“期望行为”所定义的正确动作。
7.1 Buyside-oriented(session initiator) Logon and session initiation test case
7.2 Sellside-oriented(session acceptor) Logon and session initiation test case
7.3 Test cases applicable to all FIX systems
|
|
来自: 昵称32345233 > 《待分类》