OnixS C++ FIX Engine  3.24.0
API Documentation

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:

fix-message-repeating-group.gif

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 NoRoutingIDs tag.

Each entry of repeating group has a selected leading field, which in turn identifies the beginning of a new group 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. The RoutingType field is an example of such a separator.

Important aspects of FIX repeating groups structure:

Group class

OnixS C++ FIX Engine exposes the OnixS::FIX::Group class to encapsulate all aspects that are related with 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 ofrepeating 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 number of instances, the OnixS::FIX::Message::setGroup method is available.

Warning

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.

Example

// Forms 'Market Data Request' message.
using namespace OnixS::FIX;
using namespace OnixS::FIX::FIX42;
Message request(Values::MsgType::Market_Data_Request, ProtocolVersion::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[0].set(Tags::MDEntryType, "EntryType_1");
// .. and the same but for the second instance.
groupMDEntryTypes[1].set(Tags::MDEntryType, "EntryType_2");
}
// Creates 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[0].set(Tags::Symbol, "EURUSD_0");
groupRelatedSym[1].set(Tags::Symbol, "EURUSD_1");
}
request.validate();
clog << request.toString() << 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.

Example

// Gets group from 'Mass Quote' message.
class OutputFunctor
{
public:
void operator()(GroupInstance& quoteEntriesInstance)
{
//Gets entries of a nested QuoteEntries repeating group.
clog << "BidSize=" << quoteEntriesInstance.getInt32(Tags::BidSize) << endl
<< "OfferSize=" << quoteEntriesInstance.getInt32(Tags::OfferSize) << endl;
}
};
using namespace OnixS::FIX;
using namespace OnixS::FIX::FIX42;
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"
"302=123\001295=1\001299=0\001134=1000000\001135=900000\001188=1.4363\001190=1.4365\00110=084\001";
Message message;
Message::parse (rawMessage.c_str(), rawMessage.size(), MessageParsingFlag::Strict, message);
//Gets a quoteSets repeating group.
Group quoteSets = message.getGroup(Tags::NoQuoteSets);
//Iterates over all repeating group entries of the NoQuoteSets group by the index.
for(size_t quoteSetsIndex = 0; quoteSetsIndex < quoteSets.size(); ++quoteSetsIndex)
{
//Gets a nested QuoteEntries repeating group.
Group quoteEntries = quoteSets[quoteSetsIndex].getGroup(Tags::NoQuoteEntries);
//Iterates over all repeating group entries of the NoQuoteEntries group by iterators.
std::for_each(quoteEntries.begin(), quoteEntries.end(), OutputFunctor());
}

Removing Repeating Group from Message

To remove an entire repeating group together with its leading tag, the OnixS::FIX::Message::remove method is exposed by OnixS::FIX::Message and the OnixS::FIX::Group class.