QuickFIXJ Initiator Acceptor Integration

This post is beginning of a set of tutorial which we will write as part of building a web based application which will use QuickFIX/J for trade booking. By end of this tutorial you should have an initiator and acceptor with valid login working. In previous post we created an initiator. Though in this post we will once again take a look at initiator code but please refer the link for information related to fields present in settings and also to check which all jars are required for building FIX application using QuickFIX/J.

Before we proceed further let’s clear some jargon:

  1. Initiator: Your FIX client
  2. Acceptor: Your FIX server

First we will write an Application which is the basic building block whether you write an initiator or acceptor. Let’s write our very simple initiator TestTradeAppInitiator.java. Currently we will have a default plain implementation and as we proceed building our application we will add more functionality.

TestTradeAppInitiator.java


package com.mumz.test.fix.initiator;

import quickfix.Application;
import quickfix.DoNotSend;
import quickfix.FieldNotFound;
import quickfix.IncorrectDataFormat;
import quickfix.IncorrectTagValue;
import quickfix.Message;
import quickfix.RejectLogon;
import quickfix.SessionID;
import quickfix.UnsupportedMessageType;

/***
 * The Class TestTradeAppInitiator.
 * @author prabhat.jha
 */
public class TestTradeAppInitiator implements Application {

	/** (non-Javadoc)
	 * @see quickfix.Application#onCreate(quickfix.SessionID)
	 */
	@Override
	public void onCreate(SessionID sessionId) {

	}

	/** (non-Javadoc)
	 * @see quickfix.Application#onLogon(quickfix.SessionID)
	 */
	@Override
	public void onLogon(SessionID sessionId) {

	}

	/** (non-Javadoc)
	 * @see quickfix.Application#onLogout(quickfix.SessionID)
	 */
	@Override
	public void onLogout(SessionID sessionId) {

	}

	/** (non-Javadoc)
	 * @see quickfix.Application#toAdmin(quickfix.Message, quickfix.SessionID)
	 */
	@Override
	public void toAdmin(Message message, SessionID sessionId) {

	}

	/** (non-Javadoc)
	 * @see quickfix.Application#fromAdmin(quickfix.Message, quickfix.SessionID)
	 */
	@Override
	public void fromAdmin(Message message, SessionID sessionId)
			throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue,
			RejectLogon {

	}

	/** (non-Javadoc)
	 * @see quickfix.Application#toApp(quickfix.Message, quickfix.SessionID)
	 */
	@Override
	public void toApp(Message message, SessionID sessionId) throws DoNotSend {

	}

	/*** (non-Javadoc)
	 * @see quickfix.Application#fromApp(quickfix.Message, quickfix.SessionID)
	 */
	@Override
	public void fromApp(Message message, SessionID sessionId)
			throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue,
			UnsupportedMessageType {

	}
}

Second is our initiator settings.

initiatorSettings.txt

#default settings for sessions
[DEFAULT]#This will applies to all sessions
ConnectionType=initiator
LogonTimeout=30
ReconnectInterval=5
ResetOnLogon=Y
FileLogPath=C:\test\app\QuickFixJ\initiator\logs
[SESSION]#A single session
BeginString=FIX.4.2
SenderCompID=MY-INITIATOR-SERVICE
TargetCompID=MY-ACCEPTOR-SERVICE
StartDay=sunday
EndDay=friday
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
CheckLatency=N
SocketConnectPort=12000
SocketConnectHost=127.0.0.1
UseDataDictionary=Y
DataDictionary=C:\test\app\QuickFixJ\initiator\FIX42.xml
FileStorePath=C:\test\app\QuickFixJ\initiator\ICE

Third we will write our very simple acceptor TestTradeAppExecutor.java.

TestTradeAppExecutor


package com.mumz.test.fix.executor;

import quickfix.Application;
import quickfix.DoNotSend;
import quickfix.FieldNotFound;
import quickfix.IncorrectDataFormat;
import quickfix.IncorrectTagValue;
import quickfix.Message;
import quickfix.RejectLogon;
import quickfix.SessionID;
import quickfix.UnsupportedMessageType;

/***
 * The Class TestTradeAppExecutor.
 * @author prabhat.jha
 */
public class TestTradeAppExecutor implements Application {
	
	/** (non-Javadoc)
	 * @see quickfix.Application#onCreate(quickfix.SessionID)
	 */
	@Override
	public void onCreate(SessionID sessionId) {
		System.out.println("Executor Session Created with SessionID = " + sessionId);
	}

	/** (non-Javadoc)
	 * @see quickfix.Application#onLogon(quickfix.SessionID)
	 */
	@Override
	public void onLogon(SessionID sessionId) {

	}

	/** (non-Javadoc)
	 * @see quickfix.Application#onLogout(quickfix.SessionID)
	 */
	@Override
	public void onLogout(SessionID sessionId) {

	}

	/** (non-Javadoc)
	 * @see quickfix.Application#toAdmin(quickfix.Message, quickfix.SessionID)
	 */
	@Override
	public void toAdmin(Message message, SessionID sessionId) {

	}

	/** (non-Javadoc)
	 * @see quickfix.Application#fromAdmin(quickfix.Message, quickfix.SessionID)
	 */
	@Override
	public void fromAdmin(Message message, SessionID sessionId)
			throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue,
			RejectLogon {

	}

	/** (non-Javadoc)
	 * @see quickfix.Application#toApp(quickfix.Message, quickfix.SessionID)
	 */
	@Override
	public void toApp(Message message, SessionID sessionId) throws DoNotSend {

	}

	/** (non-Javadoc)
	 * @see quickfix.Application#fromApp(quickfix.Message, quickfix.SessionID)
	 */
	@Override
	public void fromApp(Message message, SessionID sessionId)
			throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue,
			UnsupportedMessageType {
		
	}
}

Fourth step is to write settings for acceptor.

acceptorSettings.txt

#default settings for sessions
[DEFAULT]    # ——-> This will applies to all sessions
ConnectionType=acceptor
ResetOnLogon=Y
FileLogPath=C:\test\app\QuickFixJ\acceptor\logs
LogonTimeout=6000
ReconnectInterval=6030
[SESSION] #A single session
BeginString=FIX.4.2
SenderCompID=MY-ACCEPTOR-SERVICE
TargetCompID=MY-INITIATOR-SERVICE
StartDay=sunday
EndDay=friday
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
CheckLatency=N
SocketAcceptPort=12000
UseDataDictionary=Y
DataDictionary=C:\test\app\QuickFixJ\acceptor\FIX42.xml
FileStorePath=C:\test\app\QuickFixJ\acceptor\ICE

Fifth we will write our simple class which will start our executor. On our way building a complete application we will revisit and cleanup the way we are starting our executor, for now let it be a simple java class.

TestTradeAppExecutorApp.java


package com.mumz.test.fix.executor;

import quickfix.Application;
import quickfix.ConfigError;
import quickfix.DefaultMessageFactory;
import quickfix.FileLogFactory;
import quickfix.FileStoreFactory;
import quickfix.MessageFactory;
import quickfix.SessionSettings;
import quickfix.SocketAcceptor;

/**
 * The Class TestTradeAppExecutorApp.
 * 
 * @author prabhat.jha
 */
public class TestTradeAppExecutorApp {

	/**
	 * The main method.
	 * 
	 * @param args
	 *            the args
	 */
	public static void main(String[] args) {
		SocketAcceptor socketAcceptor = null;
		try {
			SessionSettings executorSettings = new SessionSettings(
					"C:/test/app/QuickFixJ/acceptor/acceptorSettings.txt");
			Application application = new TestTradeAppExecutor();
			FileStoreFactory fileStoreFactory = new FileStoreFactory(
					executorSettings);
			MessageFactory messageFactory = new DefaultMessageFactory();
			FileLogFactory fileLogFactory = new FileLogFactory(executorSettings);
			socketAcceptor = new SocketAcceptor(application, fileStoreFactory,
					executorSettings, fileLogFactory, messageFactory);
			socketAcceptor.start();
		} catch (ConfigError e) {
			e.printStackTrace();
		}
	}
}

Fifth and final step is to create a simple java class for running our initiator.

TestTradeAppExecutorApp.java

package com.mumz.test.fix.initiator;

import quickfix.Application;
import quickfix.ConfigError;
import quickfix.DefaultMessageFactory;
import quickfix.FileLogFactory;
import quickfix.FileStoreFactory;
import quickfix.MessageFactory;
import quickfix.Session;
import quickfix.SessionID;
import quickfix.SessionSettings;
import quickfix.SocketInitiator;

/**
 * The Class TestTradeAppInitiatorApp.
 * 
 * @author prabhat.jha
 */
public class TestTradeAppInitiatorApp {

	/**
	 * The main method.
	 * 
	 * @param args
	 *            the args
	 */
	public static void main(String[] args) {
		SocketInitiator socketInitiator = null;
		try {
			SessionSettings initiatorSettings = new SessionSettings(
					"C:/test/app/QuickFixJ/initiator/initiatorSettings.txt");
			Application initiatorApplication = new TestTradeAppInitiator();
			FileStoreFactory fileStoreFactory = new FileStoreFactory(
					initiatorSettings);
			FileLogFactory fileLogFactory = new FileLogFactory(
					initiatorSettings);
			MessageFactory messageFactory = new DefaultMessageFactory();
			socketInitiator = new SocketInitiator(initiatorApplication, fileStoreFactory, initiatorSettings, fileLogFactory, messageFactory);
			socketInitiator.start();
			SessionID sessionId = socketInitiator.getSessions().get(0);
			Session.lookupSession(sessionId).logon();
		} catch (ConfigError e) {
			e.printStackTrace();
		}
	}
}

That’s all, while executing this example, first run TestTradeAppExecutorApp and then TestTradeAppInitiatorApp.

If everything is proper you should see logs and ICE folders created in your initiator and executor directory. Your initiator log file should contain something like this:

20120731-05:04:53: Session FIX.4.2:MY-INITIATOR-SERVICE->MY-ACCEPTOR-SERVICE schedule is weekly, SUN 00:00:00-UTC – FRI 00:00:00-UTC
20120731-05:04:53: Created session: FIX.4.2:MY-INITIATOR-SERVICE->MY-ACCEPTOR-SERVICE

And in your acceptor log something like:

20120731-05:04:48: Session FIX.4.2:MY-ACCEPTOR-SERVICE->MY-INITIATOR-SERVICE schedule is weekly, SUN 00:00:00-UTC – FRI 00:00:00-UTC
20120731-05:04:48: Created session: FIX.4.2:MY-ACCEPTOR-SERVICE->MY-INITIATOR-SERVICE

There are 5 comments

  1. Saurabh Singh

    thanks Prabhat, worked like a charm! gave me an easy start with quickfix. I must admit though that being a novice I wasn’t aware that initiator(client) won’t work until acceptor (server) is running and was struggling with logon failure after trying your implementation from the previous post. Maybe worth mentioning in your previous post that it won’t login until server is running whose code is given in the next page.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s