How to send FIX message with QuickFIX/J

user3756506 picture user3756506 · Mar 14, 2016 · Viewed 14.9k times · Source

I need a simple example of how to initialize a session and send one FIX message. I have this initial code:

SessionSettings settings = new SessionSettings( new FileInputStream("fix.cfg"));

Application application = new Application(settings);
MessageStoreFactory messageStoreFactory = new FileStoreFactory(settings);
LogFactory logFactory = new ScreenLogFactory( true, true, true);
MessageFactory messageFactory = new DefaultMessageFactory();

Initiator initiator = new SocketInitiator(application, messageStoreFactory, settings, logFactory, messageFactory);
initiator.start();

Answer

Slimu picture Slimu · Mar 14, 2016

From the code above, I see that you have an initiator application (the client) and you need to also create an acceptor application (the server). Below I've attached the two classes that will do what do you want.

First I'll list the acceptor application:

public class ServerApplication implements Application {

    @Override
    public void onCreate(SessionID sessionID) {
    }

    @Override
    public void onLogon(SessionID sessionID) {
    }

    @Override
    public void onLogout(SessionID sessionID) {
    }

    @Override
    public void toAdmin(Message message, SessionID sessionID) {
    }

    @Override
    public void fromAdmin(Message message, SessionID sessionID) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon {
    }

    @Override
    public void toApp(Message message, SessionID sessionID) throws DoNotSend {
    }

    @Override
    public void fromApp(Message message, SessionID sessionID) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType {
        System.out.println("FromApp: " + message);
    }

    public static void main(String[] args) throws ConfigError, FileNotFoundException, InterruptedException, SessionNotFound {
        SessionSettings settings = new SessionSettings("res/acceptor.config");

        Application application = new ServerApplication();
        MessageStoreFactory messageStoreFactory = new FileStoreFactory(settings);
        LogFactory logFactory = new ScreenLogFactory( true, true, true);
        MessageFactory messageFactory = new DefaultMessageFactory();

        Acceptor initiator = new SocketAcceptor(application, messageStoreFactory, settings, logFactory, messageFactory);
        initiator.start();

        CountDownLatch latch = new CountDownLatch(1);
        latch.await();
    }
}

This is a server application that will stay started and listen for messages from the clients which connect to it. Here is the configuration file (acceptor.properties) used by it:

[default]
ApplicationID=server
FileStorePath=storage/messages/
ConnectionType=acceptor
StartTime=00:01:00 Europe/Bucharest
EndTime=23:59:00 Europe/Bucharest
HeartBtInt=30
UseDataDictionary=Y
DataDictionary=FIX42.xml
ValidateUserDefinedFields=N
ValidateIncomingMessage=N
RefreshOnLogon=Y

[session]
BeginString=FIX.4.2
SocketAcceptPort=9877
SenderCompID=server
TargetCompID=client
AcceptorTemplate=N
lockquote

Next is the client application code. It tries to connect to a server and after that it will send a message to it:

public class ClientApplication implements Application {

    private static volatile SessionID sessionID;

    @Override
    public void onCreate(SessionID sessionID) {
        System.out.println("OnCreate");
    }

    @Override
    public void onLogon(SessionID sessionID) {
        System.out.println("OnLogon");
        ClientApplication.sessionID = sessionID;
    }

    @Override
    public void onLogout(SessionID sessionID) {
        System.out.println("OnLogout");
        ClientApplication.sessionID = null;
    }

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

    @Override
    public void fromAdmin(Message message, SessionID sessionID) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon {
        System.out.println("FromAdmin");
    }

    @Override
    public void toApp(Message message, SessionID sessionID) throws DoNotSend {
        System.out.println("ToApp: " + message);
    }

    @Override
    public void fromApp(Message message, SessionID sessionID) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType {
        System.out.println("FromApp");
    }

    public static void main(String[] args) throws ConfigError, FileNotFoundException, InterruptedException, SessionNotFound {
        SessionSettings settings = new SessionSettings("res/initiator.config");

        Application application = new ClientApplication();
        MessageStoreFactory messageStoreFactory = new FileStoreFactory(settings);
        LogFactory logFactory = new ScreenLogFactory( true, true, true);
        MessageFactory messageFactory = new DefaultMessageFactory();

        Initiator initiator = new SocketInitiator(application, messageStoreFactory, settings, logFactory, messageFactory);
        initiator.start();

        while (sessionID == null) {
            Thread.sleep(1000);
        }

        final String orderId = "342";
        NewOrderSingle newOrder = new NewOrderSingle(new ClOrdID(orderId), new HandlInst('1'), new Symbol("6758.T"),
                new Side(Side.BUY), new TransactTime(new Date()), new OrdType(OrdType.MARKET));
        Session.sendToTarget(newOrder, sessionID);
        Thread.sleep(5000);
    }
}

The configuration file for it (initiator.config) is almost the same as the one used for the acceptor:

[default]
ApplicationID=client
FileStorePath=storage/messages/
ConnectionType=initiator
StartTime=00:01:00 Europe/Bucharest
EndTime=23:59:00 Europe/Bucharest
HeartBtInt=30
UseDataDictionary=Y
DataDictionary=FIX42.xml
ValidateUserDefinedFields=N
ValidateIncomingMessage=N
RefreshOnLogon=Y

[session]
BeginString=FIX.4.2
SocketConnectHost=localhost
SocketConnectPort=9877
SenderCompID=client
TargetCompID=server

The configuration files both miss some options, but for testing purposes are enough. Each of the classes has a main method added just for testing the case you wanted.

Normally you would handle a bit different the way they are started or stopped. The server application listens for messages/connections and is never stopped, while the client application stops right after sending the first message.