Onix Solutions Logo

Java FIX Engine — Programmer's Guide

Version 1.9.44

Introduction

Onix Solutions Java FIX Engine is a simple fully Java compliant tool that will FIX-enable applications written in Java.

The Engine provides the following services:

High-level Architecture

System Requirements

Distribution Package

3rd Party Libraries

JAR Notes License
onixs-util The collection of utility classes. OnixS License
onixs-fix-engine The FIX engine. OnixS License
onixs-fast-coder The FAST coder. OnixS License
onixs-fixml-converter The FIXML converter. OnixS License
slf4j-api The SLF4J logging facility facade. Massachusetts Institute of Technology (MIT) X11 License
logback-classic, logback-core The logging facility implementation. This can be replaced with any supported implementation. LGPL v2.1
commons-io The commons-io is a library of utilities to assist with developing IO functionality. Apache License Version 2.0
joda-time Date and time processing library. Apache License Version 2.0
commons-pool The commons-pool library provides an object-pooling API and implementation. Apache License Version 2.0
commons-lang The commons-lang library provides extra functionality for classes in java.lang. Apache License Version 2.0
xercesImpl The Xerces-J is the reference implementation of high performance, fully compliant XML parser. Apache License Version 2.0
xml-apis The XML APIs collection. W3C License

Classpath Libraries Selection

JAR FIX Engine FAST Coder FIXML Converter Session Scheduler
onixs-util + + + +
onixs-fix-engine + + + +
onixs-fast-coder   +    
onixs-fixml-converter     +  
onixs-fix-scheduler       +
slf4j-api + + + +
logback-classic, logback-core + + + +
commons-io + + + +
joda-time + + + +
commons-pool + + + +
commons-lang     +  
xercesImpl     +  
xml-apis     +  
commons-codec + + + +
quartz       +
c3p0       +

Getting Started

All Engine classes have a well formed API and could be easy extended for customer requirements.

The typical way of using the Engine is as follows:

  1. Initialize the Engine.
  2. Create the Session object.
  3. Establish the FIX session as Initiator or Acceptor.
  4. Send and receive application-level FIX messages.
  5. Disconnect the session.
  6. Shutdown the Engine.

Error Reporting

Exception handling is used as a fundamental error-reporting mechanism. In the event of any errors arising then the biz.onixs.fix.engine.EngineException is thrown.

Engine

To initialize the FIX Engine class library the biz.onixs.fix.engine.Engine.init(..) method is used. This method must be called before all other methods.

The engine configuration is set during initializtion phase. See Configuration → Engine Initialization for details.

To shutdown the Engine the biz.onixs.fix.engine.Engine.shutdown() method is used. No other Engine methods must be called after this method.

Example:

import biz.onixs.fix.engine.Engine;

public class SimpleEngine {
    public static void main(String[] args) {
        try {
            final Engine engine = Engine.init();

            // Session-related logic...
            engine.shutdown();
        } catch (Exception ex)
            System.out.println("Exception: " + ex);
        }
    }
}

See also: Configuration → Engine Initialization.

FIX Version

As the FIX protocol evolves its new versions will be released to you to extend the current functionality.

Supported FIX versions are: FIX 4.0, 4.1, 4.2, 4.3, 4.4 and 5.0. The biz.onixs.fix.engine.Version enum is used to identify them.

Example:

Version v = Version.FIX44;

Each FIX version can be produced by appropriate number too, e.g.:

final Version fixVersion = Version.getByNumber("4.2");

FIX Message

The general format of a FIX message is a stream of <tag>=<value> fields with a field delimiter (<SOH>) between fields in the stream (so-called "tag-value FIX format").

Below is an example of a FIX message:

FIX message example

It is represented with the biz.onixs.fix.engine.Message class.

To create a message the biz.onixs.fix.engine.Message(java.lang.String type, biz.onixs.fix.engine.Version version) constructor is used.

To parse a message in the raw format the biz.onixs.fix.engine.Message(java.lang.String rawMessage) constructor is used.

To validate a message the biz.onixs.fix.engine.Message.validate() method is used. This method checks for the presence of required fields.

Example (samples-pro-guide/src/main/java/biz/onixs/fix/sample/proguide/FixMessageCreation.java):

// Init the engine
final Engine engine = Engine.init();
// Create "New Order - Single", MsgType = "D"
final Message order = new Message("D", Version.FIX40);
// Another way to create FIX message
final String rawMsg = "8=FIX.4.0\u00019=86\u000135=D\u000149=0\u000156=0\u000134=1\u000152=99990909-17:17:17\u0001"
        + "11=90001008\u000121=1\u000155=IBM\u000154=1\u000138=10\u000140=1\u000159=0\u000110=191\u0001";
final Message order2 = new Message(rawMsg);
// Validate created message
order2.validate();
// Shutdown the engine
engine.shutdown();

Fields

To set a field value the appropriate biz.onixs.fix.engine.Message.set() method is used.

To get a field value the biz.onixs.fix.engine.Message.get() method is used.

Example:

   String ClOrdID = order.get(11);
   execReport.set(17, "Unique identifier of execution message");

To remove a field the biz.onixs.fix.engine.Message.remove(int tag) method is used.

The Tag class contains the constants for the tag values. This class is defined for each FIX version namespace. The use of these constants makes the source code more readable.

Example:

  import biz.onixs.fix.engine.Message;
  import static biz.onixs.fix.engine.FIX40.Tag;
	...
  // New Order – Single
  Message order = new Message("D", Version.FIX40);
  order.set(Tag.ClOrdID, "90001008");
  order.set(Tag.Side, "1");
  order.set(Tag.TimeInForce, "0");

See also: FIX Repeating Group.

FIX Session

A FIX session is defined as a bi-directional stream of ordered messages between two parties within a continuous sequence number series. It is represented by the biz.onixs.fix.engine.Session class.

To create a session object the appropriate constructor is used.

To terminate the session the Session.dispose() method is used.

A session has one of two possible roles: Acceptor or Initiator.

Acceptor is the receiving party of the FIX session. It listens for the incoming connection on the pre-defined port. The acceptor has responsibility to perform first level authentication and formally declare the connection request "accepted" through transmission of an acknowledgment Logon message.

Initiator establishes the telecommunications link and initiates the session via transmission of the initial Logon message.

To obtain current role the Session.getRole() method is used.

Connection Establishment

To establish the session as Acceptor the Session.logonAsAcceptor() method is used.

To establish the session as Initiator the Session.logonAsInitiator() method is used.

To disconnect the session the Session.logout(...) method is used.

Example:

    import biz.onixs.fix.engine.Message;
    import biz.onixs.fix.engine.Session;
    import biz.onixs.fix.engine.Version;
    ...
    Session acceptor = new Session("SenderCompID", "TargetCompID", Version.FIX40);
    acceptor.logonAsAcceptor();
    
    Session initiator = new Session("TargetCompID", "SenderCompID", Version.FIX40);
    // Sends the Logon message and waits for the acknowledgment Logon
    initiator.logonAsInitiator("localhost", Engine.getInstance().getListenPort());
    
    // Message exchange and processing ... 
     
    // Sends the Logout message and waits for the confirming Logout
    initiator.logout();
    acceptor.logout();
    // Free resources
    initiator.dispose();
    acceptor.dispose();

See also:  Session state, Custom Logon Message, Sequence Numbers.

Message Exchange

To send a message to counterparty the Session.send(...) method is used. As soon as a session is created it is possible to start sending messages via the session. If the session is not established, the messages will be sent when the connection is established with the counterparty.

To receive incoming application-level messages it is necessary to implement the Session.InboundApplicationMessageListener interface for incoming message event handler and register it by Session.setInboundApplicationMessageListener(Session.InboundApplicationMessageListener listener).

Example.

package biz.onixs.fix.sample.proguide;


import biz.onixs.fix.engine.Session;
import biz.onixs.fix.engine.Engine;
import biz.onixs.fix.parser.Version;
import biz.onixs.fix.parser.Message;
import biz.onixs.fix.tag.FIX42;
import biz.onixs.fix.tag.Tag;
import biz.onixs.util.Utils;

import java.text.SimpleDateFormat;
import java.util.Date;


public class MessageExchange implements Session.InboundApplicationMessageListener {
    private static final String SENDER_COMP_ID = "SenderCompId";
    private static final String TARGET_COMP_ID = "TargetCompId";
    private static final Version VERSION = Version.FIX42;
    private static final String ACCEPTOR_HOST = "localhost";
    private static final int ACCEPTOR_PORT = 11011;
    private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("yyyyMMdd-HH:mm:ss");

    public void onInboundApplicationMessage(Object sender, Session.InboundApplicationMessageArgs args) {
        System.out.println("Incoming application-level message: " + args.getMsg());
        // processing of the application-level incoming message...
    }

    private void run() {
        final Engine engine = Engine.init(ACCEPTOR_PORT);

        final Session acceptor = new Session(SENDER_COMP_ID, TARGET_COMP_ID, VERSION);
        acceptor.logonAsAcceptor();

        final Session initiator = new Session(TARGET_COMP_ID, SENDER_COMP_ID, VERSION);
        initiator.logonAsInitiator(ACCEPTOR_HOST, ACCEPTOR_PORT);

        initiator.setInboundApplicationMessageListener(this);

        final Message order = new Message("D", VERSION);
        order.set(Tag.ClOrdID, "Unique identifier for Order as assigned by the buy-side");
        order.set(Tag.HandlInst, "1");
        order.set(Tag.Symbol, "Ticker symbol");
        order.set(Tag.Side, "1");
        order.set(Tag.TransactTime, FORMATTER.format(new Date()));
        order.set(FIX42.Tag.OrdType, "1");
        order.validate();

        acceptor.send(order);

        Utils.waitForEnterToTerminateApp();

        acceptor.logout();

        acceptor.dispose();
        initiator.dispose();
        engine.shutdown();
    }

    public static void main(String[] args) {
        final MessageExchange messageExchange = new MessageExchange();
        messageExchange.run();
    }
}

This example can be found in samples/samples-pro-guide, class biz.onixs.fix.sample.proguide.MessageExchange.java

Sequence Numbers

All FIX messages are identified by a unique sequence number (the MsgSeqNum field).

Sequence numbers are initialized at the start of each FIX session starting at 1 (one) and increment throughout the session.  Each session establishes an independent incoming and outgoing sequence series.

A single FIX session can exist across multiple sequential (not concurrent) physical connections.  Parties can connect and disconnect multiple times while maintaining a single FIX session.  In other words, FIX Session is comprised of one or more FIX Connections.

Resetting the inbound and outbound sequence numbers back to 1, for whatever reason, constitutes the beginning of a new FIX session.

Monitoring sequence numbers enables parties to gracefully synchronize applications when reconnecting during a FIX session. 

To disconnect the FIX Connection while maintaining a single FIX Session the Session.logout(...) method is used. It is possible to continue the session later using the Session.logonAsAcceptor() or Session.logonAsInitiator(...) methods again.

To terminate a FIX Session the Session.dispose() method is used.

The Engine automatically synchronizes sequence numbers when reconnecting during a FIX session on the base of the information previously stored in log files.

Sequence numbers diagram

See also: Sequence Numbers Management.

Configuration

Engine Initialization

The engine is configured during initialization phase. The initialization method is overloaded. Thus there are multiple ways to pass the configuration.

Properties File

The engine settings are taken from the properties.

PropertyBasedSettings settings = new PropertyBasedSettings("engine.properties");
Engine engine = Engine.init(settings);

The properties file is loaded as described in the Unified Resource Loading.

The configuration file example:

Dialect=LavaDialect.xml
Log.InboundMessages=true
Validate.NumberOfRepeatingGroupInstances=false
Validate.RequiredFields=true
Validate.UnknownFields=true

Settings Class

The engine settings are available as the class properties.

EngineSettings settings = new EngineSettings();
Engine engine = Engine.init(settings);

The settings can be changed before initialization method call.

License File

The pre-defined license file name is "OnixS.lic". The license file is loaded during engine initialization as described in the Unified Resource Loading.

The default license file name can be changed using "LicenseFile" configuration parameter or EngineSettings.LicenseFile property.

The following table explains different options to keep the license file.

License File Location License File Name LicenseFile Property Note
application classpath OnixS.lic no change required  
current directory *.lic no change required Any file with the ".lic" extension in the current directory is checked automatically.
user home directory *.lic no change required Any file with the ".lic" extension in the user home is checked automatically.
application classpath AltName.ext AltName.ext  
absolute path "/foo/bar" AltName.ext /foo/bar/AltName.ext  
relative path "foo/bar" AltName.ext foo/bar/AltName.ext  

Logging

The SLF4J (Simple Logging Facade for Java) is used for logging. The SLF4J detects and uses the concrete logging implementation configured by user. By default, the Logback logging implementation is recommended.

The Logback (or any other logging implementation) must be configured at the beginning of the application lifecycle.

The examples of Logback configurations can be found in the application examples.

The details of Logback configuration can be found here.

See also: Classpath Libraries Selection.

Persistent Session Storage

By default, the FIX engine uses file system directory specified by the "Log.Directory" parameter for storing incoming and outgoing messages, session’s state data.

For each FIX session the following files are created:

Where:

When the biz.onixs.fix.engine.Session.logonAsAcceptor() object is created anew after the Engine's restart, FIX Session's state (the sequence numbers of last received and sent messages, previously sent messages, etc) is restored from these files.

To start a FIX session as a new one (so called "clean start"), it is necessary to remove the log files from the previous runs.

Connecting parties must bi-laterally agree as to when sessions are to be started/stopped and log files are backed up based upon individual system and time zone requirements.

When the FIX session is finished, the log files are not needed anymore. They can be backed up and later a new FIX session with the same SenderCompID and TargetCompID will start sequence numbers from 1. The usual practice is to backup the log files at the end of each business day (so called "End Of Day procedure") to start the sequence numbers from 1 at the beginning of the next day.

See also: Log.Directory, Log.InboundMessages, Sequence Numbers.

Settings

Property Description Type Default Value
LicenseFile Specifies the name of the license file resource. string OnixS.lic
Dialect Specifies the location of one or several files with the FIX Dialects definition. The file names are separated with the '|' character. The dialect files are loaded during engine initialization as described in the Unified Resource Loading. string <empty>
ListenPort FIX Engine listens on this port(s) for incoming connections. If it is set to '0' then only session-initiators can be created. If it is set to '-1' then the telecommunication level is disabled and only message parsing/assembling can be used.
Use comma delimited list if more than one listen port is required.
It is important to avoid using ports used by other services.
string 0
Log.Directory Inbound/outbound messages and session's state data are stored in this directory. string FixEngineStorage
Log.InboundMessages Option to log inbound messages. boolean true
Validate.NumberOfRepeatingGroupInstances Option to validate that the declared number of repeating group instances is equal to the actual one. For in inbound and outbound messages boolean false
Validate.RequiredFields Option to validate the presence of required fields in inbound and outbound messages. boolean false
Validate.UnknownFields Option to validate the presence of unknown fields in inbound and outbound messages. boolean false
ConnectionRetries.Interval The initial time interval between the attempts to restore the telecommunication link, in milliseconds. integer 90000
ConnectionRetries.Number Number of attempts to restore the telecommunication link. The range is [0..MAX_INT]. integer 3
Connection.TcpNoDelay Option to improve latency at the expense of message throughput. boolean true
Connection.TcpSendBufferSize The size of the TCP buffer allocated to FIX connection for sending data, in bytes. integer 65535
Connection.TcpReceiveBufferSize The size of the TCP buffer allocated to FIX connection for receiving data, in bytes. integer 65535
Connection.OutputQueueSize The size of the internal output queue allocated to FIX connection, in messages. integer 1000
ReasonableTransmissionTime

The reasonable transmission time as % from HeartBtInt value.

When either end of the connection has not received any data for (HeartBtInt * (100 + ReasonableTransmissionTime)/100) seconds, it will transmit a Test Request message.

If there is still no Heartbeat message received after (HeartBtInt * (100 + ReasonableTransmissionTime)/100) seconds then the connection should be considered lost and corrective action be initiated.

integer 20
SessionListenerDelayWarningThreshold The limit of time to spend in the session listener code. If the listener takes longer then the warning is generated. In milliseconds. integer 1000

The settings names (keys) are case-sensitive.

Unified Resource Loading

By default, any external resource is looked for at the following places and in the following order (if other is not set explicitely):

  1. Classpath
  2. Absolute file path
  3. Current directory
  4. User home directory

If it can't be found at the 1st location then the 2nd one is checked, etc.

For example, you can put a dialect file to the classpath or current directory and it will be located by engine.

Advanced

FIX Repeating Group

It is permissible for fields to be repeated in the same message within a repeating group (e.g. "215=2<SOH>216=2<SOH>217=Dest_1<SOH>216=4<SOH>217=Dest_2<SOH>" represents a repeating group with two repeating instances "delimited" by tag 216 (first field in the repeating group.).

The NoRoutingIDs<215> field specifies the number of repeating group instances (2 in this case). This is so called "NumberOfInstances field". The NumberOfInstances field must immediately precede the repeating group contents (repeating group instances).

Repeating Group

The FIX repeating group is represented with the biz.onixs.fix.engine.Group class.

To get the biz.onixs.fix.engine.Group object that represents the existing repeating group of the message the biz.onixs.fix.engine.Message.getGroup(int numberOfInstancesTag) method is used.

To create a new repeating group or modify the number of instances in the existing one the biz.onixs.fix.engine.Message.setGroup(int numberOfInstancesTag, int numberOfInstances) method is used.

To remove a repeating group method biz.onixs.fix.engine.Message.remove(int numberOfInstancesTag) is used.

The Group class works with fields and embedded repeating groups in the same manner as the biz.onixs.fix.engine.Message class, but each method has an additional parameter that defines the index of the repeating group instance (starting from 0).

Setting Value

Example.

class RepeatingGroupSettingValue {
    private static final Logger LOG = LoggerFactory.getLogger(RepeatingGroupGettingValue.class);

    public static void main(String[] args) {
        final Engine engine = Engine.init();
        final Message message = new Message("V", Version.FIX42);
        message.set(Tag.MDReqID, "ABSD");
        message.set(Tag.SubscriptionRequestType, 1);
        message.set(Tag.MarketDepth, 1);
        message.set(Tag.MDUpdateType, 1);
        message.set(Tag.AggregatedBook, "N");
        // create a repeating group NoMDEntryTypes with two instances
        final Group groupMDEntryTypes = message.setGroup(Tag.NoMDEntryTypes, 2);
        groupMDEntryTypes.set(Tag.MDEntryType, 0, "EntryType_1"); // first instance
        groupMDEntryTypes.set(Tag.MDEntryType, 1, "EntryType_2"); // second instance
        // create a repeating group NoRelatedSym with two instances
        final Group groupRelatedSym = message.setGroup(Tag.NoRelatedSym, 2);
        groupRelatedSym.set(Tag.Symbol, 0, "EURUSD_0"); // first instance
        groupRelatedSym.set(Tag.Symbol, 1, "EURUSD_1"); // second instance
        message.validate();
        LOG.info("Message: {}", message);
        engine.shutdown();
    }
}

Getting Value

Example.

class RepeatingGroupGettingValue {
    private static final Logger LOG = LoggerFactory.getLogger(RepeatingGroupGettingValue.class);

    public static void main(String[] args) {
        final Engine engine = Engine.init();
        final Message message = new Message("8=FIX.4.2\u00019=142\u000135=V\u000149=0\u000156=0\u000134=0\u0001" +
                "52=99990909-17:17:17\u0001262=ABSD\u0001263=1\u0001264=1\u0001265=1\u0001266=N\u0001267=2\u0001" +
                "269=EntryType_1\u0001269=EntryType_2\u0001146=2\u000155=EURUSD_0\u000155=EURUSD_1\u000110=163\u0001");
        LOG.info("MDEntryTypes group");
        final Group mdEntryTypes = message.getGroup(Tag.NoMDEntryTypes);
        if (mdEntryTypes != null) {
            for (int i = 0; i < mdEntryTypes.getNumberOfInstances(); i++) {
                LOG.info("Instance # {}", i);
                LOG.info("MDEntryType = '{}'", mdEntryTypes.get(Tag.MDEntryType, i));
            }
        }
        LOG.info("RelatedSym group");
        final Group relatedSym = message.getGroup(Tag.NoRelatedSym);
        if (relatedSym != null) {
            for (int i = 0; i < relatedSym.getNumberOfInstances(); i++) {
                LOG.info("Instance # {}", i);
                LOG.info("Symbol = '{}'", relatedSym.get(Tag.Symbol, i));
            }
        }
        engine.shutdown();
    }
}

Accepting Dynamic Sessions

Sometimes there is a requirement to accept an incoming FIX session "on the fly", without the prior creation of the Session object. The Engine exposes an ability to create session object in response to the incoming FIX connection. To take advantage of this feature it is necessary to subscribe to the DynamicAcceptor event in the Engine object.

The event arguments object provides information to make decision whether to accept connection:

To accept the incoming connection:

  1. Session object needs to be created using session identification information (session id) provided in the event arguments or logon message
  2. created Session object is passed to the createdSession property of the Engine.DynamicAcceptorArgs.

Otherwise the incoming connection will be rejected. Optionally a reject reason can be passed to the event arguments object.

Example:

public class DynamicAcceptorSample {
    private void run() {
        final EngineSettings engineSettings = new EngineSettings();
        engineSettings.addListenPort(4500);
        final Engine engine = Engine.init(engineSettings);
        engine.setDynamicAcceptorListener(new AcceptingLogic());
        Utils.waitForEnterToTerminateApp();
        engine.shutdown();
    }

    public static void main(String[] args) {
        (new DynamicAcceptorSample()).run();
    }

    class AcceptingLogic implements Engine.DynamicAcceptorListener {
        public void onDynamicAcceptor(Object sender, Engine.DynamicAcceptorArgs args) {
            final SessionId sessionId = args.getSessionId();
            System.out.println("Dynamic acceptor: " + sessionId + ", logon message " + args.getIncomingLogonMessage());
            final Session session = new Session(sessionId);
            System.out.println("Session created: " + session);
            args.setCreatedSession(session);
        }
    }

    class RejectingLogic implements Engine.DynamicAcceptorListener {
        public void onDynamicAcceptor(Object sender, Engine.DynamicAcceptorArgs args) {
            final SessionId sessionId = args.getSessionId();
            System.out.println("Dynamic acceptor: " + sessionId + ", logon message " + args.getIncomingLogonMessage());
            args.setRejectReason("Face control failed");
        }
    }
}

Session States

To obtain the current session state the biz.onixs.fix.engine.Session.getState() method is used.

The states of the FIX session are listed below.

FIX Session States
State Role: Acceptor Role: Initiator
DISCONNECTED
The session is disconnected.
AWAIT_LOGON
The session is waiting for the initial Logon message.
N/A
AWAIT_CONFIRMING_LOGON
N/A
The initial Logon message was sent and the session is waiting for the acknowledgment Logon message.
ESTABLISHED
The session is fully established (after the successful Logon exchange).
RECONNECTING Session-initiator is trying to restore the telecommunication link.
N/A
AWAIT_CONFIRMING_LOGOUT
The initial Logout message was sent and the session is waiting for the acknowledgment Logout message.
WAIT_FOR_RETRANSMISSION
The session is waiting for the message retransmission from the counterparty.

To be notified about the changes in the session state implement biz.onixs.fix.engine.Session.StateChangeListener and the register it as event handler by the biz.onixs.fix.engine.Session.setStateChangeListener(biz.onixs.fix.engine.Session.StateChangeListener listener).

Example:

import biz.onixs.fix.engine.Session;
import biz.onixs.fix.engine.Version;

class SessionListener implements Session.StateChangeListener {
    private static final String SENDER_COMP_ID = "AcceptorAndInitiator_SND";
    private static final String TARGET_COMP_ID = "AcceptorAndInitiator_TRG";
    private static final Version VERSION = Version.FIX42;

    public void onStateChange(Object sender, Session.StateChangeArgs e) {
        System.out.println("New session state: " + e.getNewState());
        // processing of the application-level incoming message...
    }
    
	public static void main(String[] args) {
        try {
            final Engine engine = Engine.init();
            Session sn = new Session(SENDER_COMP_ID, TARGET_COMP_ID, VERSION);
            SessionListener listener = new SessionListener();
            sn.setStateChangeListener(listener);
            // ...
        } catch (Exception ex)
            System.out.println("Exception: " + ex);
        }
    }
}

Session Events and Listeners

The events of the biz.onixs.fix.engine.Session class are listed below.

Warning. It is critical to avoid

in the session event listener calling thread. Please do it from another thread.

Session Listeners and Events
Event Listener Event Description
biz.onixs.fix.engine.Session.StateChangeListener Session state is changed.
biz.onixs.fix.engine.Session.ErrorListener Error condition is detected.
biz.onixs.fix.engine.Session.InboundApplicationMessageListener Application-level message is received from the counterparty.
biz.onixs.fix.engine.Session.InboundSessionMessageListener Session-level message is received from the counterparty.
biz.onixs.fix.engine.Session.OutboundApplicationMessageListener Application-level message will be sent to the counterparty.
biz.onixs.fix.engine.Session.OutboundSessionMessageListener Session-level message will be sent to the counterparty.
biz.onixs.fix.engine.Session.WarningListener Warning condition is detected.
biz.onixs.fix.engine.Session.MessageResendingListener Application-level message resending request.

Example:

import biz.onixs.fix.engine.Session;
import biz.onixs.fix.engine.Engine;
import biz.onixs.fix.parser.Version;

public class SessionListener implements Session.StateChangeListener, Session.InboundSessionMessageListener,
        Session.InboundApplicationMessageListener, Session.OutboundSessionMessageListener,
        Session.MessageResendingListener, Session.OutboundApplicationMessageListener,
        Session.WarningListener, Session.ErrorListener {

    private static final String SENDER_COMP_ID = "AcceptorAndInitiator_SND";
    private static final String TARGET_COMP_ID = "AcceptorAndInitiator_TRG";
    private static final Version VERSION = Version.FIX42;

    public void onStateChange(Object sender, Session.StateChangeArgs e) {
        System.out.println("New session state: " + e.getNewState());
    }

    public void onInboundApplicationMessage(Object sender, Session.InboundApplicationMessageArgs e) {
        System.out.println("Incoming application-level message: " + e.getMsg());
    }

    public void onInboundSessionMessage(Object sender, Session.InboundSessionMessageArgs e) {
        System.out.println("Incoming session-level message: " + e.getMsg());
    }

    public void onOutboundApplicationMessage(Object sender, Session.OutboundApplicationMessageArgs e) {
        System.out.println("Outgoing application-level message: " + e.getMsg());
    }

    public void onOutboundSessionMessage(Object sender, Session.OutboundSessionMessageArgs e) {
        System.out.println("Outbound session-level message: " + e.getMsg());
    }

    public void onWarning(Object sender, Session.WarningArgs args) {
        System.out.println("Session warning: " + args.getReason());
    }

    public void onError(Object sender, Session.ErrorArgs args) {
        System.out.println("Session error: " + args.getReason());
    }

    public boolean onMessageResending(Object sender, Session.MessageResendingArgs args) {
        return false;
    }

    public static void main(String[] args) {
        try {
            final Engine engine = Engine.init();
            final Session sn = new Session(SENDER_COMP_ID, TARGET_COMP_ID, VERSION);
            final SessionListener listener = new SessionListener();
            sn.setStateChangeListener(listener);
            sn.setInboundSessionMessageListener(listener);
            sn.setInboundApplicationMessageListener(listener);
            sn.setOutboundSessionMessageListener(listener);
            sn.setOutboundApplicationMessageListener(listener);
            sn.setWarningListener(listener);
            sn.setErrorListener(listener);
            sn.setMessageResendingListener(listener);
            // ...
            engine.shutdown();
        } catch (Exception e) {
            System.out.println("Exception: " + e);
        }
    }
}

Custom Logon Message

Sometime there is need to set additional fields (e.g. Username<553>, Password<554>) in the initiation Logon message. In this case the biz.onixs.fix.engine.Session.logonAsInitiator(java.lang.String host, int port, int heartBtInt, biz.onixs.fix.engine.Message customLogonMsg) method must be used.

Example:

    Session acceptor = new Session("CustomLogonMessage_SND", "CustomLogonMessage_TRG", Version.FIX43);
    acceptor.LogonAsAcceptor();
Session initiator = new Session("CustomLogonMessage_TRG", "CustomLogonMessage_SND", Version.FIX43); Message customLogonMsg = new Message("A", Version.FIX43); customLogonMsg.set(Tag.Username, "USER_NAME"); customLogonMsg.set(Tag.Password, "PASSWORD");
initiator.LogonAsInitiator("localhost", Engine.getInstance().getListenPort(), 30, customLogonMsg); // message exchange and processing ...
acceptor.logout(); initiator.logout(); acceptor.dispose(); initiator.dispose();

Check samples/samples-buyside, the CredentialBuySide example.

Sequence Numbers Management

The expected sequence number of the next incoming message can be:

The sequence number of the next outgoing message can be:

Some implementations of FIX protocol (FIX Dialects) expect that the FIX Session coincides with FIX Connection, in other words that the sequence numbers are reset back to 1 after the Logout messages exchange. To interact with such FIX implementations, the keepSequenceNumbersAfterLogout parameter of Session's constructor should be set to false.

Reset Using ResetSeqNumFlag Field

ResetSeqNumFlag (141) field in the Logon (A) message indicates that the both sides of the FIX session should reset sequence numbers.

To send a Logon message with this field during FIX connection establishment, use the setResetSeqNumFlag parameter of the Session.logonAsInitiator(String host, int port, boolean setResetSeqNumFlag) method.

Next time when the session object is created incoming and outgoing sequence numbers:

See also: Sequence Numbers.

FIX Dialects

It is common for firms to implement slightly different interpretations of the FIX protocol (FIX dialects).

Within the FIX protocol such deviations from the FIX specification must be described in the FIX Engine, to ensure that the parsing or creation of the corresponding FIX messages are correct.

The Dialect configuration setting specifies one or several dialect definition files in XML format. The dialect definition file must conform to the dialect XML schema.

FIX dialect can be set on:

Please read details below.

Engine Level

The engine level dialect is defined by <FIX> element with no id attribute specified. The dialect defined for the engine level is set implicitly for all engine sessions.

Example
<?xml version="1.0" encoding="utf-8"?>
<Dialect xmlns="http://ref.onixs.biz/fix/dialects"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://ref.onixs.biz/fix/dialects http://ref.onixs.biz/fix/dialects/dialects-2_9.xsd">

    <FIX version="4.2"> 
        <Message type="N">        
            <Group numberOfInstancesTag="73">
                <Field tag="37"/>         
            </Group>
        </Message>
    </FIX>
</Dialect>

In this example the dialect is set for all FIX 4.2 sessions. I.e. it changes the base FIX version definitions in the engine.

You need no additional steps to start using this dialect from your code.

Session session = new Session("SenderCompID","TargetCompID", Version.FIX42);
...
Message message = new Message("D", Version.FIX42);
session.send(message);

Session Level

The session level dialect is defined by <FIX> element with id attribute specified. The dialect defined for the session level needs to be set explicitly for the selected sessions.

Example
<?xml version="1.0" encoding="utf-8"?>
<Dialect xmlns="http://ref.onixs.biz/fix/dialects"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://ref.onixs.biz/fix/dialects http://ref.onixs.biz/fix/dialects/dialects-2_9.xsd">

    <FIX version="4.2" id="MyFIX"> 
        <Message type="N">        
            <Group numberOfInstancesTag="73">
                <Field tag="37"/>         
            </Group>
        </Message>
    </FIX>
</Dialect>

In this example the dialect is defined over base FIX 4.2 version definition and has specified id. I.e. it doesn't change the base FIX version definitions in the engine.

Using FIX dialect in the code is easy.

Version version = Version.getById("MyFIX");
Session session = new Session("SenderCompID","TargetCompID", version);
...
Message message = new Message("D", version);
session.send(message);

Dialect Definition Examples

Example 1. Adding New User-Defined Field

To add a new user-defined field to a FIX Message add the corresponding <Field> entity to the FIX Dialect description file.

<?xml version="1.0" encoding="utf-8"?>
<Dialect xmlns="http://ref.onixs.biz/fix/dialects"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ref.onixs.biz/fix/dialects http://ref.onixs.biz/fix/dialects/dialects-2_9.xsd"> <FIX version="4.0"> <Message type="D"> <!-- Does not belong to Standard FIX 4.0 --> <Field tag="526" name="SecondaryClOrdID"/> </Message> </FIX> </Dialect>

Example 2. Adding New User-Defined Repeating Group

To add a new user-defined repeating group to a FIX Message add the corresponding <Group> entity to the FIX Dialect description file.

<?xml version="1.0" encoding="utf-8"?>
<Dialect xmlns="http://ref.onixs.biz/fix/dialects"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://ref.onixs.biz/fix/dialects http://ref.onixs.biz/fix/dialects/dialects-2_9.xsd">

    <FIX version="4.0">
        <Message type="D">
            <!-- Number of repeating groups for pre-trade allocation, does not belong to Standard FIX 4.0 -->
            <Group numberOfInstancesTag="78" name="NoAllocs">
                <!-- Does not belong to Standard FIX 4.0 -->
                <Field tag="79" name="AllocAccount"/>
                <!-- Does not belong to Standard FIX 4.0 -->
                <Field tag="661" name="AllocAcctIDSource"/>
                <!-- Does not belong to Standard FIX 4.0 -->
                <Field tag="736" name="AllocSettlCurrency"/>
                <!-- Other group fields -->
            </Group>
        </Message>
    </FIX>
</Dialect>

Example 3. Making Field Optional / Required

To make a field, which is required according to the FIX Protocol specification, optional, and visa-versa, add the corresponding <Field> entity to the FIX Dialect description and set the isRequired attribute accordingly.

<?xml version="1.0" encoding="utf-8"?>
<Dialect xmlns="http://ref.onixs.biz/fix/dialects"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://ref.onixs.biz/fix/dialects http://ref.onixs.biz/fix/dialects/dialects-2_9.xsd">

    <FIX version="4.0">
        <Message type="D">
            <!-- Required in Standard FIX 4.0, but optional in this FIX dialect -->
            <Field tag="21" isRequired="false" name="HandlInst"/>
            <!-- Optional in Standard FIX 4.0, but required in this FIX dialect -->
            <Field tag="109" isRequired="true" name="ClientID"/>
        </Message>
    </FIX>
</Dialect>

Example 4. Adding New User-Defined Message

To define a user-defined message add the corresponding <Message> entity to the FIX Dialect description.

<?xml version="1.0" encoding="utf-8"?>
<Dialect xmlns="http://ref.onixs.biz/fix/dialects"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://ref.onixs.biz/fix/dialects http://ref.onixs.biz/fix/dialects/dialects-2_9.xsd">

    <FIX version="4.0">
        <Message type="UserDefinedMessage_1">
            <Field tag="100"/>
            <Field tag="101"/>
        </Message>
    </FIX>
</Dialect>

Such a user-defined message can be used exactly the same way as the standard FIX Message:

Message userDefinedMsg = new Message(Version.FIX40, "UserDefinedMessage_1");
userDefinedMsg.set(100, "Field 100");
userDefinedMsg.set(101, "Field 101");
userDefinedMsg.validate();
System.out.println("User defined message: " + userDefinedMsg);

Example 5. Removing Field

To remove a field add the corresponding <Field> entity to the FIX dialect definition and use attribute mode="remove".

<?xml version="1.0" encoding="utf-8"?>
<Dialect xmlns="http://ref.onixs.biz/fix/dialects"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://ref.onixs.biz/fix/dialects http://ref.onixs.biz/fix/dialects/dialects-2_9.xsd">

    <FIX version="4.2">
<Message type="b">
<Group numberOfInstancesTag="296">
<Field tag="302" mode="remove"/>
</Group>
</Message>
</FIX>
</Dialect>

Example 6. Dialect BuySide/SellSide Applications

Check samples/samples-buyside and samples/samples-sellside for paired live applications with dialect support.

See also: Configuration → Settings.

SSL Encryption

The SSL (Secure Sockets Layer) support helps to make FIX communication secure.

The SSL support is implemented using Sun's java security / JSSE (Java Secure Socket Extension) implementation. Learn more here about java security and JSSE.

The SSL configuration procedure is slightly different for FIX acceptor and initiator sessions.

Acceptor: Configuring SSL

The acceptor SSL configuration is performed on the engine level via the following method.

Engine.setSSLContext(sslContext);
...
Engine.init(...);

Parameters:

Make sure that you configure SSL before doing engine init.

Initiator: Configuring SSL

The initiator SSL configuration is performed on the session level via the following method.

Session session = new Session("SenderCompID", "TargetCompID", fixVersion);
...
session.setSSLContext(sslContext);
...
session.logonAsInitiator(...);

Parameters:

Make sure that you configure SSL before doing session logon.

Creating SSL Context

One of the methods to create SSL context follows.

SSLContext sslContext = SslContextFactory.getInstance(keyStoreName, trustStoreName, keyPassword);

Parameters:

The key and trust stores are loaded as described in the Unified Resource Loading.

Key and Certificate Management

To perform key and certificate management the keytool can be used. This tool is a part of JDK package and the complete documentation can be found in the JDK documentation, section "JDK Tools and Utilities".

Below you can find the simplified pre-steps to do in order to organize secure communication between two parties.

Generate the key pair for the "SellSide":

keytool -genkey -keyalg RSA -dname "cn=SellSide, ou=FixEngine, o=OnixS, c=US" -alias sellside -keypass keypass1 -keystore C:\sellside.keystore.bin -validity 360

Generate the key pair for the "BuySide":

keytool -genkey -keyalg RSA -dname "cn=BuySide, ou=FixEngine, o=OnixS, c=US"  -alias buyside -keypass keypass2 -keystore C:\buyside.keystore.bin -validity 360

Export the certificate of "SellSide":

keytool -export -alias sellside -file sellside.cer -keystore C:\sellside.keystore.bin

Export the certificate of "BuySide":

keytool -export -alias buyside -file buyside.cer -keystore C:\buyside.keystore.bin

Import the certificate of "BuySide" into the "SellSide" trust store:

keytool -import -alias buyside -file buyside.cer -keystore C:\sellside.truststore.bin

Import the certificate of "SellSide" into the "BuySide" trust store:

keytool -import -alias sellside -file sellside.cer -keystore C:\buyside.truststore.bin

As a result we have two pairs of key store and trust store for each party to establish secure communication:

This is what was used for samples.

Example

Check samples/samples-buyside and samples/samples-sellside for paired live applications with SSL support.

Resources

Inbound Message Log Filtering

There is an option to skip saving of some inbound FIX messages to session storage. For instance, for a performance reason.

This can be configured on a per-session basis:

session.setInboundMessageLogFilter(messageFilter);

The messageFilter is the implementation of biz.onixs.fix.filter.MessageFilter interface.

For instance, the TypeMessageFilter implementation is used to filter specified message types:

MessageFilter messageFilter = new TypeMessageFilter("W X");
session.setInboundMessageLogFilter(messageFilter);

The space-delimited list of message types to filter is specified.

Resending Messages

When the Resend Request (2) message is received from the counterparty (e.g. due to a sequence number mismatch), MessageResending event is raised if an application has previously subscribed to this event. Otherwise, the SequenceReset-GapFill (4) message will be sent instead of the requested message.

If the sent application-level message needs to be resent to the counterparty then the return value of the MessageResending event listener should be set to true while handling the event. Otherwise the SequenceReset-GapFill (4) message will be sent instead (e.g. in case of an aged order).

The message that is about to be resent is available via Msg property of Session.MessageResendingArgs parameter.

Example.

public class MessageResendingListenerSample implements Session.MessageResendingListener {
    private void run() {
        // ...
        final Session session = new Session("SenderCompID", "TargetCompID", Version.FIX50);
        session.setMessageResendingListener(this);
        // ...
    }

    public boolean onMessageResending(Object sender, Session.MessageResendingArgs args) {
        System.out.println("Message is about to be resent to the counterpart: " + args.getMsg());
        // Return false if it's necessary to skip this message (GapFill will be sent).
        return false;
    }
	
    // ...
}

Memory Based Session Storage

Memory based session storage could be used to maintain a high-performance FIX session when persisting of session state and messages in the file system is not required.

To create such a session storageType parameter of Session constructor should be set to SessionStorageType.MemoryBasedStorage.

boolean keepSequenceNumbersAfterLogout = false;
Session session = new Session("SenderCompID", "TargetCompID", Version.FIX42, keepSequenceNumbersAfterLogout, SessionStorageType.MemoryBasedStorage);

Scrambling Password in Session Storage

For the security reasons the values of the following fields can be scrambled in the file-based session storage:

In order to achieve this on the engine level the following option can be used:

final FileBasedStorageRepository storageRepository = Engine.getStorageRepositoryManager().getFileBasedStorageRepository();
storageRepository.setScramblePassword(true);

Session Scheduler

In real life FIX connection occur at regular intervals. A lot of trading systems have public schedules which declare time frames for trading. The Session class exposes members for FIX connections basic handling. It also provides users with automatic reconnection facility in case of connection failure. However, there is no way in the Session functionality to maintain connections on systematic basis.

Session Scheduler

To satisfy the needs of real life trading schedules, the OnixS Java FIX Engine offers the Sessions Scheduler. This service will automatically connect certain FIX sessions to the counterpart at the beginning of the trading day as well as disconnect at the end of a day. It is also possible to keep a FIX Session connected for an entire trading week and disconnect it at the end of last trading day.

Main Class

The SessionScheduler is a workhorse class of the Sessions Scheduler component. This class exposes a simple but comprehensive API to handle connections by schedules of any complexity.

Registering a Session

The register method schedules a session for automatic logon and logout according to the specified session schedule.

If a Session is being registered at the time noted by schedule, the the scheduler will connect the Session immediately.

Un-registering a Session

The unregister method removes specified session from the scheduling service.

The unregister method doesn't disconnect active session from trading system. Therefore, if session was already connected by scheduler, it remains connected after unregistering.

Error Notification

The Scheduler exposes Error event to get notified about errors in session management.

Programmatic Configuration

There are different session schedule implementation classes.

SingleDayLengthSchedule and MultiDayLengthSchedule

The first two parameters (firstDay and lastDay) define activity week. During these days the session will always be connected at logon time and disconnected at logout time if specified session duration equals to a single day. If the session must continue for several days, then the scheduler will connect session at logon time on the day specified by the firstDay parameter and disconnected at logout time on the day specified by lastDay parameter.

The logonTime and logoutTime parameters respectively define time of logon and logout for the session for each activity day if session duration is a single day. If the session must continue for the entire week, then logonTime parameter value specifies the time for logon to be performed on the first day of activity week and logoutTime parameter value defines the time of logout performed on the last day of the activity week.

Finally the resetPolicy parameter specifies whether the session sequence numbers must be reset and on which basis (never, daily or weekly).

Example

Check samples/samples-scheduling, the ProgramScheduleSample example.

File-based Configuration

To simplify development, the Session Scheduler provides an option to define session schedules and connection settings in the configuration file for later referencing in the source code.

The presets defined in the configuration file can be loaded using SchedulerSettingsLoader class. Then both schedules and connection settings can be referenced in the source code using the string identifiers.

Configuration File Reference

The configuration file has XML-based format. The appropriate XML schema is available here.

Example

Check samples/samples-scheduling, the FileScheduleSample example.

Logon Password Authentication

When Accepting an incoming FIX connection additional authentication checks may be required. The typical checks are Logon username/password and source IP address. Depending on the result of the logon verification check the decision can be made whether to Accept the FIX connection or reject and close the connection. This is typically performed at the logon stage.

In order to achieve this you should subscribe to the inbound session messages and add the required check logic. If the check fails and the FIX connection needs to be rejected (closed) then an exception can be thrown from the inbound session message listener.

In the following example the password authentication check is demonstrated.

public class LogonPasswordVerification implements Session.InboundSessionMessageListener {
    private void run() {
	    // ...
        session.setInboundSessionMessageListener(this);
		// ...
    }

    public void onInboundSessionMessage(Object sender, Session.InboundSessionMessageArgs args) {
        final Message message = args.getMsg();
        if (message.getType().equals(FIX43.MsgType.Logon)) {
            // ...
            if (! "ExpectedPassword".equals(message.get(FIX43.Tag.Password))) {
                throw new RuntimeException("Password is incorrect");
            }
            // ...
        }
    }
}

The text from the exception goes to the FIX logout message text field (Text<58>).

Examples

Check samples/samples-buyside/Credential and samples/samples-sellside/Credential examples pair.

FIX ↔ FIXML Converter

This tool enables converting FIX message to FIXML and vice versa. The following sample code demonstrates how simple it is.

public class FixmlConverterSample {
    private static final Logger LOG = LoggerFactory.getLogger(FixmlConverterSample.class);

    public static void main(String[] args) throws Exception {
        final Engine engine = Engine.init(-1);
        final FixmlConverter converter = new FixmlConverter("src/main/conf/sample/schema", Version.FIX44);
        //
        final String inFixFile = "sample/Order.txt";
        LOG.info("Loading FIX message from file: {}", inFixFile);
        final Message inFixMessage = Utils.readFixMessage(inFixFile);
        LOG.info("Input FIX message: {}", inFixMessage);
        String fixmlMessage = converter.fix2fixml(inFixMessage);
        LOG.info("Output converted FIXML message: {}", fixmlMessage);
        //
        final String inFixmlFile = "sample/ExecRpt.xml";
        LOG.info("Loading FIXML message from file: {}", inFixmlFile);
        final String inFixmlMessage = Utils.readFixmlMessage(inFixmlFile);
        LOG.info("Input FIXML message: {}", inFixmlMessage);
        final Message outFixMessage = converter.fixml2fix(fixmlMessage);
        LOG.info("Output converted FIX message: {}", outFixMessage);
        //
        engine.shutdown();
    }
}

Examples

Check samples/samples-fixml-converter examples.

FAST Encoding and Decoding

FAST is a binary encoding method for message oriented data streams. FAST is an acronym for FIX Adapted for STreaming. The original purpose of FAST was optimization of FIX messages.

Decoding in 4 Steps

In order to decode FAST data to FIX message the following 4 steps are required:

  1. FIX Engine Initialization
  2. Template Library Loading
  3. Decoding
  4. FIX Engine Shutdown

FIX Engine Initialization

The FIX engine must be initialized as described in the following section. The appropriate FIX dialect must be configured during this step if necessary as described here.

Template Library Loading

To load FAST templates from an XML source the following code sequence can be used.

XmlTemplateLoader templateLoader = new DomXmlTemplateLoader();
InputStream is = new FileInputStream("templates.xml");
TemplateLibrary templateLibrary = templateLoader.load(is);

Decoding

Create Decoder instance first.

Decoder decoder = new Decoder(templateLibrary, FastVersion.FAST_1_1, Version.FIX50);

Decode FAST stream chunks then.

Message fixMessage = decoder.decode(data);

FIX Engine Shutdown

The FIX engine must be shutdown as described in the following section.

Example

Check samples/samples-fast for FAST related examples.

Examples

A lot of examples can be found in the samples directory. The examples are categorized by sub-directories.

In most cases the example sub-directory contains Readme.html file with the important information - configuration, startup, etc.

Eclipse Project

The examples are ready to be opened in the Eclipse Java IDE, the workspace is pre-created for your convinience. However, the additional configuraion steps are required:

Glossary

Acceptor

Session-acceptor is the receiving party of the FIX session. It listens for the incoming connection on the pre-defined port. The acceptor has responsibility to perform first level authentication and formally declare the connection request "accepted" through transmission of an acknowledgment Logon message.

Conditionally Required Fields

Fields which are required based on the presence or value of other fields.

Delimiter Character

The non-printing, ASCII "SOH" (\u0001, hex: 0x01, referred to in this document as <SOH>), is used for field termination.

MsgSeqNum Field

Integer message sequence number, the tag number is 34.

FIX

The Financial Information Exchange (FIX) Protocol is a message standard developed to facilitate the electronic exchange of information related to securities transactions. It is intended for use between trading partners wishing to automate communications.

FIX Connection

It is comprised of three parts: logon, message exchange, and logout.

FIX Dialect

This is a custom, slightly different interpretation of FIX protocol.

FIX Session

It is comprised of one or more FIX Connections, meaning that a FIX Session spans multiple logins.

Initiator

Session-Initiator establishes the telecommunications link and initiates the session via transmission of the initial Logon message.

Required Fields

Each message within the FIX protocol is comprised of required, optional and conditionally required fields (fields which are required based on the presence or value of other fields). Systems should be designed to operate when only the required and conditionally required fields are present.

Unknown Fields

Fields in a FIX message that are not expected in accordance with the FIX protocol or its dialect.

SenderCompID Field

Assigned value used to identify firm sending message, the tag number is 49.

TargetCompID Field

Assigned value used to identify receiving firm, the tag number is 56.

User-defined Fields

These fields are intended to be implemented between consenting trading partners and should be used with caution to avoid conflicts, which will arise as multiple parties begin implementation of the protocol. The tag numbers 5000 to 9999 have been reserved for them. These tags can be registered/reserved via the FIX website.

User-defined Messages

Messages those format is privately defined between the sender and receiver. A "U" as the first character in the MsgType field (i.e. U1, U2, etc) indicates such messages.

FAST

The binary encoding method for message oriented data streams. FAST is an acronym for FIX Adapted for STreaming.

Resources


© Onix Solutions