Usage

The FIX Converter defines two classes for describing a tag=value message. The FixTag class has an integer ID and a byte array as its value. Getters and setters are provided to access these. The FixTagMessage class is basically a Vector of FixTags.

FIXML documents are manipulated in org.w3c.dom.Document form.

Bytes to tag=value

Your FIX Engine may already be providing you with a tag=value representation of your message, in which case, use the methods on FixTag and FixTagMessage to make your FixTagMessage. If not, read on...

To use the FIX converter to parse an array of bytes into its representation of a FIX message in tag=value format, use :-

import org.fixprotocol.contrib.converter.*;

Document d = parsed FixRepository.xml
FixConv fc = new FixConv(d);
byte[] b = the FIX message
FixTagMessage ftm = fc.bytesToFixTagMessage(
  b,
  extMaj, // eg: "4", "5", or null
  extMin, // eg: "4", "0", or null
  extSP,  // eg: "SP1", "SP2", or null
  extEP,  // eg: "EP196", or null
  extCv   // eg: "jpmc-to-lse-custom-version", or null
  );

If the tags (BeginString (8), then possibly the ApplVerID (1128) tag, possibly the AppExtID (1156) tag, and then possibly the CstmApplVerID (1129) tag) identify a version of FIX that is not present in the repository, then the FIX message may not be decoded properly.

If the message doesn't fully define its version, and non-null external values are passed in, then these are used.

Often people edit FIX messages in text editors and don't get it right, especially when preparing test data. They might miss the BeginString, forget the BodyLength, or calculate the CheckSum incorrectly. A method is provided to repair FixTabMessages with these problems :-

ftm.repair();

Note that text editors often append \n or \r\n to the end of each line. You'll need to have stripped this prior to calling bytesToFixTagMessage.

tag=value to bytes

To convert a FixTagMessage back to bytes, you can either :-

byte[] b = fc.fixTagMessageToBytes(ftm);

or :-

byte[] b = ftm.toBytes();

The FixTagMessage also has a handy .toString() method which produces a printable string representation, which is intended primarily for debug purposes. In this printable form, the \xHH notation is used for unprintable ASCII characters, so the SOH characters for example appear as \x01.

tag=value to FIXML

To convert a FixTagMessage to FIXML :-

Document d = fc.tagToXml(
  ftm,    // the FixTagMessage
  extMaj, // eg: "4", "5", or null
  extMin, // eg: "4", "0", or null
  extSP,  // eg: "SP1", "SP2", or null
  extEP,  // eg: "EP196", or null
  extCv   // eg: "jpmc-to-lse-custom-version", or null
  );

The FixTagMessage must obey a minimum of FIX rules, including :-

  • the first tag must be BeginString (8)
  • the second tag must be BodyLength (9), although its not checked
  • the third tag must be MsgType (35)
  • for FIX.5.0 onwards, the ApplVerID (1128) tag should define the FIX application version, including service pack number
  • for FIX.5.0 onwards, the ApplExtID (1156) tag can be used to define the extension pack.
  • for FIX.5.0 onwards, if a bi-laterially agreed custom version of FIX is being spoken, the CstmApplVerID (1129) tag must identify that version, and that same ID must match the customVersion attribute in the Unified FIX Repository
  • if there are any encoded tags (eg: Japanese names in the Shift_JIS encoding), then the MessageEncoding tag has to be present

For FIX.5.0 onwards, if the ApplVerID tag is not found, the extMaj and extMin values are used (possibly with the extSP appended, if defined). If the ApplExtID tag is not found, the extEP is used if present. If the CstmApplVerID tag is not found, the extCv is used if present. If these external values are needed, and are not supplied, then an exception is thrown.

The generated XML will have the elements in the correct namespace, eg:

  • FIX 4.4 - http://www.fixprotocol.org/FIXML-4-4
  • FIX 5.0 - http://www.fixprotocol.org/FIXML-5-0
  • FIX 5.0SP2 - http://www.fixprotocol.org/FIXML-5-0-SP2
  • FIX 5.0SP3 onwards - http://www.fixprotocol.org/FIXML-5

If the input tag=value message has the ApplExtID (1156) tag or if extEP was supplied, then the resulting FIXML message has the xv attribute.

Certain tags in the FixTagMessage must be in the places described by the rules above. The converter will accept other tags in messages and components in orders different to that in the Unified FIX Repository. Rules relating to repeating groups NoXxx tags, and the first tag in each group must still be adhered to (else the message can't be processed).

tag=value to pretty string

To convert a FixTagMessage to a printable string, you can :-

String s = fc.fixTagMessageToPretty(
  ftm,
  extMaj, // eg: "4", "5", or null
  extMin, // eg: "4", "0", or null
  extSP,  // eg: "SP1", "SP2", or null
  extEP,  // eg: "EP196", or null
  extCv   // eg: "jpmc-to-lse-custom-version", or null
  );

This produces a string with one line per field, with each tag annotated with its name. Sometimes it can be easier to read a FIX tag=value message this way.

This method has to operate on an instance of a FixConv as it needs access to the Unified FIX Repository that has been loaded.

The the message doesn't fully define its version, and non-null external values are passed in, then these are used.

FIXML to tag=value

To convert from FIXML to tag=value :-

List<FixTagMessage> ftms = fc.xmlToTag(
  d,      // the FIXML document
  extMaj, // eg: "4", "5", or null
  extMin, // eg: "4", "0", or null
  extSP,  // eg: "SP1", "SP2", or null
  extEP,  // eg: "EP196", or null
  extCv   // eg: "jpmc-to-lse-custom-version", or null
  );

The FIXML document is expected to have its elements in the correct namespace. The code still works if no namespace is employed, but you may have to help it determine the version (see the versioning algorithm below for details).

The conversion algorithm inspects the namespace to work out what it can about the major, minor and service pack number of the message. It then looks for the v attribute on the root FIXML element, and also the cv attribute for the custom version. If this is insufficient, it tries to complete the picture by using the external version information passed into the xmlToTag method.

The version algorithm is as follows :-

  if namespace missing or doesn't define major and minor
    if FIXML v attribute present
      use it
    else
      if extMaj and extMin supplied
        use them
      else
        error
    append extSP if supplied
  else if namespace defines major only // this is the new FIX.5.0SP3 onwards style
    if FIXML v attribute present
      use it
      if namespace disagrees with major number in FIXML v attribute
        error
    else
      if extMaj and extMin is supplied
        use them
      else
        error
    append extSP if supplied
  else namespace defines major and minor (and possibly service pack too)
    use them
    if FIXML v attribute present
      if namespace disagrees with info in FIXML v attribute
        error

Apologies for the above, but I didn't define the standard. This is an attempt to try to do the right thing by default.

The extension pack algorithm is as follows :-

  if FIXML xv attribute present
    use it
  else if extEP supplied
    use it
  else
    no extension pack

The custom version algorithm is as follows :-

  if FIXML cv attribute present
    use it
  else if extCv supplied
    use it
  else
    normal, non-customised version

If the input FIXML message has the xv attribute, or if extEP is supplied, then the resulting tag=value message will have the AppExtID (1156) tag.

You may have noticed the result is a list of tag=value messages. This is because FIXML documents may contain a Batch of messages, eg:

<FIXML xmlns="http://www.fixprotocol.org/FIXML-4-4" v="4.4">
    <Batch>
        <!-- This header applies to all the messages -->
        <Hdr Snt="2001-09-11T09:30:47-05:00" PosDup="N" PosRsnd="N"
            SeqNum="521" SID="AFUNDMGR" TID="ABROKER"/>
        <Order ID="123456" Side="2" TxnTm="2001-09-11T09:30:47-05:00"
               Typ="2" Px="93.25" Acct="26522154">
            <Instrmt Sym="IBM" ID="459200101" Src="1"/>
            <OrdQty Qty="1000"/>
        </Order>
        <!-- This second message is a copy of the first, with different ID -->
        <Order ID="123457" Side="2" TxnTm="2001-09-11T09:30:47-05:00"
               Typ="2" Px="93.25" Acct="26522154">
            <!-- I've also included a message specific header -->
            <Hdr PosDup="Y"/>
            <Instrmt Sym="IBM" ID="459200101" Src="1"/>
            <OrdQty Qty="1000"/>
        </Order>
    </Batch>
</FIXML>

The converter will ensure each output message has tags from the Batch Hdr, with any values added or overwritten in the individual message Hdrs.

The FIX converter cannot convert a list of tag=value messages into a single FIXML document.

The generated FixTagMessages have their tags in the same order as they are defined in the Unified FIX Repository.