FIX Protocol
FIX Implementation Details
Overview
This document describes the Financial Information Exchange (FIX) implementation of the Bakkt order execution protocol. FIX provides an open standard that leverages the development and production efforts of securities transactions and standardizes requirements for accuracy and consistency. NOTE: Messages are in FIX 4.2 format (any exceptions are noted).
Table of Contents
Maintenance Window
Bakkt sessions reset daily following a maintenance window when the system is offline. The maintenance window runs from 4:30PM-5:05PM CT, but after some time clients can request to remove this maintenance window to be once a month.
Gateway Messages
After establishing and testing the FIX Gateway Bakkt and the client communicate via session and application messages. Bakkt sends clients the application message configurations during the technical integration process. These messages include the following:
- NewOrderSingle - Clients submit investor cryptocurrency orders via this message. Clients can submit orders on any tradeable cryptocurrency symbol via a single session. Bakkt only supports market orders via this message.
- Execution Report - This is how order acknowledgements are communicated from Bakkt to the client along with any cancels, rejects, or order fills for clients' investors.
- OrderCancelRequest - Clients submit order cancellations using this message.
- OrderCancelReject - If Bakkt does not accept an order, or if there are insufficient funds to reconcile a cryptocurrency purchase, this message contains the order cancellation details.
Data Types
Data types are the attributes that Bakkt uses to interpret data in a consistent format with correct values so that each attribute performs as expected. Bakkt supports the following data types in its FIX implementation. NOTE: ASCII stands for American Standard Code for Information Interchange and provides the numerical representation of characters for formatting purposes.
Type | Description |
---|---|
Int | Signed 64-bit capacity integer (consists of ASCII characters '-' and '0' - '9'); only the first character can be a minus sign if the integer value is negative; leading zeroes are allowed but not spaces |
Float | Signed decimal value (consists of ASCII characters '-', '.' and '0' - '9'); only the first character may be a minus sign if the decimal value is negative; leading zeroes are allowed; users may omit trailing zeroes after the decimal point or leading zeroes before the decimal point (supports up to nine decimal places and 16 significant digits) |
Char | Single character of any alphanumeric value except the delimiter (ASCII 1-SOH); values are case-sensitive |
Boolean | A char field containing only 'Y' or 'N' (for Yes or No) |
String | A sequence of one or more characters consisting of any alphanumeric value except the delimiter |
Date | Calendar date represented in YYYYMMDD format (e.g., 20221103) |
Utctimestamp | Date/Time combination represented in UTC/GMT with millisecond precision using the format YYYYMMDD-HH-MM-SS.sss |
Message Headers and Trailers
The following definitions provide information for standard FIX headers and trailers that clients send to Bakkt. NOTE: The SenderCompID
and TargetCompID
field values switch for messages that go from Bakkt to clients.
Standard Message Header
Tag | Field Name | Type | Definition | Optional/Required |
---|---|---|---|---|
8 | BeginString | String | For FIX 4.2 the must be the first field in the message | Required |
9 | BodyLength | Int | Message length (in bytes) and must be the second field in the message; Bakkt rejects messages that are more than 2048 bytes in length | Required |
35 | MsgType | String | The type of FIX message | Required |
34 | MsgSeqNum | Int | The session sequence number; starts at 1 every day following the maintenance window | Required |
49 | SenderCompID | String | The Bakkt-provided session endpoint identifier bound to a specific legal entity | Required |
52 | SendingTime | Utctimestamp | UTC/GMT with millisecond precision | Required |
56 | TargetCompID | String | Must always be the string AC for Bakkt | Required |
Standard Message Trailer
Tag | Field Name | Type | Definition | Optional/Required |
---|---|---|---|---|
10 | CheckSum | Int | Three-character integer of all characters in the message up to and including the delimiter preceding the CheckSum field | Required |
Session Messages
Bakkt supports the following messages to establish, maintain, and terminate a client connection.
Message | Description |
---|---|
Logon | Clients initiate a Logon with the Bakkt-provided username and password fields. Clients cannot reset sequence numbers as part of the Logon process. Heartbeats must be in the range of five to 60 seconds. Clients must logon with a MsgSeqNum of 1 following the maintenance window. |
Logout | Clients may initiate a Logout any time. Bakkt then acknowledges the initiation with a Logout of its own. Bakkt may issue a Logout followed by a disconnect in the following situations: – Receiving a message (including a Logon) with a MsgSeqNum that is too low – Failing to parse messages due to invalid BeginString, BodyLength, CheckSum or for bad data formatting, missing delimiters, or unsupported tag – Invalid HeartBtInt, Password, or EncryptMethod during Logon |
Heartbeat/TestRequest | Bakkt issues heartbeats (i.e., systematic connection tests) periodically during periods of inactivity to ensure connection integrity. Bakkt issues clients a TestRequest message if it does not receive an update within the heartbeat interval plus 100 milliseconds; it terminates the connection if it still does not receive a response within another heartbeat interval. |
Session Level Reject | Bakkt issues a Session Level Reject when it receives a message, but the Application level cannot process it. The reasons for issuing a Session Level Reject include: – Unexpected or invalid MsgType post Logon – Missing required fields/tags. |
Resend Request | Both the client and Bakkt can issue this message as part of initialization or to recover lost messages mid-stream. |
Sequence Reset | Both the client and Bakkt can issue this message as part of the message recovery process. Bakkt only supports GapFill sequence resets. |
Logon
See the following definitions of Logon submitted by the client to Bakkt. If successful, Bakkt responds with a Logon acknowledgement with the password omitted. NOTE: The asterisk (*) indicates user-defined fields from FIX 4.4.
Tag | Field Name | Type | Definition | Optional/Required |
---|---|---|---|---|
Standard Header | MsgType = A | Required | ||
98 | EncryptMethod | Int | Must always be 0 ; corresponds to "no encryption" | Required |
108 | HeartbeatInt | Int | Must be between five and 60 seconds | Required |
*553 | Username | String | Bakkt-provided username for this session; required on Logon; submitted by the client | Required |
*554 | Password | String | Bakkt-provided password for this session; required on Logon; submitted by the client | Required |
Standard Trailer | Required |
Logout
Tag | Field Name | Type | Definition | Optional/Required |
---|---|---|---|---|
Standard Header | MsgType = 5 | Required | ||
58 | Text | String | Free form text for logout | Optional |
Standard Trailer | Required |
Heartbeat
Tag | Field Name | Type | Definition | Optional/Required |
---|---|---|---|---|
Standard Header | MsgType = 0 | Required | ||
112 | TestReqID | String | Required if sending a heartbeat in response to a TestRequest | Required |
Standard Trailer | Required |
TestRequest
Tag | Field Name | Type | Definition | Optional/Required |
---|---|---|---|---|
Standard Header | MsgType = 1 | Required | ||
112 | TestReqID | String | Identifier set by initiator | Required |
Standard Trailer | Required |
ResendRequest
Tag | Field Name | Type | Definition | Optional/Required |
---|---|---|---|---|
Standard Header | MsgType = 2 | Required | ||
7 | BeginSeqNo | Int | Sequence number of first message to recover; use this value in Tag 34 (MsgSeqNum ) of the first resent message | Required |
16 | EndSeqNo | Int | Sequence number of last message in the range to resend; use this value in Tag 34 (MsgSeqNum ) of the last message; if the request is for a single message, then Tag 7 (BeginSeqNo ) must equal Tag 16 (EndSeqNo )For each resend request, the Bakkt system does not allow the client system to request more than 10,000 messages; in response to the resend request from the client system, Bakkt sends all messages for the requested range up to the last 10,000 messages | Required |
Standard Trailer | Required |
Sequence Reset
Tag | Field Name | Type | Definition | Optional/Required |
---|---|---|---|---|
Standard Header | MsgType = 4 | Required | ||
123 | GapFillFlag | Boolean | Must be ‘Y’; Bakkt does not support sequence number resets | Required |
36 | NewSeqNo | Int | Sequence number of next message to send | Required |
Standard Trailer | Required |
Session Level Reject
Tag | Field Name | Type | Definition | Optional/Required |
---|---|---|---|---|
Standard Header | MsgType = 3 | Required | ||
45 | RefSeqNum | Int | The sequence number of the received message that triggers the rejection | Required |
58 | Text | String | A message explaining the rejection reason | Optional |
371 | RefTagID | Int | The tag number of the problem field in the received message that triggers the rejection | Optional |
372 | RefMsgType | String | The MsgType of the received message that triggers the reject | Optional |
373 | SessionRejectReason | Int | A code indicating the reason for the rejection | Optional |
Standard Trailer | Required |
Business Level Reject
The system rejects messages as Business Level Rejects when they are missing conditionally required fields.
Tag | Field Name | Type | Definition | Optional/Required |
---|---|---|---|---|
Standard Header | MsgType = j | Required | ||
45 | RefSeqNum | Int | The sequence number of received message that triggers the rejection | Optional |
58 | Text | String | A message explaining the reason for the rejection | Optional |
372 | RefMsgType | String | MsgType of the received message that triggers the rejection | Required |
380 | BusinessRejectReason | String | A code indicating the reason for the rejection | Required |
Standard Trailer | Required |
Application Messages
The Bakkt system sends clients the following application message configurations for order execution sessions during the technical integration process.
Message | Description |
---|---|
NewOrderSingle | Clients submit investor cryptocurrency and NFT orders via this message. Clients can submit orders on any tradeable symbol via a single session. The Bakkt system supports market and limit orders via this message. |
Execution Report | This message includes the order acknowledgement from the Bakkt system to the client along with any cancels, rejects, or order fills for clients' investors. |
OrderCancelRequest | Clients submit order cancellations using this message. |
OrderCancelReject | If the Bakkt system does not accept an order, or if there are insufficient funds to reconcile a cryptocurrency purchase, this message contains the order cancellation details. |
NewOrderSingle
Clients submit NewOrderSingle messages to Bakkt. The system allows clients to quote cryptocurrency orders in two ways:
- Notional – Use Tag 152 in the
CashOrderQty
field (e.g., the customer buys $100 of BTCUSD by entering100
for Tag 152 in theCashOrderQty
field) - Absolute – Use Tag 38 in the
OrderQty
field (e.g., the customer sells .05 BTCUSD by entering.05
for Tag 38 in the OrderQty field)
NOTE: The asterisk (*) indicates a conditionally-required field.
Tag | Field Name | Type | Definition | Optional/Required |
---|---|---|---|---|
Standard Header | MsgType = D | Required | ||
1 | Account | String | The Bakkt client account identifier (e.g., ABC12345) | Required |
11 | ClOrdID | String | The client-specified unique order identifier; The ClOrdID must not exceed 64 characters in length | Required |
15 | Currency | String | For NFT sell orders, the currency of Price (must be the same as the NFT's native cryptocurrency); for NFT buy orders, the currency is implicitly USD, so do not specify this field | *Optional |
21 | HandlInst | Char | Must always be '1' (for automatic execution, private, and no broker) | Required |
55 | Symbol | String | The Bakkt-tradeable symbol identifier | Required |
54 | Side | Char | The market side of the order; acceptable values include '1' (for Buy) and '2' (for Sell) | Required |
44 | Price | Float | This field is for the price (e.g., “23.0”=”23.0000”=”23”); all float fields must accommodate up to fifteen significant digits | Required |
38 | OrderQty | Float | The order size in number of product units; Bakkt requires either OrderQty<3> or CashOrderQty<152> | *Optional |
40 | OrdType | Char | The type of order (market or limit); acceptable values are:1 (Market Order)2 (Limit Order) | Required |
59 | TimeInForce | Char | Time-in-Force is the life expectancy of an order; the platform currently supports the following:0 (Day)1 (Good til Cancel)3 (Immediate or Cancel) | Required |
60 | TransactTime | Utctimestamp | The UTC/GMT time that the source system submits the order in millisecond precision | Required |
152 | CashOrderQty | Float | The order size quoted as a notional cash quantity; Bakkt requires either OrderQty<3> or CashOrderQty<152> | *Optional |
Standard Trailer | Required |
Order Cancel Request
This message requests the cancellation of an order.
Tag | Field Name | Type | Definition | Optional/Required |
---|---|---|---|---|
Standard Header | MsgType = F | Required | ||
41 | OrigClOrdID | String | The client-specified unique order identifier | Required |
11 | ClOrdID | String | The client-specified unique cancel request identifier | Required |
37 | OrderID | String | The Bakkt-generated order identifier returned in the acknowledgement | Required |
55 | Symbol | String | The Bakkt-tradeable symbol identifier from NewOrderSingle | Required |
54 | Side | Char | The market side of original order per NewOrderSingle; acceptable values include '1' (for Buy) and '2' (for Sell) | Required |
60 | TransactTime | Utctimestamp | The time the client generates the cancel request | Required |
Standard Trailer | Required |
Order Cancel Reject
Bakkt may reject a cancel request by responding to the Order Cancel Request with an Order Cancel Reject message.
Tag | Field Name | Type | Definition | Optional/Required |
---|---|---|---|---|
Standard Header | MsgType = 9 | Required | ||
41 | OrigClOrdID | String | The ClOrdID of the order to cancel | Required |
11 | ClOrdID | String | The client-specified unique cancel request identifier | Required |
37 | OrderID | String | The Bakkt-generated order identifier returned in the acknowledgment | Required |
39 | OrdStatus | Char | The current status of the order | Required |
58 | Text | String | This field offers text explaining the rejection | Required |
60 | TransactTime | Utctimestamp | The time that Bakkt generates the rejection of the order cancellation request | Required |
Standard Trailer | Required |
Updated 6 months ago