Structure of FIX Repeating Groups
Sometimes fields of the same tag number can appear multiple times in the same message within a so-called repeating group.
The following diagram depicts a general structure of the repeating group in a FIX message:
Each repeating group starts from the field which identifies the number of repeating entries within a repeating group. Such a leading field must precede immediately the repeating group entries. In the referenced example, the leading field is defined by the
Each entry of a repeating group has a selected leading field, which in turn identifies the beginning of a new group entry. This field must occur in the raw message before any other tag from a single repeating group entry. In other words, these fields separate repeating group entries from each other. The
RoutingType field is an example of such a separator.
Important aspects of FIX repeating groups structure:
- Well-defined FIX messages assume all fields of a repeating group that follow one another. The appearance of an arbitrary field, which doesn't belong to the repeating group (according to the FIX specification), automatically indicates the end of the repeating group. Therefore, the further appearance of fields from the repeating group is disallowed by FIX Standard.
- It is possible for repeating groups to appear inside of another repeating group. In such a case, all entries of the inner repeating group belong to the single entry of the outer repeating group.
- The number of entries or instances, which are defined by the value of the leading field (tag), must correspond to the number of instances/entries which actually appear in the message. In particular, the number of tags-separators must be equal to the value of the leading field.
OnixS C++ FIX Engine exposes the OnixS::FIX::Group class to encapsulate all aspects that are related to handling FIX repeating groups.
Since a repeating group is identified by the leading field, which defines the number of repeating instances, C++ FIX Engine follows this approach in handling repeating groups. In particular, the OnixS::FIX::Group object is accessed, using its leading (number of instances) field. Changing the value of this field affects the length of the repeating group. Removing this field from a message or other repeating group removes all entries of the repeating group.
Adding Group to Message
To create a new repeating group or modify the number of instances, the OnixS::FIX::Message::setGroup method is available.
- Setting non-zero integer value for the field, which defines a number of instances of a repeating group, implicitly creates and/or changes the length of the repeating group object.
using namespace OnixS::FIX::FIX42;
groupMDEntryTypes = request.setGroup(Tags::NoMDEntryTypes, 2);
groupRelatedSym = request.getGroup(Tags::NoRelatedSym);
std::clog << request.toString
() << std::endl;
Accessing Repeating Group Entries
To obtain a reference to the OnixS::FIX::Group object, that represents an existing repeating group of the message, the OnixS::FIX::Message::getGroup method is available.
The OnixS::FIX::Group class works with fields, as well as with embedded repeating groups, in the same manner as the OnixS::FIX::Message class. The only difference in accessing field values is the availability of an additional parameter, which defines the index of the repeating group entry whose field is being accessed. The indexing entry starts from zero. Additionally, you can use the OnixS::FIX::Group::Iterator class to iterate over all group entries of a repeating group.
using namespace OnixS::FIX::FIX42;
std::clog << "BidSize="
(Tags::BidSize) << std::endl
(Tags::OfferSize) << std::endl;
std::string rawMessage = "8=FIX.4.2\0019=128\00135=i\00134=2\00149=PXMD\00152=20140922-14:48:49.825\00156=Q037\001117=1\001296=1\001"
for (size_t quoteSetsIndex = 0; quoteSetsIndex < quoteSets.size(); ++quoteSetsIndex)
quoteEntries = quoteSets[quoteSetsIndex].getGroup(Tags::NoQuoteEntries);
Removing Repeating Group from Message
To remove an entire repeating group together with its leading tag, the OnixS::FIX::FieldSet::erase method is exposed by OnixS::FIX::Message and the OnixS::FIX::Group class.
Detecting Ill-Formed Repeating Group
Due to the design of the FIX protocol, the FIX repeating group cannot be parsed properly without the additional information that describes its structure. This is a well-known feature/flaw of the FIX protocol - and is applicable to any software that parses FIX repeating groups. If the FIX destination you work with uses non-standard (custom) fields in the repeating group, then the FIX Engine needs the corresponding XML-based FIX Dialect description file. In a well-formed repeating group, the declared number of repeated instances (defined by the number of instances field) should be equal to the actual number of instances. By default, the FIX Engine reports an error if the incoming message does not meet this requirement. This behavior could be changed via the OnixS::FIX::EngineSettings::validateRepeatingGroupEntryCount setting.
- It is not recommended to set the OnixS::FIX::EngineSettings::validateRepeatingGroupEntryCount setting to false because this can lead to data loss during the message parsing without any notification about an error.
By default, the FIX Engine does not check that each repeating group instance starts with the correct leading field. This behavior could be changed via the OnixS::FIX::EngineSettings::validateRepeatingGroupLeadingTag setting. It is also possible to detect the ill-formed repeating group using the OnixS::FIX::Message::validate method.
- See also