Send and Receive Message from FIX Server using QuickFIX/J

In this tutorial we will use QuickFIX/J to connect to a remote FIX server and send logon message.

To consume messages from FIX server we need an Initiator.

What we need :

  1. JDK1.6.0
  2. log4j-1.2.15.jar
  3. quickfixj-all-1.5.2.jar
  4. slf4j-api-1.6.3.jar
  5. mina-core-1.1.7.jar

First we need to specify the Session and Default Settings to QuickFIX/J.

Create a file called as sessionSettings.txt.

Copy the content from below in your file. Don’t worry if you cannot understand all or any of these, we will explore them later.

[DEFAULT]# Settings which apply to all the Sessions.
ConnectionType=initiator
LogonTimeout=30
ReconnectInterval=30
ResetOnLogon=Y
FileLogPath=C:\Work\QuickFIXJ\logs
[SESSION]# Settings specifically for one session
BeginString=FIX.4.2
SenderCompID=THIS VALUE IS THE CLIENT ID
TargetCompID=THIS VALUE IS THE FIX SERVER ID
StartDay=sunday
EndDay=friday
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
CheckLatency=N
MaxLatency=240
SocketConnectPort=PORT NUMBER OF THE SERVER
SocketConnectHost=IP ADDRESS OF YOUR SERVER
UseDataDictionary=Y
DataDictionary=C:\Work\QuickFIXJ\datadictionary\FIX42.xml
FileStorePath=C:\Work\QuickFIXJ\sessioninfo
  1. ConnectionType – This specifies if you are creating an acceptor (Server) or initiator (Client).
  2. LogonTimeout – Time in seconds before your session will expire, keep sending heartbeat request if you don’t want it to expire.
  3. ReconnectInterval – Time in seconds before reconnecting.
  4. ResetOnLogon – FIX messages have a sequence ID, which shouldn’t be used for uniqueness as specification doesn’t guarantee anything about them. If Y is provided every time logon message is sent, server will reset the sequence.
  5. FileLogPath – Path where logs will be written.
  6. BeginString – Should always specifies your FIX version.
  7. SenderCompID – A String which identifies client uniquely.
  8.  TargetCompID – A String which identifies Server uniquely.
  9. Start and End Day – Start and End of your session if session is week long, used with Start and End Time.
  10. Start and End Time – Time when session starts and ends.
  11. HeartBtInt – Time in seconds which specifies the interval between heartbeat.
  12. CheckLatency – If this is set to True then you have to provide MaxLatency, value should be large enough to cater to network latency.
  13. SocketConnectPort – Port of FIX Server.
  14. SocketConnectHost – IP Address of the FIX Server.
  15. UseDataDictionary – Specifies if data dictionary will be used.
  16. FileStorePath – Session info will be saved here.

You can read more about configuration at Official Documentation.

Next Step is to write the Java code.

Every FIX application should have an implementation of Application interface, Application interface contains call back methods.
MessageCracker provides callback methods for receiving messages from Server.

public class TestApplicationImpl extends MessageCracker implements Application {
	@Override
	public void fromAdmin(Message arg0, SessionID arg1) throws FieldNotFound,
			IncorrectDataFormat, IncorrectTagValue, RejectLogon {
		System.out.println("Successfully called fromAdmin for sessionId : "
				+ arg0);
	}

	@Override
	public void fromApp(Message arg0, SessionID arg1) throws FieldNotFound,
			IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType {
		System.out.println("Successfully called fromApp for sessionId : "
				+ arg0);
	}

	@Override
	public void onCreate(SessionID arg0) {
		System.out.println("Successfully called onCreate for sessionId : "
				+ arg0);
	}

	@Override
	public void onLogon(SessionID arg0) {
		System.out.println("Successfully logged on for sessionId : " + arg0);
	}

	@Override
	public void onLogout(SessionID arg0) {
		System.out.println("Successfully logged out for sessionId : " + arg0);
	}

	@Override
	public void toAdmin(Message message, SessionID sessionId) {
		System.out.println("Inside toAdmin");
	}

	@Override
	public void toApp(Message arg0, SessionID arg1) throws DoNotSend {
		System.out.println("Message : " + arg0 + " for sessionid : " + arg1);
	}

	@Override
	public void onMessage(NewOrderSingle message, SessionID sessionID)
			throws FieldNotFound, UnsupportedMessageType, IncorrectTagValue {
		System.out.println("Inside onMessage for New Order Single");
		super.onMessage(message, sessionID);
	}

	@Override
	public void onMessage(SecurityDefinition message, SessionID sessionID)
			throws FieldNotFound, UnsupportedMessageType, IncorrectTagValue {
		System.out.println("Inside onMessage for SecurityDefinition");
		super.onMessage(message, sessionID);
	}

	@Override
	public void onMessage(Logon message, SessionID sessionID)
			throws FieldNotFound, UnsupportedMessageType, IncorrectTagValue {
		System.out.println("Inside Logon Message");
		super.onMessage(message, sessionID);
	}
}

Next step is to connect to FIX server and send Logon Message

public class TestQuickFixJConnectivity {
	public static void main(String[] args) {
		SocketInitiator socketInitiator = null;
		try {
			SessionSettings sessionSettings = new SessionSettings("C:\\Work\\QuickFixJ\\sessionSettings.txt");
			Application application = new TestApplicationImpl();
			FileStoreFactory fileStoreFactory = new FileStoreFactory(sessionSettings);
			FileLogFactory logFactory = new FileLogFactory(sessionSettings);
			MessageFactory messageFactory = new DefaultMessageFactory();
			socketInitiator = new SocketInitiator(application,
					fileStoreFactory, sessionSettings, logFactory,
					messageFactory);
			socketInitiator.start();
			SessionID sessionId = socketInitiator.getSessions().get(0);
			sendLogonRequest(sessionId);
			int i = 0;
			do {
				try {
					Thread.sleep(1000);
					System.out.println(socketInitiator.isLoggedOn());
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				i++;
			} while ((!socketInitiator.isLoggedOn()) && (i < 30));
		} catch (ConfigError e) {
			e.printStackTrace();
		} catch (SessionNotFound e) {
			e.printStackTrace();
		} catch (Exception exp) {
			exp.printStackTrace();
		} finally {
			if (socketInitiator != null) {
				socketInitiator.stop(true);
			}
		}
	}
	private static void sendLogonRequest(SessionID sessionId)
			throws SessionNotFound {
		Logon logon = new Logon();
		Header header = logon.getHeader();
		header.setField(new BeginString("FIX.4.2"));
		logon.set(new HeartBtInt(30));
		logon.set(new ResetSeqNumFlag(true));
		boolean sent = Session.sendToTarget(logon, sessionId);
		System.out.println("Logon Message Sent : " + sent);
	}
}

There are 17 comments

  1. Sean

    Very interesting! As someone who has just started playing around with QuickFIX/J this is great, Would greatly appreciate any further code samples you may have or to be able to contact you with some questions.

    As a small aside, I don’t think QuickFIX/J is using log4j any more.

      1. Sean

        What you have here is an excellent start. It would be great if you could give a bit more detail, implementing a full cycle. Logon, send buy or sell order, logoff and some examples of the typical issues you might have and how to handle it, like sequence numbers getting out of sync for example.

        The banzai example supplied does do a lot of this but the code is not well commented and it is made more complex by GUI handling etc. This is also an issue with FIXpusher.

        BTW I think there is a problem with this line of code in your example:

        Application application = new BarXApplication();

        Shouldn’t that be:

        Application application = new TestApplicationImpl(); ?

        Keep up the great work!

      2. Sean

        I just noticed your new posts, going to play around with the code a bit now. This is really helpful and very much appreciated! QuickFixJ is not the easiest software to understand and your posts help a lot, I think you have a knack for writing clear code 🙂

  2. Ben

    Good day! Would you mind if I share your blog with my myspace group?
    There’s a lot of folks that I think would really enjoy your content. Please let me know. Many thanks

  3. yendys

    Hi Prabhat, After creating all these files you have stated
    above, which folders do you put the files in? Is it in the main
    quickfixj folder or the other folders inside the parent quickfixj
    folder?

  4. Mike

    Hi Prabhat, thank you for the informative post. Do you know
    how to specify a password as part of the logon process? I am
    connecting to a TT fix adapter.

  5. Mike

    When I tried this code it didn’t work as it sends a message
    before the session is established. The error in the log was “No
    responder, not sending message”. Adding a Thread.sleep(5000); after
    the line socketInitiator.start(); fixes this.

  6. randmate

    Hi, I appreciate your Great efforts. I have a doubt !!!

    If my server sends different versions of FIX messages, how can I change the configuration file. Also without making configuration files, shall I use the Configuration as a method to dynamically change the values ?

  7. garima

    Hi Prabhat,
    Is it possible to roll over quickfixj messages.log and event.log? If yes, How can I achive this?
    In your example “DataDictionary=C:\Work\QuickFIXJ\datadictionary\FIX42.xml” line defines the path to FIX42.xml. I think this file plays a roll in generating messages.log and event.log.

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 )

Google+ photo

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

Twitter picture

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

Facebook photo

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

Connecting to %s