ZagTrader

Repeating Groups in QuickFIX: Reading, Writing and Validation Errors

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

A repeating group is a count field followed by that many sets of fields, such as NoPartyIDs (453) followed by PartyID (448), PartyIDSource (447) and PartyRole (452) for each party. QuickFIX can only split the sets apart if it knows the group from the data dictionary, which is why most group problems are dictionary problems.

The rules QuickFIX applies

  • The count field (NumInGroup) comes first and must equal the number of sets that follow. Otherwise the message gets 373=16.
  • Every set starts with the same field, the delimiter: the first field of the group in the dictionary. For Parties that is PartyID (448).
  • Inside a set, fields follow the dictionary order. A field out of place gets 373=15 in QuickFIX/J unless ValidateUnorderedGroupFields=N.
  • With UseDataDictionary=N, QuickFIX cannot parse groups. The fields are still in the message, but you cannot read them as groups.
Two parties on a FIX 4.4 New Order Single (SOH shown as |)
453=2|448=BRK01|447=D|452=1|448=CLIENT-42|447=D|452=3|

Reading a group

In all three engines, group entries are numbered from 1, not 0. Ask for the count first and loop up to it.

QuickFIX/J
int count = order.getInt(NoPartyIDs.FIELD);
for (int i = 1; i <= count; i++) {
    NewOrderSingle.NoPartyIDs party = new NewOrderSingle.NoPartyIDs();
    order.getGroup(i, party);
    String id = party.getString(PartyID.FIELD);
}
QuickFIX/n
int count = order.GetInt(Tags.NoPartyIDs);
for (int i = 1; i <= count; i++) {
    var party = new NewOrderSingle.NoPartyIDsGroup();
    order.GetGroup(i, party);
    string id = party.GetString(Tags.PartyID);
}

Asking for entry 0, or for one past the count, throws a field-not-found exception. In a message handler that becomes a Conditionally Required Field Missing reject sent to the counterparty.

Adding a group

  • Create the group object of the message's own class (in QuickFIX/J NewOrderSingle.NoPartyIDs), set its fields, and add it with addGroup. QuickFIX sets the count for you.
  • Use the group class of the right FIX version and message. The generic group class needs the count tag and the delimiter tag, and writing fields in another order than the dictionary produces messages the counterparty rejects.
  • Re-use a group object only after you have added it; addGroup copies it.

Custom groups

A counterparty may add fields to a standard group or define a group of its own. Both go in the dictionary, inside the message:

<group name="NoPartyIDs" required="N">
  <field name="PartyID" required="N"/>
  <field name="PartyIDSource" required="N"/>
  <field name="PartyRole" required="N"/>
  <field name="PartyDesk" required="N"/>
</group>

The first field listed is the delimiter. Keep it first even when you add fields, and define new fields such as PartyDesk in the <fields> section as described in custom fields and a custom dictionary.

Questions

Are QuickFIX group indexes 0-based or 1-based?
1-based in QuickFIX/J, QuickFIX/n and QuickFIX C++. getGroup(1, group) reads the first entry.
Why does QuickFIX say "Out of order repeating group members"?
A field inside a group set is not in the order the dictionary gives, or the set does not start with the delimiter field. That is SessionRejectReason 15.
Can I turn off group order checks?
In QuickFIX/J, ValidateUnorderedGroupFields=N accepts members in any order after the delimiter, and FirstFieldInGroupIsDelimiter=Y (3.x) takes the delimiter from the message. Fix the dictionary first.

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 user manual: Repeating groups
  2. QuickFIX/J user manual: Configuration
  3. QuickFIX/J source: DataDictionary.java (field checks)
  4. QuickFIX/J source: DefaultSessionFactory.java (required settings and defaults)
  5. QuickFIX/n documentation: Repeating groups
  6. QuickFIX C++ documentation: Repeating groups

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