ZagTrader

Custom Fields and a Custom Data Dictionary in QuickFIX

Written and maintained by ZagTrader. Last reviewed . How this page is sourced and checked

Most counterparties add fields of their own, usually numbered 5000 and above, and some change which standard fields a message may carry. QuickFIX checks every incoming message against its data dictionary, so those fields are rejected until the dictionary knows them. The fix is a copy of the standard dictionary with the counterparty's changes, not switching validation off.

Add a field in three places

Start from the dictionary for your FIX version that ships with the engine (FIX44.xml, FIX50SP2.xml) and save it under a new name. A field needs:

  1. A definition in the <fields> section with a number, a name and a type.
  2. An entry in each message that may carry it, under <messages>, marked required="Y" or required="N".
  3. Enumerated values, if the counterparty lists them, as <value> elements. Other values are then rejected with 373=5.
A custom tag 5001 allowed on New Order Single
<messages>
  <message name="NewOrderSingle" msgtype="D" msgcat="app">
    <field name="ClOrdID" required="Y"/>
    <!-- the standard fields of the message stay as they are -->
    <field name="StrategyCode" required="N"/>
  </message>
</messages>

<fields>
  <field number="5001" name="StrategyCode" type="STRING">
    <value enum="VWAP" description="VWAP"/>
    <value enum="TWAP" description="TWAP"/>
  </field>
</fields>
  • Names must be unique and must match between the message entry and the field definition. A field used in a message but missing from <fields> stops the engine at start.
  • Pick the type the counterparty specifies: STRING, INT, PRICE, QTY, CHAR, BOOLEAN, UTCTIMESTAMP and so on. A wrong type produces incorrect data format rejects for valid values.
  • Point the session at the new file: DataDictionary= for FIX 4.x, AppDataDictionary= for FIX 5.0 and later.

Settings that relax the checks

When you cannot get a full specification, these settings stop specific rejects. Each one hides real errors too, so prefer a correct dictionary.

SettingEffect
ValidateUserDefinedFields=NFields numbered 5000 and above that the dictionary does not define, or does not allow in that message, are accepted.
AllowUnknownMsgFields=YStandard fields below 5000 that the dictionary does not allow in that message are accepted.
AllowUnknownEnumValues=YValues outside an enumeration are accepted (QuickFIX/J 3.x and QuickFIX/n).
ValidateFieldsOutOfOrder=NHeader fields found in the body are accepted.
UseDataDictionary=NNo validation at all, and repeating groups are not parsed. Avoid on order flow.

Reading and setting custom fields in code

  • Without generated classes, use the generic accessors with the tag number: in QuickFIX/J message.setString(5001, "VWAP") and message.getString(5001). QuickFIX/n and QuickFIX C++ have the same idea with typed field objects.
  • Reading a field that is not there throws a field-not-found exception. Thrown from your message handler, it turns into a Conditionally Required Field Missing reject to the counterparty, so check for optional fields first.
  • To get typed classes for custom fields and messages, regenerate the message classes from your dictionary. QuickFIX/J documents this as building custom artefacts; QuickFIX/n and QuickFIX C++ ship generators in their repositories.

Test the dictionary before go-live

Load the same XML into the parser's venue dictionary: open the parser, choose Venue dictionary in the toolbar and load the file. Paste certification messages or a log; custom tags get their names, new values are accepted, and anything the dictionary would reject is flagged. The file is read in your browser and kept only on your device.

Questions

Why does QuickFIX reject my custom tag?
Because the data dictionary does not define it, or does not allow it in that message type. Add the field definition and the message entry, or set ValidateUserDefinedFields=N for tags of 5000 and above.
Where do custom tags start?
The user-defined range starts at 5000. QuickFIX uses 5000 as the line between ValidateUserDefinedFields and AllowUnknownMsgFields.
Can one QuickFIX application use different dictionaries per counterparty?
Yes. DataDictionary or AppDataDictionary is a per-session setting, so each [SESSION] can point at its own file.

The FIX side of the problem

What the error means on any FIX engine, with example messages you can open in the parser:

Reference

Sources

  1. QuickFIX/J source: DataDictionary.java (field checks)
  2. QuickFIX/J user manual: Configuration
  3. QuickFIX/J source: ValidationSettings.java (validation defaults)
  4. QuickFIX/J README: runtime artefacts per FIX version
  5. QuickFIX/n documentation: Custom fields, groups and messages
  6. QuickFIX/n documentation: Configuration
  7. QuickFIX C++ documentation: User defined fields
  8. QuickFIX C++ documentation: Validation

Setting names, defaults and message texts were checked against the projects' source code and documentation on the review date shown at the top of the page. Behaviour can change between releases; check the version you run. This guide is independent and not affiliated with the QuickFIX projects.

See also

More QuickFIX guides