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
- Create
SessionSettings
object with config file.
- Create object of
Application
class.
- Create Object of
SocketAcceptor
class by passing SessionSettings
.
- 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)
{
}
public void onLogon(QuickFix.SessionID value)
{
}
public void onLogout(QuickFix.SessionID value)
{
}
public void toAdmin(QuickFix.Message value, QuickFix.SessionID session)
{
}
public void toApp(QuickFix.Message value, QuickFix.SessionID session)
{
}
public void fromAdmin(QuickFix.Message value, SessionID session)
{
}
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)
{
}
}
Console.WriteLine("Got message from App" + value.ToString());
}
}
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
- Create application class object, i.e.,
ClientInitiator
.
- Create object of
SessionSettings
class.
- Create
SocketInitiator
class.
- Run
Start
method.
- 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)
{
}
}
Console.WriteLine("Got message from App" + value.ToString());
}
- Run
FixAccceptor
.
- Then Run
FixInitiator
. This application will send order to FixAcceptor
.
Fix Initiator
Fix Acceptor
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.