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 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:
- Well defined FIX messages assume all fields of a repeating group follow one another. The appearance of an arbitrary field which doesn't belong to repeating group (according to the FIX specification) automatically indicates the end of the repeating group. Therefore further appearance of fields from the repeating group is disallowed by the FIX Standard.
- It is possible for repeating groups to appear inside of another repeating group. In such 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 number of tags-separators must equal to value of the leading field.
Group class
OnixS .NET FIX Engine exposes 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 .NET FIX Engine follows this approach in handling repeating groups. In particular, the 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.
Adding Group into Message
To create a new repeating group or modify the number of instances the SetGroup(Int32, Int32) method is available.
To create a new embedded repeating group or modify the number of instances the SetGroup(Int32, Int32, Int32) 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. |
Accessing Repeating Group Entries
To obtain a reference to the Group object that represents an existing repeating group of the message, the GetGroup(Int32) method is available.
To obtain a reference to the embedded Group object that represents an existing embedded repeating group of the another repeating group, the GetGroup(Int32, Int32) method is available.
The Group class works with fields as well as with embedded repeating groups in the same manner as the 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.
Removing Repeating Group from Message
To remove an entire repeating group together with its leading tag, Remove(Int32) method is exposed by Message and Remove(Int32, Int32) method is exposed by Group class.
Example

// Forms 'Market Data Request' message. Message request = new Message( MsgType.MarketDataRequest, ProtocolVersion.FIX42); // Sets up regular fields. 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_0"); // .. and the same but for the second instance. groupMDEntryTypes.Set(Tags.MDEntryType, 1, "EntryType_1"); // 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"); // Create embedded repeating group which belongs to first entry of // groupRelatedSym repeating group Group groupSecAltID = groupRelatedSym.SetGroup(Tags.NoSecurityAltID, 0, 1); groupSecAltID.Set(Tags.SecurityAltID, 0, "EURUSD_Alt_0"); request.Validate(); Console.WriteLine(request.ToString());

' Forms Market Data Request message. Dim request As Message = New Message( _ MsgType.MarketDataRequest, FIXForge.NET.FIX.ProtocolVersion.FIX42) ' Sets up regular fields. 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. Dim groupMDEntryTypes As Group = request.SetGroup(Tags.NoMDEntryTypes, 2) ' Defines fields in the first instance/entry of repeating group.. groupMDEntryTypes.Set(Tags.MDEntryType, 0, "EntryType_0") ' .. and the same but for the second instance. groupMDEntryTypes.Set(Tags.MDEntryType, 1, "EntryType_1") ' Create a repeating group NoRelatedSym with two instances. ' (another way of creating and accessing repeating group). request.Set(Tags.NoRelatedSym, 2) Dim groupRelatedSym As Group = request.GetGroup(Tags.NoRelatedSym) groupRelatedSym.Set(Tags.Symbol, 0, "EURUSD_0") groupRelatedSym.Set(Tags.Symbol, 1, "EURUSD_1") ' Create embedded repeating group which belongs to first entry of ' groupRelatedSym repeating group Dim groupSecAltID as Group = groupRelatedSym.SetGroup(Tags.NoSecurityAltID, 0, 1) groupSecAltID.Set(Tags.SecurityAltID, 0, "EURUSD_Alt_0") request.Validate() Console.WriteLine(request.ToString())