当我开始研究FIX协议的时候,我想在因特网上寻找一些很好的教程可以作为FIX协议规范的补充,当时没有什么内容,所以当我开始写博客的时候,我想把自己在FIX协议方面的经验以清晰简洁的教程格式发布出来。因为我也喜欢问答式的知识分享,所以我写了一些关于FIX协议面试问题的博客,你可能会感兴趣。
在今天的FIX教程中,我们将了解FIX协议会话级消息。正如你们可能知道的,所有的FIX消息可以大致分为两类,
理解FIX会话如何工作是非常重要的,因为除非你知道FIX序列号的基本原理、FIX会话如何连接、发送方FIX 引擎和接收方FIX引擎之间的消息序列是什么,否则您将无法快速识别与FIX协议相关的任何问题。FIX规范非常清楚FIX引擎应该在各种FIX会话连接/断开场景中做什么。
根据FIX协议,首先发送方FIX引擎和接收方FIX引擎通过TCP/IP协议在指定的IP地址和端口上通过租用的线路、Radianz链接、虚拟专用网(VPN)或互联网相互连接。一旦TCP套接字连接建立,发送方应用程序发送Logon(FIX标记35=A MsgType=A)与约定的SenderCompID
(FIX标记49)和TargetCompID
(FIX标记56)。
接收方FIX引擎接收这个消息并基于SenderCompID
(FIX标记49)和TargetCompID
(FIX标记56)验证发送方FIX引擎, 如果客户端身份验证成功, 接收方FIX引擎回复登录(FIX标记35=A)消息, 成功建立连接, 然后FIX引擎将通过心跳消息(FIX标记35=0)在指定的心跳间隔保持连接活跃。
如果接收方FIX引擎无法验证客户端,它将发送一个登出消息(FIX标记35=5),连接将被终止,尽管套接字连接仍然存在。如果接收到序列号低于预期的FIX消息,接收方FIX引擎也可以发送登出消息(FIX标记35=5)拒绝连接。
现在让我们详细地看看每个会话级别或Admin消息。您总是可以参考FIX协议规范文档,建议也参考该文档来获得每个消息的完整描述。FIX规范中指定的一些重要的会话级别或管理消息如下:
FIX (financial information exchange) Protocol中,心跳消息用MsgType=0表示。FIX Session Initiator和FIX Session Acceptor都在心跳间隔定义的时间间隔(通常为30或60秒)内互相发送心跳消息以保持FIX会话处于活动状态。如果您在FIX Engine日志文件中看到Heartbeat消息(FIX标记35=0),则意味着您的FIX会话已启动并已连接。
登录消息由FIX标记35=A表示,它用于从FIX 发起者(客户端)发送登录消息。根据FIX协议,一旦FIX Initiator和FIX Acceptor之间的TCP连接建立,FIX Initiator发送登录消息(tag 35=A),该消息包含事先商定的SenderCompID
(tag 49)和TargetCompID
(tag 56),还有FIX Acceptor期望的序列号 (FIX tag 34)。
当FIX acceptor接收到Logon请求(MsgType=A)时,它根据FIX Message和Sequence No中指定的CompID对FIX会话进行身份验证,并根据身份验证的结果用Logout (tag 35=5)消息或Logon(tag 35=A)消息回复。
Resend Request (FIX tag 35=2或MsgType=2)用于请求在传输过程中或由于错误序列号而丢失的消息的重新传输或重放。它通常由正在接收消息的FIX Engine发送,以启动消息的重新传输。如果检测到序列号间隙,或者接收应用程序的FIX Engine丢失了消息,或者作为初始化过程的一部分使序列号同步,FIX Engine将使用Resend Request(标记35=2)。
Resend Request (FIX标记35=2或MsgType=2)可以用于请求单个FIX消息、一系列FIX消息或特定FIX消息之后的所有FIX消息。
值得注意的是,发送FIX Engine可能会在重新发送消息时考虑消息类型;例如,如果一个新订单处于重发序列中,并且从最初发送到现在已经经过了很长一段时间,发送方FIX Engine可能不希望重新发送该订单,因为市场动态、价格等可能已经改变,这可能会导致陈旧的订单被拒绝,这是由订单管理系统(OMS)完成的。(Sequence Reset (FIX tag 35=4或MsgType=4)也称为Gap Fill,用于跳过发送方FIX Engine不想重发的FIX消息。)
接收到的FIX Engine必须按顺序处理消息,例如,如果FIX消息号11被错过,12-13被接收,应用程序应该忽略12和13,并请求重新发送11-13,或11 -0(0表示无穷)。强烈建议使用第二种方法从非序列条件中恢复,因为当FIX engine的两端同时试图恢复序列号间隙时,它允许在存在某些竞态条件时更快地恢复。
测试请求用FIX标记35=1或MsgType=1表示。FIX Engine使用测试请求消息来强制要求对方的FIX Engine发送心跳。测试请求(FIX标记35=1)消息检查序列号或验证通信线路状态。相对的FIX引擎用包含TestReqID (FIX标记112)的心跳(FIX标记35=0)响应测试请求消息(FIX标记35=1)。
TestReqID (FIX标记112)验证对方FIX Engine正在生成心跳(FIX标记35=0),是否作为测试请求的回应(FIX标记35=1),而不是正常的超时。相反的FIX引擎在生成的Heartbeat (FIX标记35=0)中包含TestReqID (FIX标记112)。任何字符串都可以用作TestReqID (FIX标记112)(一些FIX引擎通常使用时间戳字符串)。
会话级别拒绝消息用FIX标记35=3或MsgType=3表示。会话级别Reject由FIX引擎在收到FIX消息但由于会话级别规则违反(如FIX Protocol规范文档中所指定)而不能正确处理时使用。例如,FIX Engine将使用会话级别Reject,或者它接收到一个包含无效基本数据(例如MsgType 35 =$)的FIX消息,该消息成功通过了反加密、Checksum
(FIX tag 10)和BodyLength
(FIX tag 9)检查。作为一条规则,只要有可能,FIX消息就应该转发到交易应用程序以获得业务级别的拒绝。
被拒绝的消息应该被记录到日志文件中,传入的序列号必须由FIX Engine递增。
值得注意的是,接收FIX Engine时应该忽略任何不正确、无法解析或数据完整性检查失败的FIX消息。对下一个有效的FIX消息的处理将导致序列号不匹配的检测,并且将生成一个重发请求(FIX标记35=2或MsgType=2)并传递给对方的FIX Engine。
Reject (FIX标记3)消息的生成和接收表明了一个严重的错误,可能是发送或接收FIX Engine中的错误逻辑导致的。如果发送的FIX引擎选择重新发送被拒绝的消息,它应该被分配一个新的序列号(FIX标记34),并使用PossResend
(FIX标记97)=Y发送。建议在FIX标签Text
(fix tag 58)中描述拒绝的原因,然后接收FIX引擎或开发人员可以使用它来识别会话级别拒绝的实际原因(例如,Limit Order中没有Price标签)。
下面是一些可以使用会话级拒绝(FIX Tag 3或MsgType=3)的场景。
CompID问题: FIX Initiator或FIX Acceptor发送不正确的SenderCompID(标签49)和TargetCompID(标签56)。
无效的MsgType: FIX Initiator 或FIX Acceptor发送的MsgType不是特定FIX版本(如FIX4.2)中指定的
值的数据格式不正确: 如果FIX标记是时间戳类型,但FIX引擎却发送其他数据类型
必须的标签缺失: FIX Initiator或FIX Acceptor都没有在特定的FIX消息中发送必须的FIX 标签,例如,在OrdType =2
的NewOrderSingle
(MsgType=D)消息中丢失Price
(FIX tag 44),即Limit Order。
无效的标签: FIX Initiator或FIX Acceptor发送的标签不是特定FIX版本在FIX规范中指定的,例如FIX4.2
没有为该消息类型定义标记: FIX initiator或FIX Acceptor正在发送某一标记不是在FIX 规范中为该特定消息类型指定的标记,例如在登出消息中发送TestReqID。
未定义的标签: 如果某一发送者FIX引擎正在发送自定义标签,而接收引擎没有配置或支持该标签。
没有指定值的标签: 例如35=
,该特定的FIX标签没有值。这不是一个有效的FIX消息,因此接收FIX引擎将拒绝它。
序列重置也称为间隙填充(Gap Fill)消息,由FIX标记35=4或FIX MsgType 35=4表示。它用于响应重发请求(FIX tag 35=2或MsgType=2),通过发送FIX引擎来重置对方FIX引擎上收到的序列号。Sequence Reset message (FIX tag 35=4)在两种不同的模式下操作,一种是GapFillFlag
(FIX tag 123)是’Y’,也称为Sequence Reset - GapFill; 另一种模式是GapFillFlag
(FIX tag 123)是’N’或不存在,也称为Sequence Reset - Reset mode。按照FIX协议规范,“Sequence Reset (FIX tag 35=4)-Reset”模式仅用于从无法通过“Gap Fill”模式恢复的灾难情况中恢复。
Sequence Reset或GapFill消息(fix tag 35=4)可以在以下情况下有用:
在FIX协议规范中,注销消息由FIX标记35=5或MsgType=5表示,它用于终止或关闭任何FIX会话。如果接收方FIX引擎无法验证客户端,它将发送一个登出消息(FIX标记35=5),连接将被终止,尽管套接字连接仍然存在。
如果接收到序列号低于预期的修复消息,接收方FIX引擎也可以发送登出消息(修复标记35=5)。注销消息(标记35=5)用于终止FIX会话。没有交换登出消息(tag 35=5)的会话终止或断开连接被视为异常情况。
在实际终止或关闭会话之前,交换登出消息(fix tag 35=5)允许FIX引擎发送方执行任何可能需要或必要的Sequence Reset (fix tag 35=4)或Gap fill操作。登出发起者还应该等待对方的FIX引擎响应确认登出消息(FIX标记35=5),如果远程FIX engine在指定的时间内没有响应,它可以终止会话。