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 the general structure of a repeating group in a FIX message:
Each repeating group starts from the field which identifies the number of repeating entries within repeating group. Such a leading field must immediately precede the repeating group entries. In the referenced example the leading field is defined by NoRoutingIDs
tag.
Each entry of a repeating group has a selected field which in turn identifies the beginning of a group new entry. This field must occur in raw message before any other tag from a single repeating group entry. In other words, these fields separate repeating group entries from each other. RoutingType
field is an example of such separator.
Important aspects of FIX repeating groups structure:
OnixS C++ FIX Engine exposes OnixS::FIX::Group class to encapsulate all aspects related with handling FIX repeating groups.
Since a repeating group is identified by the leading field which defines the number of repeating instances, the OnixS 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 repeating group. Removing this field from a message or other repeating group removes all entries of the repeating group.
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 a field which defines a number of instances of a repeating group implicitly creates and/or changes the length of the repeating group object.
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. Entries indexing starts from zero.
To remove an entire repeating group together with its leading tag, OnixS::FIX::Message::remove method is exposed by OnixS::FIX::Message and OnixS::FIX::Group class.
// Forms 'Market Data Request' message. #include <OnixS/FIXEngine.h> using namespace OnixS::FIX; using namespace OnixS::FIX::FIX42; Message request(Values::MsgType::MarketDataRequest, FIX_42); request.set(Tags::MDReqID, "ABSD"); request.set(Tags::SubscriptionRequestType, 1); request.set(Tags::MarketDepth, 1); request.set(Tags::MDUpdateType, 1); request.set(Tags::AggregatedBook, "N"); // Creates a repeating group NoMDEntryTypes with two instances. Group* groupMDEntryTypes = request.setGroup(Tags::NoMDEntryTypes, 2); // Defines fields in the first instance/entry of repeating group.. groupMDEntryTypes->set(Tags::MDEntryType, 0, "EntryType_1"); // .. and the same but for the second instance. groupMDEntryTypes->set(Tags::MDEntryType, 1, "EntryType_2"); // Once group is setup, it MUST be released to avoid memory leaks. groupMDEntryTypes->release(); // Create a repeating group NoRelatedSym with two instances. // (another way of creating and accessing repeating group). request.set(Tags::NoRelatedSym, 2); Group* groupRelatedSym = request.getGroup(Tags::NoRelatedSym); groupRelatedSym->set(Tags::Symbol, 0, "EURUSD_0"); groupRelatedSym->set(Tags::Symbol, 1, "EURUSD_1"); // Don't forget to release the group. groupRelatedSym->release(); request.validate(); clog << request.toString() << endl;