• Programmer’s Guide
  • Api Documentation
  • Repeating Group API
Show / Hide Table of Contents
  • License Agreement
  • Release Notes
  • Backgrounder
    • About FIX
    • About FIX messages
    • About FIX sessions
    • About FIX 5.0
  • Installation And Uninstallation
    • Requirements & Compatibility
    • Supported Features
    • Samples descriptions
    • Uninstallation instructions
  • Quick Start
    • Session acceptor creation
    • Session initiator creation
    • Creating new order
    • Sending order
    • Processing incoming message
    • Closing session
    • Sample application
  • Basic Concepts
    • Main components
    • FixServer description
    • IFixServerListener description
    • IFixSessionListener description
    • IFixSession description
    • Repeating Groups description
    • Message validation
  • FIX Session Acceptor
    • Create
    • Connect
    • Reject
    • Reconnect
    • Disconnect
    • Release
    • Send message
  • FIX Session Initiator
    • Create
    • Establish connection
    • Reconnect
    • Disconnect
    • Dispose
    • Send message
  • FIX Session
    • Persistent session
    • Session state
    • Sequence number handling
    • Session qualifier
  • FIX Message
    • Create
    • Get field
    • Add field
    • Set field
    • Remove field
    • Repeating group
    • User defined fields
    • Clone message
  • FIX Prepared Message
    • Create
    • Add field
    • Set field
  • Repeating Group API
    • Indexing Repeating Group
    • Working with Repeating Groups through API
    • Repeating Group Pool
    • Get Repeating Group
    • Get Entry
    • Get nested group
    • Add new Repeating Group to message
    • Add new Entry to Repeating Group
    • Remove Entry from Repeating Group
    • Leading tag self-maintaining
    • ITagList interface
    • Validation
    • Copying
    • Finishing work with Repeating Group API
  • Validation
    • Initialization
    • Validation
  • Monitoring and Administration
    • Overview
    • Response result codes
    • Supported commands
  • Recovery
    • Store-and-forward
    • Gap fill
    • Fail-over
  • Configuration
    • Global configuration
    • Server Behavior
    • Queue and Storage
    • Validation
    • Administrative plugin
    • Session’s configuration
    • Configure SeqNum fields length
    • Definition of session’s configuration via properties file
    • Definition of session’s configuration via XML file
    • Loading of session’s configuration
  • TLS Support
    • SSL/TLS configuration
    • How to define an SSL certificate
    • How to use sslPort and requireSsl configuration options
    • Configuration examples
    • Diagnostic and troubleshooting
  • Other Topics
    • Log files
    • FAQ
    • Troubleshooting

Repeating Group API

There is API for Repeating Group in FIX Antenna .NET Core. It allows to create, remove and modify Repeating Groups and their entries.

Indexing Repeating Group

To use the Repeating Group API, you can pass the FixMessage instance to static method RawFixUtil.IndexRepeatingGroup(). There are four implementations of this method:

  1. Indexes Repeating Group according to FIX dictionary. Dictionary version and message type selects by passed arguments.

    FixMessage IndexRepeatingGroup(FixMessage msg, FixVersion version, string msgType, bool validation)
    
  2. Indexes Repeating Group according to FIX dictionary. Dictionary version and message type selects by passed arguments and validation is turn off.

    FixMessage IndexRepeatingGroup(FixMessage msg, FixVersion version, string msgType)
    
  3. Indexes Repeating Group according to FIX dictionary. FIX version and message type extracted from message.

    FixMessage IndexRepeatingGroup(FixMessage msg, bool validation)
    
  4. Indexes Repeating Group according to FIX dictionary. FIX version and message type extracted from message and validation turned off.

    FixMessage IndexRepeatingGroup(FixMessage msg)
    

All methods return the passed message. If you try to work with Repeating Group API without calling RawFixUtil.IndexRepeatingGroup(), method IndexRepeatingGroup(FixMessage msg) will be implicitly called, so you get indexed message with turned off validation.

Working with Repeating Groups through API

There are two classes for working with Repeating Group through api: RepeatingGroup and RepeatingGroup.Entry. RepeatingGroup contains methods for managing entries of Repeating Group. Entry contains methods for managing tags in specific entry of RepeatingGroup and sub groups. By default, FIX Antenna uses instances of RepeatingGroup and RepeatingGroup.Entry from internal pool to reduce garbage production.

Repeating Group Pool

The first thing that you should know about Repeating Group API is pooling. Remember simple rule: if you got RepeatingGroup or Entry instance by calling method that returns instance of group or entry, then there is no need in group.Release() / entry.Release(): all groups and entries will come back to pool after the call of msg.ReleaseInstance(). In other case, if you get group or entry by an explicit call of RepeatingGroupPool.GetEntry() / GetRepeatingGroup() you should explicitly return group/entry object to pool by Release method call.

Get Repeating Group

There are two ways to get Repeating Group from indexed message:

  1. Don't forget about msg.ReleaseInstance()! If you don't call this method it may cause unnecessary object creation.

    FixMessage msg = RawFixUtil.GetFixMessage(executionReport.GetBytes());
    msg = RawFixUtil.IndexRepeatingGroup(msg, true);
    
    RepeatingGroup group = msg.GetRepeatingGroup(555); //Leading tag of Repeating Group
    //Some operations
    msg.ReleaseInstance();
    
  2. In this case FixMessage filling passed group by information about group content.

    FixMessage msg = RawFixUtil.GetFixMessage(executionReport.GetBytes());
    msg = RawFixUtil.IndexRepeatingGroup(msg, true);
    RepeatingGroup group = RepeatingGroupPool.GetRepeatingGroup(); // Or new RepeatingGroup() or something else
    msg.GetRepeatingGroup(555, group); // Leading tag of Repeating Group
    //Some operations
    group.Release();
    

If you try to get non-existent group, you get exception (if you call void method) or null value (if you call method which returns RepeatingGroup instance). There are safe methods (GetOrAddRepeatingGroup()) which adds repeating group if it's doesn't exist.

Get Entry

After you get RepeatingGroup instance, you can get entries of this group. There are also two ways to get it:

  1. Don't forget about msg.ReleaseInstance() ! If you don't call this method, it may cause unnecessary object creation.

    FixMessage msg = RawFixUtil.GetFixMessage(executionReport.GetBytes());
    msg = RawFixUtil.IndexRepeatingGroup(msg, true);
    
    RepeatingGroup group = msg.GetRepeatingGroup(555); //Leading tag of Repeating Group
    RepeatingGroup.Entry entry = group.GetEntry(0); //Number of entry in group
    //Some operations
    msg.ReleaseInstance();
    
  2. In this case FixMessage filling passed entry by information about entry content.

    FixMessage msg = RawFixUtil.GetFixMessage(executionReport.GetBytes());
    msg = RawFixUtil.IndexRepeatingGroup(msg, true);
    RepeatingGroup group = RepeatingGroupPool.GetRepeatingGroup(); // Or new RepeatingGroup() or something else
    RepeatingGroup.Entry entry = RepeatingGroupPool.GetEntry();
    msg.GetRepeatingGroup(555, group); // Leading tag of Repeating Group
    group.GetEntry(0, entry); //Number of entry in group
    //Some operations
    entry.Release();
    group.Release();
    

Get nested group

You can get nested group using method Entry.GetGroup():

FixMessage msg = RawFixUtil.GetFixMessage(executionReport.GetBytes());
msg = RawFixUtil.IndexRepeatingGroup(msg, true);
RepeatingGroup group = RepeatingGroupPool.GetRepeatingGroup(); // Or new RepeatingGroup() or something else
RepeatingGroup.Entry entry = RepeatingGroupPool.GetEntry();
msg.GetRepeatingGroup(555, group); // Leading tag of Repeating Group
group.GetEntry(0, entry); //Number of entry in group

RepeatingGroup subGroup = entry.GetGroup(FIX43.ExecutionReport.InstrumentLeg.NoLegSecurityAltID);

//Some operations
entry.Release();
msg.ReleaseInstance();

Add new Repeating Group to message

To create Repeating Group is used method AddRepeatingGroupAtIndex:

FixMessage msg = RawFixUtil.GetFixMessage(executionReport.GetBytes());
msg = RawFixUtil.IndexRepeatingGroup(msg, true);

int repeatingGroupIndex = 20; //Index in message
int leadingTag = 555; //Leading tag for group
bool validation = true; //Turn on validation
RepeatingGroup group = msg.AddRepeatingGroupAtIndex(repeatingGroupIndex, leadingTag, validation);
//Some operations
msg.ReleaseInstance();

Parameter repeatingGroupIndex is an index of leading tag in FIX message. First tag has index = 0. Parameter validation enables or disables validation of group. Information about validation is below. Also you can add nested group to entry:

FixMessage msg = RawFixUtil.GetFixMessage(executionReport.GetBytes());
msg = RawFixUtil.IndexRepeatingGroup(msg, true);
RepeatingGroup group = RepeatingGroupPool.GetRepeatingGroup(); // Or new RepeatingGroup() or something else
RepeatingGroup.Entry entry = RepeatingGroupPool.GetEntry();
msg.GetRepeatingGroup(555, group); // Leading tag of Repeating Group
group.GetEntry(0, entry); //Number of entry in group

int leadingTag = FIX43.ExecutionReport.InstrumentLeg.NoLegSecurityAltID;
bool validation = true;
RepeatingGroup subGroup = entry.AddRepeatingGroup(FIX43.ExecutionReport.InstrumentLeg.NoLegSecurityAltID, validation);

//Some operations
entry.Release();
group.Release();
msg.ReleaseInstance();

Parameter validation is optional for creating repeating group. If it is ommited, its value will be inherited from parent group.

Add new Entry to Repeating Group

To create new Entry is used method AddEntry():

FixMessage msg = RawFixUtil.GetFixMessage(executionReport.GetBytes());
msg = RawFixUtil.IndexRepeatingGroup(msg, true);
RepeatingGroup group = RepeatingGroupPool.GetRepeatingGroup(); // Or new RepeatingGroup() or something else
RepeatingGroup.Entry entry = RepeatingGroupPool.GetEntry();
msg.GetRepeatingGroup(555, group); // Leading tag of Repeating Group

//Add at end
Entry entry1 = group.AddEntry()
//Add at index. First index = 0
Entry entry2 = group.AddEntry(1);

entry.Release();
group.Release();
msg.ReleaseInstance();

If you pass index greater than current group size or less than zero, you will get IndexOutOfRangeException.

Remove Entry from Repeating Group

There are few methods to remove entry from group:

group.Remove(index); //remove entry by index
entry.Remove(); //remove current entry, but doesn't return it in pool
group.Remove(entry); //remove passed entry, but doesn't return it in pool

Leading tag self-maintaining

Leading tag of group is fully self-maintaining. You can't update it directly. Leading tag doesn't appear in message, until group is empty. Also when group becomes empty leading tag is removed from message.

FixMessage msg = new FixMessage();
msg.Set(8, "FIX.4.4");
msg.Set(35, "8");
msg.Set(10, 123);

RepeatingGroup group = msg.AddRepeatingGroupAtIndex(555, 2);
Console.WriteLine(msg.ToPrintableString()); //8=FIX.4.4 | 35=8 | 10=123  group is empty, so it doesn't show in message

RepeatingGroup.Entry entry1 = msg.AddEntry();
RepeatingGroup.Entry entry2 = msg.AddEntry();
Console.WriteLine(msg.ToPrintableString()); //8=FIX.4.4 | 35=8 | 10=123  group have two entries now, but all entry is empty, so group still doesn't show in message
Console.WriteLine(group.GetSize()); // Prints 2, method getSize returns number of all groups - empty and non empty
Console.WriteLine(group.GetLeadingTagValue()); // Prints 0

entry1.addTag(600, "TBD");
Console.WriteLine(msg.ToPrintableString()); //8=FIX.4.4 | 35=8 | 555=1 | 600=TBD | 10=123  group appear in message.
Console.WriteLine(group.GetSize()); // Prints 2
Console.WriteLine(group.GetLeadingTagValue()); // Prints 1

entry.removeTag(600);
Console.WriteLine(msg.ToPrintableString()); //8=FIX.4.4 | 35=8 | 10=123  group is removed from message because there is no non-empty entries
Console.WriteLine(group.GetSize()); // Prints 2, method getSize returns number of all groups - empty and non empty
Console.WriteLine(group.GetLeadingTagValue()); // Prints 0

When we add two or more groups at the same place in message the behavior is the same as when we add two tags in the same place in message:

FixMessage msg = new FixMessage();
msg.set(8, "FIX.4.4");
msg.set(35, "8");
msg.set(10, 123);

RepeatingGroup group555 = msg.AddRepeatingGroupAtIndex(555, 2);
RepeatingGroup group454 = msg.AddRepeatingGroupAtIndex(454, 2); //group 555 will appear right after group 454

group555.AddEntry().addTag(600, "TBD");
Console.WriteLine(msg.ToPrintableString()); //8=FIX.4.4 | 35=8 | 555=1 | 600=TBD | 10=123
group454.AddEntry().addTag(455, 5);
Console.WriteLine(msg.ToPrintableString()); //8=FIX.4.4 | 35=8 | 454=1 | 455=5 | 555=1 | 600=TBD | 10=123
RepeatingGroup group = msg.AddRepeatingGroup(555, 2);

Nested repeating groups also have self-maintained leading tags.

When we add two nested groups one by one, they will appear in the order of adding:

RepeatingGroup.Entry entry = group555.AddEntry();
entry.addTag(600, "TBD");
RepeatingGroup group604 = entry.AddRepeatingGroup(604);
RepeatingGroup group539 = entry.AddRepeatingGroup(539);

Console.WriteLine(msg.ToPrintableString()); //8=FIX.4.4 | 35=8 | 454=1 | 455=5 | 555=1 | 600=TBD | 10=123 sub groups 604 and 539 is empty, so they doesn't show

group539.addTag(524, "524val");
Console.WriteLine(msg.ToPrintableString()); //8=FIX.4.4 | 35=8 | 454=1 | 455=5 | 555=1 | 600=TBD | 525=1 | 524=524val | 10=123
group604.addTag(605, "605val");
Console.WriteLine(msg.ToPrintableString()); //8=FIX.4.4 | 35=8 | 454=1 | 455=5 | 555=1 | 600=TBD | 604=1 | 605=605val | 525=1 | 524=524val | 10=123

All methods which work with index inside entry like RemoveTagAtIndex, GetTagValueAsXXXAtIndex do not work with empty groups:

RepeatingGroup.Entry entry = group555.AddEntry();
entry.AddTag(600, "TBD");
RepeatingGroup group604 = entry.AddRepeatingGroup(604);

entry.RemoveTagAtIndex(1); //returns false, because there is no any real tag at index 1 inside entry.

ITagList interface

There is a common interface for FixMessage and RepeatingGroup.Entry for Add, Get, Update, Remove operations on tags in entry:

ITagList entry = group.GetEntry(0);
entry.AddTag(tag, tagValue);
entry.UpdateValue(tag, tagValue, missingTagHandling);
entry.RemoveTag(tag);
entry.GetTagValueAsString(tag);
//And others

Validation

Validation of repeating groups is available during initial indexing of Repeating Group and during modification of Repeating Group.

During indexing there are such validations:

  1. Leading tag value validation. Leading tag value must be equal to number of Repeating Group entries.
  2. Duplicate tag validation. All tags inside entry must be unique.
  3. Delimiter tag validation. Delimiter tag must be followed by leading tag.

During modification of Repeating group there are such validations:

  1. Tag refers to group validation. Must be mapping group -> tag in dictionary.
  2. Duplicate tag validation. All tags inside entry must be unique.

Copying

It is possible to copy repeating group and entry to other message or group. To copy repeating group from one FIX message to another, use method FixMessage.CopyRepeatingGroup:

RepeatingGroup srcGroup = srcMsg.GetRepeatingGroup(232);
RepeatingGroup copiedGroup = dstMsg.CopyRepeatingGroup(srcGroup, 9); // group for copy and index where group will be inserted

To copy entry of repeating group to other group, use method RepeatingGroup.CopyEntry:

RepeatingGroup groupForCopy = srcMsg.GetRepeatingGroup(454);
RepeatingGroup.Entry entryForCopy = groupForCopy.GetEntry(1);
RepeatingGroup tarGetGroup = dstMsg.GetRepeatingGroup(454);

Entries can be copied to the same message or to another message. To copy nested repeating group, use method Entry.CopyRepeatingGroup:

RepeatingGroup groupForCopy = srcMsg.GetRepeatingGroup(555).GetEntry(0).GetRepeatingGroup(539);
RepeatingGroup.Entry tarGetEntry = dstMsg.GetRepeatingGroup(555).GetEntry(0);

RepeatingGroup copiedGroup = tarGetEntry.CopyRepeatingGroup(groupForCopy);

You can insert nested group in any entry or even in root of message without limitation

Finishing work with Repeating Group API.

If you created FixMessage message from pool, call of ReleaseInstance() will return all RG instances and message itself to corresponding pools. In other case you should call method InvalidateRepeatingGroupIndex() at the end of the work with Repeating Group API. Also don't forget to call methods Release() for RepeatingGroup.Entry and RepeatingGroup if you got it from pool explicitly.

In This Article
  • Indexing Repeating Group
  • Working with Repeating Groups through API
  • Repeating Group Pool
  • Get Repeating Group
  • Get Entry
  • Get nested group
  • Add new Repeating Group to message
  • Add new Entry to Repeating Group
  • Remove Entry from Repeating Group
  • Leading tag self-maintaining
  • ITagList interface
  • Validation
  • Copying
  • Finishing work with Repeating Group API.
Back to top Generated by DocFX