Click here to Skip to main content
Click here to Skip to main content

Fix Message Implementation using QuickFix

By , 6 Sep 2011
 

Purpose

The purpose of this document is to give brief details about FIX and basic implementation of messages using QuickFix .NET library.

First of all, we need to know what is FIX protocol.

What is FIX Protocol?

It is a series of messaging specifications for the electronic communication of trade-related messages. It has been developed through the collaboration of banks, broker-dealers, exchanges, industry utilities and associations, institutional investors, and information technology providers from around the world. These market participants share a vision of a common, global language for the automated trading of financial instruments.

Most of the exchanges use this standard for communication like sending Order, Executions, MarketData, etc. There are many versions of specifications released by FIX organization like 4.0, 4.2, 5.0, etc.

You can read more about FIX on http://www.fixprotocol.org.

What is QuickFix?

QuickFIX is a free and open source implementation of the FIX protocol in various languages like C++, Java, ruby, .NET, etc.

So let’s start with implementation of Fix Messages. I am going to create two applications, server and client which we call as FixAcceptor and FixInitiator respectively.

Implementation with C#

To use QuickFix engine, we’ll need two DLLs quickfix_net.dll and quickfix_net_message.dll which can be downloaded from QuickFix website.

I created one solution which has two projects FixAcceptor and FixInitiator. FixAcceptor is active as server and FixInitiator is client app.

FixAcceptor

To start FixAcceptor, we need to configure and configurations are put into acceptor.cfg which should be pretty straight forward configurations like below:

[DEFAULT]
ConnectionType=acceptor
SocketAcceptPort=5001
SocketReuseAddress=Y
StartTime=00:00:00
EndTime=00:00:00
FileLogPath=log
FileStorePath=c:\fixfiles
[SESSION]
BeginString=FIX.4.2
SenderCompID=EXECUTOR
TargetCompID=CLIENT1
DataDictionary=c:\user\nek\Code\FIX test App\data Dictionary\FIX42.xml
  • Connection type tells this application will run as Acceptor which is server.
  • SocketAcceptPort: listening port.
  • Session tag: is having configuration for creating session between client application (initiator) and acceptor.
  • BegingString: This sets session will work on which Fix Message specification.
  • SenderCompID: Id of server which will listen and send messages.
  • TargetCompID=Id of client to which server will send messages.
  • DataDictionary: Path of data dictionary file which is XML format, this file has message specifications according to various specifications versions.

Source Code

To start any session with Fix, we need to create Class which should implement QuickFix.Application interface. It has the following methods to be implemented:

public interface Application 
{ 
void fromAdmin(Message __p1, SessionID __p2); 
void fromApp(Message __p1, SessionID __p2); 
void onCreate(SessionID __p1); 
void onLogon(SessionID __p1); 
void onLogout(SessionID __p1); 
void toAdmin(Message __p1, SessionID __p2); 
void toApp(Message __p1, SessionID __p2); 
} 

public override void onMessage(QuickFix42.NewOrderSingle order, SessionID sessionID) 
{ 
Symbol symbol = new Symbol(); 
Side side = new Side(); 
OrdType ordType = new OrdType(); 
OrderQty orderQty = new OrderQty(); 
Price price = new Price(); 
ClOrdID clOrdID = new ClOrdID(); 
order.get(ordType); 
if (ordType.getValue() != OrdType.LIMIT) 
throw new IncorrectTagValue(ordType.getField()); 
order.get(symbol); 
order.get(side); 
order.get(orderQty); 
order.get(price); 
order.get(clOrdID); 
QuickFix42.ExecutionReport executionReport = new QuickFix42.ExecutionReport 
(genOrderID(), 
genExecID(), 
new ExecTransType(ExecTransType.NEW), 
new ExecType(ExecType.FILL), 
new OrdStatus(OrdStatus.FILLED), 
symbol, 
side, 
new LeavesQty(0), 
new CumQty(orderQty.getValue()), 
new AvgPx(price.getValue())); 
executionReport.set(clOrdID); 
executionReport.set(orderQty); 
executionReport.set(new LastShares(orderQty.getValue())); 
executionReport.set(new LastPx(price.getValue())); 
if (order.isSetAccount()) 
executionReport.set(order.getAccount()); 
try 
{ 
Session.sendToTarget(executionReport, sessionID); 
} 
catch (SessionNotFound) { } 
}
Session.sendToTarget(executionReport, sessionID);

The above statement sends executionReport object to session which is built between client and server.

Start FixAcceptor Application

[STAThread]
static void Main(string[] args)
{
SessionSettings settings = new SessionSettings(@"acceptor.cfg");
FixServerApplication application = new FixServerApplication();
FileStoreFactory storeFactory = new FileStoreFactory(settings);
ScreenLogFactory logFactory = new ScreenLogFactory(settings);
MessageFactory messageFactory = new DefaultMessageFactory();
SocketAcceptor acceptor
= new SocketAcceptor(application, storeFactory, settings, logFactory, messageFactory);
acceptor.start();
Console.WriteLine("press <enter> to quit");
Console.Read();

acceptor.stop();
}

Steps

  1. Create SessionSettings object with config file.
  2. Create object of Application class.
  3. Create Object of SocketAcceptor class by passing SessionSettings.
  4. Run Start method of acceptor object.

Start FixInitiator

To start FixAcceptor, we need to configure and configurations are put into acceptor.cfg which should be pretty straight forward configurations like below:

[DEFAULT]
ConnectionType=initiator
HeartBtInt=30
ReconnectInterval=1
FileStorePath=c:\fixfiles
FileLogPath=log
StartTime=00:00:00
EndTime=00:00:00
UseDataDictionary=N
SocketConnectHost=localhost
[SESSION]
BeginString=FIX.4.2
SenderCompID=CLIENT1
TargetCompID=FixServer
SocketConnectPort=5001
  • Connection type tells this application will run as Acceptor which is server.
  • SocketAcceptPort: listening port.
  • Session tag: is having configuration for creating session between client application (initiator) and acceptor.
  • BeginString: this sets session will work on which Fix Message specification
  • SenderCompID: Id of client which will send messages
  • TargetCompID: Id of server to which server will listen messages
  • DataDictionary: Path of data dictionary file which is xml format, this file is having message specifications according to various specifications versions.

Source Code

To start any session with Fix, we need to create class which should implement QuickFix.Application interface.

public class ClientInitiator : QuickFix.Application 
{ 
public void onCreate(QuickFix.SessionID value) 
{ 
//Console.WriteLine("Message OnCreate" + value.toString()); 
} 
public void onLogon(QuickFix.SessionID value) 
{ 
//Console.WriteLine("OnLogon" + value.toString()); 
} 
public void onLogout(QuickFix.SessionID value) 
{ 
// Console.WriteLine("Log out Session" + value.toString()); 
} 
public void toAdmin(QuickFix.Message value, QuickFix.SessionID session) 
{ 
//Console.WriteLine("Called Admin :" + value.ToString()); 
} 
public void toApp(QuickFix.Message value, QuickFix.SessionID session) 
{ 
// Console.WriteLine("Called toApp :" + value.ToString()); 
} 
public void fromAdmin(QuickFix.Message value, SessionID session) 
{ 
// Console.WriteLine("Got message from Admin" + value.ToString()); 
} 
public void fromApp(QuickFix.Message value, SessionID session) 
{ 
if (value is QuickFix42.ExecutionReport) 
{ 
QuickFix42.ExecutionReport er = (QuickFix42.ExecutionReport)value; 
ExecType et = (ExecType)er.getExecType(); 
if (et.getValue() == ExecType.FILL) 
{ 
//TODO: implement code 
} 
} 
Console.WriteLine("Got message from App" + value.ToString()); 
} 

} 
/// <summary> 
/// The main entry point for the application. 
/// </summary> 
//[STAThread] 
static void Main() 
{ 
ClientInitiator app = new ClientInitiator(); 
SessionSettings settings = new SessionSettings(
    @"c:\users\nek\Code\FIX test App\initiator.cfg"); 
QuickFix.Application application = new ClientInitiator(); 
FileStoreFactory storeFactory = new FileStoreFactory(settings); 
ScreenLogFactory logFactory = new ScreenLogFactory(settings); 
MessageFactory messageFactory = new DefaultMessageFactory(); 
SocketInitiator initiator = new SocketInitiator(application, storeFactory, settings, 
    logFactory, messageFactory); 
initiator.start(); 
Thread.Sleep(3000); 
SessionID sessionID = (SessionID)list[0]; 
QuickFix42.NewOrderSingle order = new QuickFix42.NewOrderSingle(new ClOrdID("DLF"), 
    new HandlInst(HandlInst.MANUAL_ORDER), new Symbol("DLF"), new Side(Side.BUY), 
    new TransactTime(DateTime.Now), new OrdType(OrdType.LIMIT)); 
order.set(new OrderQty(45)); 
order.set(new Price(25.4d)); 
Session.sendToTarget(order, sessionID); 
Console.ReadLine(); 
initiator.stop(); 
}

Steps

  1. Create application class object, i.e., ClientInitiator.
  2. Create object of SessionSettings class.
  3. Create SocketInitiator class.
  4. Run Start method.
  5. Create session id.

How to Send Order

Create order object of NewOrderSingle class. Set type of order, symbol, side, etc., and send order by SendToTarget method.

Receive Order Notification in Client

You can receive sent order acknowledgement in FromApp method in application class.

Start Application

QuickFix42.NewOrderSingle order = new QuickFix42.NewOrderSingle(new ClOrdID("DLF"), 
    new HandlInst(HandlInst.MANUAL_ORDER), new Symbol("DLF"), new Side(Side.BUY), 
    new TransactTime(DateTime.Now), new OrdType(OrdType.LIMIT));

order.set(new OrderQty(45));

order.set(new Price(25.4d));

Session.sendToTarget(order, sessionID); 
public void fromApp(QuickFix.Message value, SessionID session)
{
if (value is QuickFix42.ExecutionReport)
{
QuickFix42.ExecutionReport er = (QuickFix42.ExecutionReport)value;
ExecType et = (ExecType)er.getExecType();
if (et.getValue() == ExecType.FILL)
{
//TODO: implement code
}
}
Console.WriteLine("Got message from App" + value.ToString());

}
  1. Run FixAccceptor.
  2. Then Run FixInitiator. This application will send order to FixAcceptor.

Fix Initiator

fixInitiator.png

Fix Acceptor

FixAcceptor.png

I’ll continue the advanced version of Fix message implementation in next blog.

Please give your valuable feedback.

There is also the need to inherit MessageCracker class which has some virtual methods to handle messages like: the below method invokes when any Order is sent by client then this method sends execution report of this order to client. ExecutionReport can be Filled, Cancelled, etc. Filled Execution Report means order has been successfully executed on exchange.

License

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

About the Author

Neeraj Kaushik 1980
Architect Initto Technologies India Pvt Ltd
India India
Member
• Technical Architect with 9 years of Application development experience
• Good knowledge and expertise on multiple areas of technologies and their business applications
• Strong experience in high performance and business critical applications.
• Experience in creating framework, Code generators, and UML diagrams.
• Developed messaging framework for Algo Trading, technical analysis tool, market feed client Api, Payment Solutions for SWIFT, Internationalization for Core Banking Solution product etc.
• Practical knowledge of building and practicing agile delivery methodologies (SCRUM & TDD).
• Proven ability in producing technical documentation and presentation to clients.
• Active participation in trainings, article writing & taking initiatives.
• Passion to get knowledge from various resources acquires best practices.
• Good understanding of financial domain especially in investment banking and banking domain.
Specialties
 
Technical Architectures, Multi-threading Architecture, Algo Trading systems, Messaging Framework, FIX Implementation, Technical Analysis & Charting, ActiveMQ, MSMQ, C#, WinForms, ASP.NET MVC, Jquery, WCF, Sql Server 2008, Oracle, TFS, TDD, QuickFix, Open Source Tools & Framework.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionExample causes problem for FIXT.1.1 versionmembershafiqul bashar27 Aug '12 - 20:03 
Hi
I used your example application with quickfix_net.dll & quickfix_net_messages.dll in for connecting a FIXT.1.1 gateway.
All of the doc found at online refers for these two dll. But main problem is whenever I assign a BeginString=FIXT.1.1 , it throws an exception "Begin String must be from FIX.4.2 to FIX.4.4".
 

I tried with later version of quickFix.dll but it caused problems more.
So my request is to fix the issues and better if you send me a simple vb.net application to coonect with FIXT.1.1
 
Thanks
-Russel
AnswerRe: Example causes problem for FIXT.1.1 versionmemberNeeraj Kaushik 198027 Aug '12 - 20:40 
Hi Russel,
 
I just published one blog with FIXT1.1 version. You can read here implementation-of-fix-messages-for-fix-5-0-sp2-and-fixt1-1-specification[^]
 
You can send me mail if you want specific solution.
 
Thanks
Neeraj
GeneralRe: Example causes problem for FIXT.1.1 versionmembershafiqul bashar28 Aug '12 - 0:29 
Thanks Neeraj, for the reply.
 
I saw your post.
Can you please send me the sample application in vb.net for connection with FIXT.1.1?
 
Please do this favor.
I am eagerly waiting for your reply.
 

-Russel
GeneralRe: Example causes problem for FIXT.1.1 versionmemberinamalvi25 Mar '13 - 18:42 
Hi Neeraj
 
I got your email when I was looking on internet for some help with Fix Engine.
Actually I am developer of auto trading system and I was using API from the brokers to connect and send my orders.
Now, when I approached some other brokers who are offering better options, they are not providing me the API. The are saying that I should use FIX protocol to communicate with them and this is all new to me
 
After studying on internet I came to know that I need "FIX engine" software which I should be able to merge with my application and use it communicate with broker or brokers.
 
I will appreciate if you guide me in this regards, I am totally new in this and dont know how to proceed. I visited FTL website and looked for the vendors and I am trying to communicate with them but still have not received any response.
 
I am also willing to compensate for such consultancy by person or company who can help me
 
Thanks
GeneralFIX is connecting on Single Machine only i.e.SocketConnectHost=localhost for connecting in LAN network i used SocketConnectHost=remote but not workmemberMember 319880029 Feb '12 - 1:28 
I have implemented FIX using given sample, it is connecting and send message to server from client when SocketConnectHost=localhost but when I tried in network i used SocketConnectHost=remote but it not work.
Could you please kindly give me suggestion over this.
 
Thanks and Regards,
Samadhan Bagal
bagalsamadhan@gmail.com
9860856155
GeneralRe: FIX is connecting on Single Machine only i.e.SocketConnectHost=localhost for connecting in LAN network i used SocketConnectHost=remote but not work [modified]memberNeeraj Kaushik 198029 Feb '12 - 1:52 
Put below in Acceptor config:
 
SocketAcceptPort=<valid port>
 
and Initiator Configuration
 
SocketConnectHost=<ip address/machine name>
SocketConnectPort=<valid Port>
 
Please let me know if it works.
Please note port should be access by client machine. It should not be blocked by firewall.

modified 29 Feb '12 - 8:08.

GeneralRe: FIX is connecting on Single Machine only i.e.SocketConnectHost=localhost for connecting in LAN network i used SocketConnectHost=remote but not workmemberkhokon771 Aug '12 - 23:15 
Thanx for nice post.
 
it should be
SocketConnectHost=<ip address>
 
How can i stop sending msg to server?
Below steps does not work in remote server.
 
HeartBtInt=30
ReconnectInterval=0
GeneralRe: FIX is connecting on Single Machine only i.e.SocketConnectHost=localhost for connecting in LAN network i used SocketConnectHost=remote but not workmemberNeeraj Kaushik 19801 Aug '12 - 23:30 
I am not sure I understood your question. Please be more specific why you want to stop sending msg.
GeneralRe: FIX is connecting on Single Machine only i.e.SocketConnectHost=localhost for connecting in LAN network i used SocketConnectHost=remote but not workmemberkhokon771 Aug '12 - 23:39 
In your sample it justs keep on sending same messages again and again after some interval. I just want to see one full cycle of one message send and receive report.
For this i made ReconnectInterval = 0. Is it possible to do that?
GeneralRe: FIX is connecting on Single Machine only i.e.SocketConnectHost=localhost for connecting in LAN network i used SocketConnectHost=remote but not workmemberNeeraj Kaushik 19805 Aug '12 - 18:59 
Hi,
 
I don't see same message is coming multiple times. Your problem might be because initiator could not send messages to acceptor, it might be because of acceptor was not running. When acceptor turned on, initiator sends messages which were not sent earlier as well. In this case acceptor sends multiple execution reports. Initiator maintains session, message information in logfiles which you can find in c:\fixfiles folder.
 
You need to run both components to see full life cycle of order and execution report.
 
Please let me know if you still face any problem.
 
Thanks
Neeraj
Questiondynamic acceptor issuememberGajananPise23 Feb '12 - 23:06 
Hello Neeraj,
 
I am Gajanan working on quickfix/j.. i have done simple application to execute order by initiator/acceptor.. but i want to create multiple order handler acceptor(dynamic acceptor) i mean multiple session hander acceptor..
Please help me...
 
thanks in adv..
AnswerRe: dynamic acceptor issuememberNeeraj Kaushik 198029 Feb '12 - 2:51 
you can check my recent post here
QuestionMarketDatamemberedsoncosta16 Feb '12 - 0:49 
Hi Man.
 
do you have any examples: How to retrieve Marketdata using QuickFix??
 
Thank you
Edson / Brazil
AnswerRe: MarketDatamemberneeraj198016 Feb '12 - 4:29 
you can send MarketDataRequest message to FIX server like
 
var marketDataRequest = new MarketDataRequest();
            marketDataRequest.set(new QuickFix.MDReqID(Utility.GetNewUniqueId()));
            marketDataRequest.set(new QuickFix.SubscriptionRequestType('1'));
            marketDataRequest.set(new QuickFix.MarketDepth(1));
            marketDataRequest.set(new QuickFix.MDUpdateType(1));
            marketDataRequest.set(new QuickFix.AggregatedBook(true));
            var noMDEntryTypes = new MarketDataRequest.NoMDEntryTypes();
            var mdEntryType_bid = new QuickFix.MDEntryType('0');
            noMDEntryTypes.set(mdEntryType_bid);
            marketDataRequest.addGroup(noMDEntryTypes);
            var mdEntryType_offer = new QuickFix.MDEntryType('1');
            noMDEntryTypes.set(mdEntryType_offer);
            marketDataRequest.addGroup(noMDEntryTypes);
            var relatedSymbol = new MarketDataRequest.NoRelatedSym();
            relatedSymbol.set(new QuickFix.Symbol(instrument));
            marketDataRequest.addGroup(relatedSymbol);
 
Response can be like MarketDataRequestReject (reject message), MarketDataIncrementalRefresh (for realtime price) and MarketDataSnapshotFullRefresh ( for snapshot data)
eg.
public override void onMessage(QuickFix42.MarketDataRequestReject message, SessionID session)
        {
            System.Console.WriteLine("MarketDataRequestReject : " + message.ToString());
        }
        public override void onMessage(QuickFix42.MarketDataIncrementalRefresh message, SessionID session)
        {
            System.Console.WriteLine("MarketDataIncrementalRefresh : " + message.ToString());
        }
I hope it will help you.
GeneralRe: MarketDatamemberMember 344990819 Feb '12 - 7:33 
Could you please contact me if you are interested in FIX protocol integration projects?
thank you
martin
 
crabapple (at) gmail
Question64 bitmemberSillychuckie7 Sep '11 - 11:35 
Hi there - nice enough article.
Do you run this in 32 or 64 bit (x86/x64) environments?
I'm looking for a set of 'official', pre-built 64 bit compatible QuickFix dll's. I don't want to build myself and can only find some questionnable builds elsewhere.
Can you help? The 32bit version I have seems to be targeted to 32 bit only, so won't work for me.
The only other I found is a 'DamageBoy' port (from GitHub) - but that has a few issues too.
 
Thanks. SC.
AnswerRe: 64 bitmemberroberto.reff12 Sep '11 - 22:21 
There are no compiled x64 dlls available. I had to build my own. No need to use 'DamageBoy' fork.
 
Regards
Roberto
GeneralMy vote of 5memberfredatcodeproject7 Sep '11 - 3:58 
very good article
I didn't know FIX
Questionno source codememberseckin durgay4 Sep '11 - 20:57 
I couldn't download sourcecode. Could you add?
AnswerRe: no source codememberneeraj198016 Feb '12 - 3:38 
Source code is already attached file: FixInitiator.zip. Please let me know if you still facing issue.
QuestionGood startmemberQuinton Viljoen15 Aug '11 - 23:08 
Thanks for the article, it is definitely a good start. I have one suggestion, please add a custom data dictionary implementation as this is one area that mostly everyone struggles with :P
 
Regards
Q
GeneralGood Examplemembersuresh suthar17 Mar '11 - 1:12 
Hi Neeraj
 
Its a very good example for QuickFix implementation.
But I am not able to browse or download the sample code.
Please upload sample project.
 
And one more help please:
How to retrieve marketdata using QuickFix???
Be an Eagle, Sky is Yours.

GeneralMy vote of 5memberEspen Harlinn14 Jan '11 - 0:38 
5 for QuickFix for .Net, it's good to know that this excellent library is available for .Net developers Smile | :)
GeneralMy vote of 5memberkdgupta8713 Jan '11 - 22:17 
cool

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 6 Sep 2011
Article Copyright 2011 by Neeraj Kaushik 1980
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid