Session Protocol

Introduction

A FIX session is defined as a bi-directional stream of ordered messages between two parties within a continuous sequence number series. A single FIX session can exist across multiple sequential (not concurrent) physical connections. Parties can connect and disconnect multiple times while maintaining a single FIX session. Connecting parties must bi-laterally agree as to when sessions are to be started/stopped based upon individual system and time zone requirements. Resetting the inbound and outbound sequence numbers back to 1, for whatever reason, constitutes the beginning of a new FIX session.

It is recommended that a new FIX session be established once within each 24 hour period. It is possible to maintain 24-hour connectivity and establish a new set of sequence numbers by sending a Logon<A> message with the ResetSeqNumFlag(141) set.

The FIX session protocol is based on an optimistic model. Normal delivery of data is assumed (i.e. no communication level acknowledgment of individual messages) with errors in delivery identified by message sequence number gaps. This section provides details on the implementation of the FIX session layer and dealing with message sequence gaps.

The following terms are used throughout this section:

  • Valid FIX Message is a message that is properly formed according to this specification and contains a valid body length and checksum field
  • Initiator establishes the telecommunications link and initiates the session via transmission of the initial Logon<A> message.
  • Acceptor is the receiving party of the FIX session. This party has responsibility to perform first level authentication and formally declare the connection request “accepted” through transmission of an acknowledgment Logon<A> message.
  • FIX Connection is comprised of three parts: logon, message exchange, and logout.
  • FIX Session is comprised of one or more FIX Connections, meaning that a FIX Session spans multiple logins.

Application Version Independence

A FIXT.1.1 FIX session supports transmission of multiple versions of Application Messages over the same FIX session.

A FIXT.1.1 FIX session can support transmission of multiple application versions of the same Message Type.

Default Application Version Identification

Session Default Application Version

The Session Default Application Version is specified in the DefaultApplVerID(1137) of the Logon<A> message used to initiate a FIX session. The Session Default Application Version must be specified at Logon time.

Message Type Default Application Version

The <MsgTypeGrp> component can optionally be used to specify what Application Messages are supported over the FIX Session being initiated.

Within the <MsgTypeGrp> component, a FIX session can specify a Message Type Default Application Version on the Logon<A> message within the <MsgTypeGrp> Component. For each Message Type where the default application version is different from the Session Default Application Version, the Message Type Default Application Version is specified using the RefMsgType(372) field to specify the MsgType, the RefApplVerID(1130) to specify the Application Version and the DefaultVerIndicator(1410) field to indicate if the RefApplVerID(1130) as the default.

The Message Type Default Application Version has precedence over the Session Default Application Version.

Explicit Application Version

The application version can be specified on a Message Instance using the ApplVerID(1128) field from the FIXT.1.1 <Standard Header>.

The Explicit Application Version only applies to the Message Instance in which it is sent, default application versions remain unaltered.

The Explicit Application Version has precedence over the Message Type Default Application Version and the Session Default Application Version.

FIX Message Processors (colloquially FIX engines) must maintain state information regarding the Default Application Version used during the FIX Session.

Application Version Precedence

Application Version Fields Precedence
Session Default DefaultApplVerID(1137) Lowest level of precedence
Message Type Default RefMsgType(372), RefApplVerID(1130), DefaultVerIndicator(1410) Supercedes the Session Default Application Version.
Explicit ApplVerID(1128) Has precedence over Default Application Versions. Only applies to the Message Instance.

Extension Pack Support

The concept of an Extension Pack was introduced with FIX.5.0 and FIXT.1.1 in order to permit adoption of functionality between versions of FIX. An Extension Pack is a set of changes to the FIX Specification (more accurately – to the FIX Repository). Prior to the introduction of FIX.5.0 and FIXT.1.1 , early adopters were required to use user defined tags to adopt new functionality as part of the existing version. Extension Packs permit the assignment of tag numbers and message types so that specific enhancements can be adopted between versions of the FIX Specification.

Extension Pack Backround

Extension Packs are identified by a sequential integer number and must be applied in order.

Extension Packs are cumulative.

Extensions are applied sequentially to create a Version of FIX, normally released as a Service Pack (starting with FIX.5.0).

An Extension Pack is considered available for use, if it has been approved and released for use by the FIX Global Technical Committee.

Use of Extension Packs

A FIX session can optionally specify a default extension pack as part of the Session Default Application Version by inclusion of a valid Extension Pack number in the DefaultApplExtID(1407).

An Extension Pack can be specified for a specific Message Type using the RefApplExtID(1406) field within the <MsgTypeGrp> Comoponent. If provided, the RefApplExtID becomes part of the Message Type Default Application Version.

A Message Instance can explicitly include an Extension Pack in the ApplExtID(1156) field. If the ApplExtID is specified it becomes part of the Explicit Application Version.

An Extension Pack is considered Incompatible with the Application Version if the Extension Pack specified is less than the last Extension Pack that were used to create the Application Version.

Given Application Version N, created from Extension Packs, x , x+1, .. x+y, an Extension Pack z is considered compatible with Application Version N if z > x+y.

Note to FIX Message Processor Implementors: There is no requirement for a FIX Message Processor to be able to dynamically configure and apply Extension Packs. The creation of Application Versions that include Extension Packs is deemed to be done outside of standard processing during development or configuration time.

Custom Application Version Support

In order to permit counterparties to create custom versions of FIX that restrict and/or extend the FIX specification, the concept of a Custom Appplication Version has been introduced. The Custom Application Version can be considered and implementation specific dictionary based upon the Application Version specified in an ApplVerID field.

The Custom Application Version can be a subset of a FIX Application Version.

By counterparty agreement, a Custom Application Version can be optionally specified. The Custom Application Version is a user defined string whose format is left undefined by the specification. Users can choose to use a URI or URL for instance. Marketplaces may choose to use their market acronym and a version number, such as CME5.0 or OMX5.0 for instance.

A default Custom Application Version can be specified in the DefaultCstmApplVerID(1408), If specified, the DefaultCstmApplVerID becomes part of the Session Default Application Version.

A default Custom Application Version can be specified for a Message Type using the RefCstmApplVerID(1131) field. If specified, the RefCstmApplVerID<1131> becomes part of the Message Type Default Application Version.

A Custom Application Version can be specified explicitly on an Application Message using the CstmApplVerID(1129) field in the FIXT Standard Header. If specified, the CstmApplVerID<1129> becomes part of the Explicit Application Version for the message instance.

Application Version Not Specified on FIXT.1.1 Session Level MessagesFIX Session Level messages (Logon<A>, Logout<5>, Reject<3>, ResendRequest<2>, SequenceReset<4>, TestRequest<1>, Heartbeat<0>) are versioned as part of the FIXT.1.1 Session Level.

The use of the Explicit Application Version fields [ApplVerID(1128), ApplExtID(1156), CstmApplVerID(1129)] is not permitted on FIX Session Level Messages.

Logon

Message exchange starts with exchanging initiating Logon messages. See description in Logon<A> message section.

Message Exchange

After completion of the initiazation process, normal message exchange begins. Descriptions of all valid FIXT1.1 application and session level messages can be found in 'FIX 5.0 SP2 : Messages By Category'.

Logout

Message exchange normally terminates with exchanging Logout messages. See description in Logout<5> message section.

Message Recovery

During initialization, or in the middle of a FIX session, message gaps may occur which are detected via the tracking of incoming sequence numbers. The following section provides details on how to recover messages.

As previously stated, each FIX participant must maintain two sequence numbers for each FIX session, one each for incoming and outgoing messages which are initialized at ‘1’ at the beginning of the FIX session. Each message is assigned a unique (by connection) sequence number, which is incremented after each message. Likewise, every message received has a unique sequence number and the incoming sequence counter is incremented after each message.

When the incoming sequence number does not match the expected number corrective processing is required. Note that the SeqReset-Reset message (used only to recover from a disaster scenario vs. normal resend request processing) is an exception to this rule as it should be processed without regards to its MsgSeqNum(34). If the incoming message has a sequence number less than expected and the PossDupFlag(43) is not set, it indicates a serious error. It is strongly recommended that the session be terminated and manual intervention be initiated. If the incoming sequence number is greater than expected, it indicates that messages were missed and retransmission of the messages is requested via the Resend Request<2> (see the earlier section, Ordered Message Processing).

Note: For the purposes of the following paragraphs requester refers to the party requesting the resend and resender refers to the party responding to the request. The process of resending and synchronizing messages is referred as “gap filling”.

Upon receipt of a Resend Request<2>, the resender can respond in one of three ways:

  1. retransmit the requested messages (in order) with the original sequence numbers and PossDupFlag(43) set to “Y” except for the administrative messages (listed below) which are not to be resent and which require a SeqReset-GapFill<4> (see #2)
  2. issue a SeqReset-GapFill<4> with PossDupFlag(43) set to “Y” message to replace the retransmission of administrative and application messages
  3. issue a SeqReset-Reset<4> with PossDupFlag(43) set to “Y” to force sequence number synchronization

The normal course of action involves a combination of #1 and #2. Note that #3 should be used ONLY to recover from a disaster situation which cannot be otherwise recovered via “Gap Fill” mode.

During the gap fill process, certain administrative messages should not be retransmitted. Instead, a special SeqReset-GapFill<4> message is generated. The administrative messages which are not to be resent are: Logon<A>, Logout<5>, ResendRequest<2>, Heartbeat<0>, TestRequest<1> and SeqReset-Reset<4> and SeqReset-GapFill<4>. The SeqReset-GapFill<4> can also be used to skip application messages that the sender chooses not to retransmit (e.g. aged orders). This leaves Reject<3> as the only administrative message which can be resent.

All FIX implementations must monitor incoming messages to detect inadvertently retransmitted administrative messages (PossDupFlag(43) flag set indicating a resend). When received, these messages should be processed for sequence number integrity only; the business/application processing of these message should be skipped (i.e. do not initiate gap fill processing based on a resent ResendRequest<2>).

If there are consecutive administrative messages to be resent, it is suggested that only one SeqReset-GapFill<4> message be sent in their place. The sequence number of the SeqReset-GapFill<4> message is the next expected outbound sequence number. The NewSeqNo(36) field of the GapFill<4> message contains the sequence number of the highest administrative message in this group plus 1. For example, during a Resend operation there are 7 sequential administrative messages waiting to be resent. They start with sequence number 9 and end with sequence number 15. Instead of transmitting 7 GapFill<4> messages (which is perfectly legal, but not network friendly), a SeqReset-GapFill<4> message may be sent. The sequence number of the GapFill<4> message is set to 9 because the remote side is expecting that as the next sequence number. The NewSeqNo(36) field of the GapFill<4> message contains the number 16, because that will be the sequence number of the next message to be transmitted.

Sequence number checking is a vital part of FIX session management. However, a discrepancy in the sequence number stream is handled differently for certain classes of FIX messages. The table below lists the actions to be taken when the incoming sequence number is greater than the expected incoming sequence number.

NOTE: In *ALL* cases except the Sequence Reset - Reset<4> message, the FIX session should be terminated if the incoming sequence number is less than expected and the PossDupFlag(43) is not set. A Logout<5> message with some descriptive text should be sent to the other side before closing the session.

Response by message type
Message type Action to be taken on Sequence # mismatch
Logon<A> Must always be the first message transmitted. Authenticate and accept the connection. After sending a Logon<A> confirmation back, send a ResendRequest<2> if a message gap was detected in the Logon<A> sequence number.
Logout<5>

If a message gap was detected, issue a ResendRequest<2> to retrieve all missing messages followed by a Logout<5> message which serves as a confirmation of the logout request. DO NOT terminate the session. The initiator of the Logout sequence has responsibility to terminate the session. This allows the Logout<5> initiator to respond to any ResendRequest<2> message.

If this side was the initiator of the Logout sequence, then this is a Logout<5> confirmation and the session should be immediately terminated upon receipt.

The only exception to the “do not terminate the session” rule is for an invalid Logon<A> attempt. The session acceptor has the right to send a Logout message and terminate the session immediately. This minimizes the threat of unauthorized connection attempts.

ResendRequest<2>

Perform the Resend processing first, followed by a ResendRequest<2> of your own in order to fill the incoming message gap.

SeqReset-GapFill<4>

Send a ResendRequest<2> back. Gap Fill messages behave similar to a SeqReset message. However, it is important to insure that no messages have been inadvertently skipped over. This means that GapFill messages must be received in sequence. An out of sequence GapFill is an abnormal condition

SeqReset-Reset<4>

Ignore the incoming sequence number. The NewSeqNo(36) field of the SeqReset message will contain the sequence number of the next message to be transmitted.

All Other Messages

Perform Gap Fill operations.

Logon Message NextExpectedMsgSeqNum Processing

The NextExpectedMsgSeqNum(789) field has been added in FIX 4.4 to the Logon<A> message to support a proposed new way to resynchronize a FIX session. This new method is optional and its use should be bilaterally agreed upon between counterparties.

NextExpectedMsgSeqNum(789) is used as follows:

In its Logon<A> request the session initiator supplies in NextExpectedMsgSeqNum(789) the value next expected from the session acceptor in MsgSeqNum(34). The outgoing header MsgSeqNum(34) of the Logon<A> request is assigned the next-to-be-assigned sequence number as usual.

The session acceptor validates the Logon request including that NextExpectedMsgSeqNum(789) does not represent a gap. It then constructs its Logon<A> response with NextExpectedMsgSeqNum(789) containing the value next expected from the session initiator in MsgSeqNum(34) having incremented the number above the Logon<A> request if that was the sequence expected. The outgoing header MsgSeqNum(34) is constructed as usual.

The session initiator waits to begin sending application messages until it receives the Logon response. When it is received the initiator validates the response including that NextExpectedMsgSeqNum(789) does not represent a gap.

Both sides react to NextExpectedMsgSeqNum(789) from its counterparty thus:

  • If equal to the next-to-be-assigned sequence, proceed sending new messages beginning with that number.
  • If lower than the next-to-be-assigned sequence, "recover" (see "Message Recovery") all messages from the the last message delivered prior to this Logon<A> through the specified NextExpectedMsgSeqNum(789) sending them in order; then Sequence Reset-Gap Fill<4> over the sequence number used in Logon<A> and proceed sending newly queued messages with a sequence number one higher than the original Logon<A>.
  • If higher than the next-to-be-assigned sequence, send Logout<5> to abort the session.

Neither side should generate a ResendRequest<2> based on MsgSeqNum(34) of the incoming Logon message but should expect any gaps to be filled automatically. If a gap is produced by the Logon message MsgSeqNum<34>, the receive logic should expect the gap to be filled automatically prior to receiving any messages with sequences above the gap.