FIX Session Level Management
Establishing and Maintaining a FIX Session
The Logon [A] message initiates a connection to the Bullish platform. FIX sessions are typically initiated by Bullish participants, and can be made any time while the system is available.
Participants are highly recommended to reset sequence numbers at each logon, which minimizes the likelihood of hitting the message cap described in Sequence Number Cap. The option of not resetting sequence numbers is retained here, however, in case the participant wishes to recover messages intra-day in circumstances such as unexpected network disconnects.
Table 3: Logon [A] message
| Tag | Field Name | Req'd | Type | Comments |
|---|---|---|---|---|
| < Standard Header > | Y | 35 = A | ||
| 98 | EncryptMethod | Y | int | Encrypted messages are not supported 0 = NONE |
| 108 | HeartBtInt | Y | int | A 30-second interval is required |
| 141 | ResetSeqNumFlag | Y | Boolean | Indicates both sides of a FIX session should reset sequence numbers back to 1. We recommend that customers frequently reset sequence numbers at a time convenient for them. This should be 'N' in cases of reconnection after an unexpected disconnect. Y = Yes N = No |
| 554 | Password | C | String | Password assigned to the CompID. Required when sent from the client into the Bullish platform. |
| 1409 | SessionStatus | C | int | Sent from Bullish to indicate status of Logon attempt. 0 = Session active |
| < Standard Trailer > | Y |
A successful logon attempt shall be acknowledged by the Bullish platform with a Logon [A] message indicating SessionStatus (1409) = 0 (session active).
Figure 1: Successful logon
Unsuccessful logons shall be rejected using a Logout [5] message containing a SessionStatus (1409) field to indicate the reason for the rejection.
Figure 2: Unsuccessful logon attempt
Once a FIX session has been successfully established, both FIX engines on either side of the connection should regularly exchange messages to ensure that the connection remains live. The frequency of such a message exchange is determined by the HeartBtInt (108) value indicated in the Logon [A] message. The send or receipt of any application message satisfies this requirement to regularly exchange messages. In the event that the session does not send or receive an application message then, then it may instead use the Heartbeat [0] message.
Table 4: Heartbeat [0] message
| Tag | Field Name | Req'd | Type | Comments |
|---|---|---|---|---|
| < Standard Header > | Y | 35 = 0 (zero) | ||
| 112 | TestReqID | N | String | Required when the heartbeat is the result of a Test Request [1] message. The value in this field should echo the TestReqID (112) received in the Test Request. |
| < Standard Trailer > | Y |
At any point either counterparty can force the opposing FIX engine to send a Heartbeat [0] message by submitting a TestRequest [1] message containing a TestReqdID (112) value, which should be echoed in the Heartbeat [0] response.
Table 5: TestRequest [1] message
| Tag | Field Name | Req'd | Type | Comments |
|---|---|---|---|---|
| < Standard Header > | Y | 35 = 1 | ||
| 112 | TestReqID | Y | String | ID to be returned in the resulting Heartbeat [0] response |
| < Standard Trailer > | Y |
Figure 3: TestRequest from Bullish triggering a Heartbeat response from participant
Sequence Number Tracking, Recovery, and Reset
The FIX protocol uses simple, incrementing MsgSeqNum (34) values (carried in the Standard Header of each message) to both detect and request retransmission of missed messages.
Each engine should maintain a simple message count of outbound and inbound messages, values which should increment by one for each message sent or received per FIX session. Should a message be received that does not match the expected sequence number given, then it is possible that one or more messages were lost.
In that situation, a ResendRequest [2] message may be sent to request retransmission of a specified range of messages identified by their MsgSeqNum (34) value.
Table 6: ResendRequest [2] message
| Tag | Field Name | Req'd | Type | Comments |
|---|---|---|---|---|
| < Standard Header > | Y | 35 = 2 | ||
| 7 | BeginSeqNo | Y | int | MsgSeqNum (34) of first message in the range to be resent (inclusive) |
| 16 | EndSeqNo | Y | int | MsgSeqNum (34) of the last message in the range to be resent (inclusive), or "0" to request resend all messages after the indicated BeginSeqNo (7) |
| < Standard Trailer > | Y |
The expected response to a ResendRequest [2] message is a stream of application messages with PossDupFlag (43) set to "Y" (yes) in the header to indicate that this is a potentially duplicative message.
It may be appropriate in some situations for the opposite FIX engine to refuse to replay the message. This is typically the case for administrative messages which either have limited value (e.g., Heartbeat messages) or might cause confusion (e.g., Logon messages). In such circumstances, the opposite FIX engine may respond with a SequenceReset [4] message with GapFillFlag (123) set to "Y."
The SequenceReset [4] message can be used in two distinct situations:
-
To request that the counterparty adjusts their internal sequence number to the indicated NewSeqNo (36) value. In this case, GapFillFlag (123) is either not present or set to "N" (no).
-
In the message replay situation described above, to replace a FIX message which will not be resent. In this case, GapFillFlag (123) should be set to "Y" and the NewSeqNo (36) field will contain the next sequence number to be sent.
Table 7: SequenceReset [4] message
| Tag | Field Name | Req'd | Type | Comments |
|---|---|---|---|---|
| < Standard Header > | Y | 35 = 4 | ||
| 123 | GapFillFlag | N | Boolean | Indicates that this Sequence Reset is replacing administrative or application messages which will not be resent. Y = Yes N = No |
| 36 | NewSeqNo | Y | int | New sequence number |
| < Standard Trailer > | Y |
Sequence Number Cap
Since Bullish is a 24 x 7 x 365 venue without regular scheduled downtime, there is a need for a mechanism by which sequence numbers are reset on a regular basis (to avoid them growing uncontrollably).
Sequence number resets require clients to logoff and then login again using the Logon [A] message with the ResetSeqNumFlag (141) set to 'Y'. This resets the sequence numbers on both sides. Clients are free to perform this action whenever is convenient for their own schedule and set-up.
Bullish shall establish a cap to prevent sequence number counter overflow; Bullish shall send an unsolicited Logout [5] message should either the inbound or outbound sequence number reach 100,000,000.
To alert clients to an approaching threshold, the Bullish platform shall send an unsolicited News [B] message to warn them that they are reaching the maximum threshold, when they reach 1,000 messages less than the threshold. This gives the client the chance to cleanly log out (using a Logout [5]) and log back in again (Logon [A]) with the ResetSeqNumFlag (141) set to 'Y'.
Table 8: News[B] message indicating an approaching sequence number cap
| Tag | Field Name | Req'd | Type | Comments |
|---|---|---|---|---|
| < Standard Header > | Y | 35 = B | ||
| 148 | Headline | Y | String | Text to indicate that the sequence number threshold is approaching. |
| < Standard Trailer > | Y |
Figure 4: Controlled reset sequence number workflow
Multiple FIX Sessions
Each FIX connection to the Bullish platform will be assigned a unique SenderCompID (49) identifier that should be present in the Standard Header. The client can also request to use their own unique SenderCompID value.
Each Bullish client can have up to 20 FIX sessions which can be used to trade across multiple sub-accounts and shared by multiple individual traders (or trading systems).
Clients will be allowed to map multiple senderCompID 's to each institution ID.
Terminating a FIX Session
As a 24 x 7 trading platform, Bullish does not have a scheduled "end of day" like traditional markets. Participants are therefore free (and encouraged) to regularly log out and back into their FIX session at a time suitable for their trading activity. By resetting sequence numbers as a result of this action, participants may minimize the likelihood of hitting the Sequence Number Cap.
The Logout [5] message initiates or confirms the termination of a FIX session. This would typically be initiated by the Participant, but Bullish may initiate a logout in exceptional circumstances such as planned upgrades or administrative actions.
Table 9: Logout [5] message
| Tag | Field Name | Req'd | Type | Comments |
|---|---|---|---|---|
| < Standard Header > | Y | 35 = 5 | ||
| 1409 | SessionStatus | C | int | Status of the FIX session. Sent by Bullish server only. 4 = Session Logout Complete 5 = Invalid username or password 6 = Account locked 7 = Logons are not allowed at this time 8 = Password expired 101 = Logout as a result of sequence number threshold 102 = Closed due to platform halt. |
| 58 | Text | N | String | Text specifying reason for the logout. |
| < Standard Trailer > | Y |
Figure 5: Manual logout workflow
Handling FIX Errors
In the event that the Bullish platform receives a message that it can not understand or process, it shall respond with a Reject [3] message, providing details of the error.
Table 10: Reject [3] message
| Tag | Field Name | Req'd | Type | Comments |
|---|---|---|---|---|
| < Standard Header > | Y | 35 = 3 | ||
| 45 | RefSeqNum | Y | int | MsgSeqNum (34) of the rejected message. |
| 372 | RefMsgType | N | String | MsgType (35) of the rejected message. |
| 371 | RefTagID | N | String | If a message is rejected due to an issue with a particular field its tag number will be indicated. |
| 373 | SessionRejectReason | N | int | Reason for the rejection. See Error & Rejection Codes. 0 = Invalid Tag Number 1 = Required Tag Missing 2 = Tag not defined for this message type 3 = Undefined tag 4 = Tag specified without a value 5 = Value is incorrect (out of range) for this tag 6 = Incorrect data format for value 8 = Signature problem 9 = CompID problem 10 = SendingTime Accuracy Problem 11 = Invalid MsgType 13 = Tag appears more than once 14 = Tag specified out of required order 15 = Repeating group fields out of order 16 = Incorrect NumInGroup count for repeating group 99 = Other |
| 58 | Text | N | String | Text specifying the reason for the rejection. |
| < Standard Trailer > | Y |