Insights : OnixS

Applied FIX Protocol Standards

Written by Admin | Jul 14, 2020 2:09:33 PM

The Financial Information eXchange (FIX) protocol is an open electronic communications standard. It is designed to standardise and streamline electronic communications in the financial services industry supporting multiple formats and types of communications between financial entities supporting order advertisements, order submissions, order amendments, order status and trade execution reporting, and trade allocation.

FIX is predominantly considered a front office industry standard. It is also applied in middle office post-trade type business functions for trade matching and confirmations but is not currently widely used in post trade settlement processing where SWIFT and other specialist messaging standards are prevalent i.e. ISO 15022 and ISO 20022.

The core FIX protocol and family of messaging specification standards are maintained by FIX Trading Community™ - an independent non-profit, industry-driven standards body.

FIX has evolved into a family of related technical standards that include a significant number of differing use cases and numerous acronyms - so before diving into the specific FIX message standards references, syntax and enumeration formats it is worth spending some time understanding some key concepts:

  • The first key concept is that the FIX Protocol Standards are technical specifications rather than concrete implementations. The core technical implementations are known as "FIX Engines" that support the FIX Protocol session, application and encoding specifications. One of the key benefits of the FIX protocol standards used for trading are that they mandate the behaviour of the connected counterparties so that FIX Engine implementations from different providers are interoperable.

  • FIX Engine implementations support Initiator and Acceptor roles with a bi-directional stream of ordered messages between two parties within a continuous sequence number series with heartbeats, sequence gap detection, and replay recovery support.

  • The FIX Session layer provides reliable, ordered, recoverable communication between FIX counterparties. From the FIX 5.0 version the session layer was separated from the application layer.

  • FIX Transport Session Protocol (FIXT) is the application version independent session layer that is used in conjunction with FIX 5.0SP2 and later versions of FIX.

  • The FIX Performance Session Layer (FIXP) standard is a high performance, high efficiency, reliable session level protocol.

  • The FIX Application level messaging specifies the fields and messages used at an application level. It is the FIX application level messages that most developers will work with to create and consume messaging-based communications with counterparties via the APIs of the FIX Engine implementation in use.

  • It is also worth noting that the FIX messaging standards are designed to be extensible - meaning that it is common practice to add FIX tags that extend the base message standards based on bilateral or multilateral usage conventions. Such usage is usually defined in a "FIX Rules of Engagement" (FIX RoE) specification that is published by the relevant exchange, investment firm or utility for implementation by connected counterparties. Such extensions are typically known as "FIX Dictionary" FIX dialect variants that extend or specialise the base FIX messaging standards.

  • The FIX Encoding standards include commonly used implementations for "standard" FIX tag/value pairs, FIXML XML encoding, Simple Binary Encoding (SBE) and FIX Adapted for Streaming (FAST). The FIX Engine implementations will include API functionally to work with tag/value pairs as well as FIX to/from FIXML convertors, SBE Decoder/Encoders and FIX/FAST Decoder/Encoders.

Applying the FIX standards to specific business contexts can take the developer down many different paths. It is recommended to ensure a base knowledge of the context of what the FIX standards are, how they are used and in what trading contexts. With this knowledge you can then focus on the specific subset of the FIX Protocol Standards required in your target use case based on available references.

A basic FIX Engine implementation overview can be summarised like this:

The FIX Engine implementation exposes an API for developers to integrate into trading or application logic. The FIX Engine can then maintain multiple simultaneous FIX sessions with counterparties:

As already noted above the FIX Engine supports a continuous sequence number series with heartbeats, sequence gap detection, and replay recovery support for each FIX session. Meaning that the FIX session level protocol supports message recovery logic using FIXT 1.1: Resend Request <2> messages , FIXT 1.1 PossDupFlag (43) field and FIXT 1.1 Sequence Reset <4> message in gap fill or reset mode. The local FIX Engine message storage of message logs and message state enables reliable recovery – always subject to counterparty specific FIX policies. This session level recovery logic can be complex, so for now we suggest noting the above references as bookmarks to come back to when relevant.

Focusing on the FIX application level messaging, the most common (but not the only) way of presenting a FIX message is the tag-value FIX message format. In this presentation format all fields are presented as tag=value pairs and are delimited by the special <SOH> 0x01 symbol that is not visible in most standard text editors.

The following example shows the partial structure of FIX 4.4 New Order – Single <D> message in raw tag-value format:

And the same message in Hex shows the <SOH> 0X01 delimiter that can appear as a non-displayed character white space in textual editors.

And the same message in a more human readable format:

Field Name Value Description
8 BeginString FIX.4.4  
9 BodyLength 185  
35 MsgType D ORDER_SINGLE
49 SenderCompID Client  
56 TargetCompID TradingGateway  
34 MsgSeqNum 2  
52 SendingTime 20200629-09:46:25.726  
11 ClOrdID 20200629-104618-8052625  
1 Account TestAccount  
63 SettlType 0 REGULAR
21 HandlInst 1 AUTOMATED_EXECUTION_ORD ER_PRIVATE
111 MaxFloor 0  
55 Symbol MSFT  
54 Side 1 BUY
60 TransactTime 20200629-10:46:25.711  
38 OrderQty 100000  
40 OrdType 1 MARKET
15 Currency USD  
59 TimeInForce 0 DAY
10 CheckSum 114  

And to extend the example messages, an associated simulated FIX 4.4 Execution Report <8> message showing an order fill with the same views:

And the human readable view.

Field Name Value Description
8 BeginString FIX.4.4  
9 BodyLength 252  
35 MsgType 8 EXECUTION_REPORT
49 SenderCompID TradingGateway  
56 TargetCompID Client  
34 MsgSeqNum 2  
52 SendingTime 20200629-09:46:26.116  
37 OrderID OrderID_104626  
11 CIOrdID 20200629-104618-8052625  
17 ExecID ExecID_1  
150 ExecType 0 NEW
39 OrdStatus 0 NEW
1 Account TestAccount  
63 SettlType 0 REGULAR
55 Symbol MSFT  
54 Side 1 BUY
38 OrderQty 100000  
40 OrdType 1 MARKET
15 Currency USD  
59 TimeInForce 0 DAY
32 LastQty 0  
31 LastPx 0  
151 LeavesQty 100000  
14 CumQty 0  
6 AvgPx 0  
60 TransactTime 20200629-10:46:26  
21 HandlInst 1 AUTOMATED_EXECUTION_ORD ER_PRIVATE
111 MaxFloor 0

 

10 CheckSum 144

 

The above examples used the standard OnixS .NET FIX Engine Trading Client and Exchange Emulator samples. For illustration of how the associated FIX New Order Single message was generated, this is the OnixS FIX Engine API reference implementation sample code snippet:

C#/.NET Framework and .NET Core FIX Engine SendNewOrder code sample:

public void SendNewOrder(Order order)
    {
        Message message = new Message(MsgType.NewOrderSingle, session.Version);
        message[Tag.ClOrdID] = order.ClientOrderID; message[Tag.HandlInst] = HandlInst.AutomatedExecutionOrderPrivateNoBrokerIntervention;
        message[Tag.Symbol] = order.Symbol;
        message.Set(Tag.Side, (int)order.Side);
        message[Tag.TransactTime] = order.TransactTime.ToString("yyyyMMdd-HH:mm:ss.fff", CultureInfo.InvariantCulture);
        message.Set(Tag.OrdType, Char.ToString((char)order.Type));

        if (Order.OrderType.Market != order.Type && Order.OrderType.ForeignExchangeMarketOrder != order.Type )
        {
            message.Set(Tag.Price, order.Price);
        }

        message.Set(Tag.OrderQty, order.Quantity);

        if (!string.IsNullOrEmpty(order.Currency))
        {
            message.Set(Tag.Currency, order.Currency);
        }

        message.Set(Tag.MaxFloor, 0);
        message.Set(Tag.TimeInForce, TimeInForce.DayOrSession);

        if (session.Version < ProtocolVersion.Fix43)
        {
            message.Set(OnixS.Fix.Fix43.Tag.SettlmntTyp, OnixS.Fix.Fix43.SettlmntTyp.Regular); message.Set(OnixS.Fix.Fix43.Tag.Rule80A, OnixS.Fix.Fix43.Rule80A.Individual_Investor_single_order);
        }

        if (!string.IsNullOrEmpty(settings.Account))
        {
            message[Tag.Account] = settings.Account;
        }

        if (!string.IsNullOrEmpty(order.SecurityID))
        {
            message[Tag.SecurityID] = order.SecurityID;
        }

        if (!string.IsNullOrEmpty(order.Text))
        {
            message[Tag.Text] = order.Text;
        }

        orderBook.AddOrder(order);
        session.Send(message);
    }

And a C++ SendNewOrder code snippet from the OnixS FIX Engine C++ SDK implementation:

void setOrderFields(Message * order)
{
    order->set(Tags::HandlInst, HandlInst::Automated_execution_order_private_no_Broker_intervention);
    order->set(Tags::ClOrdID, "Unique identifier for Order");
    order->set(Tags::Symbol, "IBM");
    order->set(Tags::Side, Side::Buy);
    order->set(Tags::OrderQty, 1000);
    order->set(Tags::OrdType, OrdType::Market);
    order->set(Tags::TransactTime, Timestamp::utc(), TimestampFormat::YYYYMMDDHHMMSSMsec);
}

And the SendNewOrder code snippet from the OnixS FIX Engine Java SDK implementation:

private Message createOrder() {
    final Message order = Message.create(FIX40.MsgType.Order_Single, fixVersion);
    order.set(Tag.HandlInst, "1");
    order.set(Tag.ClOrdID, "Unique identifier for Order");
    order.set(Tag.Symbol, "IBM");
    order.set(Tag.Side, "1");
    order.set(Tag.OrderQty, 1000);
    order.set(Tag.OrdType, "1");
    return order;
}

These are based on the reference implementation source code samples included in the OnixS FIX Engine SDK software distributions. These source code samples are designed to be ready-to-run fast-start source code samples for developers to review, execute, understand API usage and then adapt to the required context.

In this specific context, reference the OnixS FIX Engine NET Framework, .NET Core, C++ and Java implementation online Programming Guides provides much more detailed reference on OnixS SDK API usage for the specific target platform in use.

Rather than repeat the content of available online FIX references, it is suggested to bookmark those that are relevant to the problem in hand. There are a number of excellent online references available and the various Search Engines are your friend here. Our suggested reference bookmarking list is:

  • The FIX Wikipedia entry is not particularly technically useful, but is a useful reference for introductory concepts.

  • Even for experienced FIX developers, reference to the OnixS FIX data dictionary saves much time and effort for any deep dive into the specific FIX message standards syntax in tag/value and enumeration formats.

  • Do you need to analyse FIX messaging interactions in human readable format by analysing FIX Engine message log files? The OnixS FIX Analyser is a high performance FIX log file analysis tool supporting queries, validation, monitoring of FIX standards and dialects designed to save time and money in developing and supporting FIX based trading infrastructures.