Click here to Skip to main content
15,881,757 members
Articles / Programming Languages / C#

Implementation of FIX messages for Fix 5.0 sp2 and FIXT1.1 specification

Rate me:
Please Sign up or sign in to vote.
4.50/5 (4 votes)
30 Aug 2012CPOL2 min read 27.9K   3  
This post will demonstrate how to connect with FIX5.0 server and FIXT1.1 specification and uses of QuickFix/n (native .NET FIX engine).

This post will demonstrate how to connect with FIX5.0 server and FIXT1.1 specification and uses of QuickFix/n (native .NET FIX engine).

Introduction

With this release of FIX protocol version 5.0, a new Transport Independence framework (TI) introduced which separates the FIX Session Protocol from the FIX Application Protocol. This gives freedom to send message across different messaging technologies like MSMQ, message bus etc.

Because of different versions of transport and application protocol, we will have to explicitly defines settings in config file.

TransportDataDictionary is used for defining transport protocol version eg. FIXT.1.1.xml

AppDataDictionary is used for defining data dictionary for FIX application protocol version eg. FIX50.xml

You can read more about FIXT1.1 and FIX 5.0 Sp2 specification on fixprotocol.org.

http://fixprotocol.org/specifications/FIXT.1.1

http://fixprotocol.org/specifications/FIX.5.0

QuickFix/N

To demonstrate implementation of FIX 5.0 sp2, I’ll use open source FIX engine for .net (QuickFix/N) which is one of best open source engine in native .NET code. Code for quickfix.net is available on github and primarily contributed by Connamara System’s developers. These guys are doing commendable job.

Implementation

FixInitiator

This is client application which will connect with FIX server to send and receive FIX messages. I am demonstrating implementation of MarketDataRequest and its responses (MarketDataSnapshot & MarketDataIncrementalRefresh).

Start with Configuration

First we create configuration file for initiator.

[default] 
PersistMessages=Y 
ConnectionType=initiator 
UseDataDictionary=Y
[SESSION] 
ConnectionType=initiator 
FileStorePath=store 
FileLogPath=fixlog 
BeginString=FIXT.1.1 
DefaultApplVerID=FIX.5.0
TransportDataDictionary=FIXT.1.1.xml 
AppDataDictionary=FIX50.xml 
SenderCompID=ABC 
TargetCompID=FIXSERVER 
SocketConnectHost=127.0.0.1 
SocketConnectPort=3500 
HeartBtInt=20 
ReconnectInterval=30 
ResetOnLogon=Y 
ResetOnLogout=Y 
ResetOnDisconnect=Y

*Note- AppDataDictionary is for application protocol eg. FIX 5.0 and TransportDataDictionary is for transport protocol.

You can read more about configuration here.

Create Application Class

Before starting with implementation you would need to have quickFix.dll which is available of github  at https://github.com/connamara/quickfixn

To connect with FIX session, you will have to implement QuickFix.Application interface.

C++
public interface Application 
{ 
   void FromAdmin(Message message, SessionID sessionID); 
   void FromApp(Message message, SessionID sessionID); 
   void OnCreate(SessionID sessionID); 
   void OnLogon(SessionID sessionID); 
   void OnLogout(SessionID sessionID); 
   void ToAdmin(Message message, SessionID sessionID); 
   void ToApp(Message message, SessionID sessionId); 
}

I create one class named FixClient50Sp2 which implements interface and inherit base class for message cracking and getting message events.

image

FIX Application Setup

Setting up Initiator

C++
// FIX app settings and related 
var settings = new SessionSettings("C:\\initiator.cfg");
// FIX application setup 
MessageStoreFactory storeFactory = new FileStoreFactory(settings); 
LogFactory logFactory = new FileLogFactory(settings); 
_client = new FixClient50Sp2(settings);
IInitiator initiator = new SocketInitiator(_client, storeFactory, settings, logFactory); 
_client.Initiator = initiator;

* _client is an instance of the class FixClient50Sp2.

Starting Initiator

C++
_client.Start();

Implementation of QuickFix.Application Interface methods

C++
/// <summary> 
/// every inbound admin level message will pass through this method, 
/// such as heartbeats, logons, and logouts. 
/// </summary> 
/// <param name="message"></param> 
/// <param name="sessionId"></param> 
public void FromAdmin(Message message, SessionID sessionId) 
{ 
    Log(message.ToString()); 
}
/// <summary> 
/// every inbound application level message will pass through this method, 
/// such as orders, executions, secutiry definitions, and market data. 
/// </summary> 
/// <param name="message"></param> 
/// <param name="sessionID"></param> 
public void FromApp(Message message, SessionID sessionID) 
{ 
    Trace.WriteLine("## FromApp: " + message);
    Crack(message, sessionID); 
}
/// <summary> 
/// this method is called whenever a new session is created. 
/// </summary> 
/// <param name="sessionID"></param> 
public void OnCreate(SessionID sessionID) 
{ 
    if (OnProgress != null) 
        Log(string.Format("Session {0} created", sessionID)); 
}
/// <summary> 
/// notifies when a successful logon has completed. 
/// </summary> 
/// <param name="sessionID"></param> 
public void OnLogon(SessionID sessionID) 
{ 
    ActiveSessionId = sessionID; 
    Trace.WriteLine(String.Format("==OnLogon: {0}==", ActiveSessionId));
    if (LogonEvent != null) 
        LogonEvent(); 
}
/// <summary> 
/// notifies when a session is offline – either from 
/// an exchange of logout messages or network connectivity loss. 
/// </summary> 
/// <param name="sessionID"></param> 
public void OnLogout(SessionID sessionID) 
{ 
    // not sure how ActiveSessionID could ever be null, but it happened. 
    string a = (ActiveSessionId == null) ? "null" : ActiveSessionId.ToString(); 
    Trace.WriteLine(String.Format("==OnLogout: {0}==", a));
    if (LogoutEvent != null) 
        LogoutEvent(); 
}
/// <summary> 
/// all outbound admin level messages pass through this callback. 
/// </summary> 
/// <param name="message"></param> 
/// <param name="sessionID"></param> 
public void ToAdmin(Message message, SessionID sessionID) 
{ 
    Log("To Admin : " + message); 
}
/// <summary> 
/// all outbound application level messages pass through this callback before they are sent. 
/// If a tag needs to be added to every outgoing message, this is a good place to do that. 
/// </summary> 
/// <param name="message"></param> 
/// <param name="sessionId"></param> 
public void ToApp(Message message, SessionID sessionId) 
{ 
    Log("To App : " + message); 
}

Callback to Subscription

C++
public void OnMessage(MarketDataIncrementalRefresh message, SessionID session) 
{ 
    var noMdEntries = message.NoMDEntries; 
    var listOfMdEntries = noMdEntries.getValue(); 
    //message.GetGroup(1, noMdEntries); 
    var group = new MarketDataIncrementalRefresh.NoMDEntriesGroup();
    Group gr = message.GetGroup(1, group);
    string sym = message.MDReqID.getValue();
    var price = new MarketPrice();
    for (int i = 1; i <= listOfMdEntries; i++) 
    { 
        group = (MarketDataIncrementalRefresh.NoMDEntriesGroup)message.GetGroup(i, group);
        price.Symbol = group.Symbol.getValue();
        MDEntryType mdentrytype = group.MDEntryType;
        if (mdentrytype.getValue() == ’0′) //bid 
        { 
            decimal px = group.MDEntryPx.getValue(); 
            price.Bid = px; 
        } 
        else if (mdentrytype.getValue() == ’1′) //offer 
        { 
            decimal px = group.MDEntryPx.getValue(); 
            price.Offer = px; 
        }
        price.Date = Constants.AdjustedCurrentUTCDate.ToString("yyyyMMdd"); 
        price.Time = group.MDEntryTime.ToString(); 
    }
    if (OnMarketDataIncrementalRefresh != null) 
    { 
        OnMarketDataIncrementalRefresh(price); 
    } 
}

Code can be found at github.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Saxo Bank A/S
Denmark Denmark
• Solution Architect /Principle Lead Developer with 12 years of IT experience with more emphasize on Capital Domain and Investment banking domain.
• Strong experience in Continuous Integration, Delivery and DevOps solutions.
• Strong experience in drafting solutions, stakeholder communications and risk management.
• Proved strong coding and designing skills with agile approaches (TDD, XP framework, Pair Programming).
• Delivered many projects with involvement from inception to delivery phase.
• Strong experience in high performance, multithreaded, low latency applications.
• Ability to communicate with the business and technical stake holders effectively.
• Have extensive experience in Capital Market Domain: Front Office & BackOffice (Algorithm Trading tools, messaging framework, Enterprise bus, integration of FIX APIs and many trading APIs).
• Functional knowledge of Portfolio/Wealth Management, Equities, Fixed Income, Derivatives, Forex.
• Practical knowledge of building and practicing agile delivery methodologies (SCRUM, TDD, Kanban).

Technical Skills

• Architectural: Solution Design, Architectural Presentations (Logical, Component, Physical, UML diagrams)
• Languages: C#, C++
• Server Technologies: WCF, Web API,
• Middle Ware: ActiveMQ, RabbitMQ, Enterprise Service Bus
• UI Technologies: Winforms and WPF
• Web Technologies: Asp.Net Mvc, KnockOutJS, JQuery, Advance Java Scripts Concepts
• Databases: Sql Server 2008 +, MySQL
• Tools/Frameworks: TFS, SVN, NUnit, Rhino Mocks, Unity, NAnt, QuickFix/n, Nhibernate, LINQ, JIRA,

Functional Skills

• Wealth Management System, Trade Life Cycle, Trading Components and their integrations
• Working knowledge of Stocks, Bonds, CFDs,Forex, Futures and Options
• Pricing Systems, Market Data Management,
• BackOffice Processes : Settlement Processes, Netting, Tax, Commissions, Corporate Actions Handling,
• Reporting Solutions : OLTP and OLAP Data model designing
• FIX Engine implementation and integration

Comments and Discussions

 
-- There are no messages in this forum --