• Version 1.15.2
Show / Hide Table of Contents

Flat Group Reader Sample

Source code


using System;
using System.Diagnostics;
using System.IO;
using NLog.Extensions.Logging;
using OnixS.Fix;
using OnixS.Fix.Fix44;

namespace RepeatingGroupFlatMessage
{
    static class RepeatingGroupFlatMessage
    {
        static int Main()
        {
            try
            {
                var settings = new EngineSettings()
                {
                    LicenseStore = GetLicenseStoreFolder(),
                    LoggerProvider = new NLogLoggerProvider()
                };
                Engine.Init(settings);

                FlatMessage marketDataRequest = CreateMarketDataRequestMessage();

                Log("Created FIX message in the native (tag=value) format:\n\n" + marketDataRequest);

                ProcessMarketDataRequestMessage(marketDataRequest);

                FlatMessage order = CreateMessageWithNestedRepeatingGroups();

                ProcessMessageWithNestedRepeatingGroups(order);

                Engine.Shutdown();
            }
            catch (Exception ex)
            {
                Log("Exception: " + ex);

                return 1;
            }
            finally
            {
                // From https://github.com/NLog/NLog/wiki/Tutorial:
                // NET Application running on Mono / Linux are required to stop threads / timers before entering application shutdown phase.
                // Failing to do this will cause unhandled exceptions and segmentation faults, and other unpredictable behavior.
                NLog.LogManager.Shutdown(); // Flush and close down internal threads and timers
            }

            return 0;
        }

        /// <summary>
        /// Creates a Market Data Request (MsgType=V) message.
        /// </summary>
        static FlatMessage CreateMarketDataRequestMessage()
        {
            var request = new FlatMessage(ProtocolVersion.Fix44);

            // See https://www.onixs.biz/fix-dictionary/4.4/msgType_V_86.html
            request.Set(Tag.MsgType, MsgType.MarketDataRequest);

            request.Add(Tag.MDReqID, "1")
                   .Add(Tag.SubscriptionRequestType, SubscriptionRequestType.SnapshotUpdate)
                   .Add(Tag.MarketDepth, "0")
                   .Add(Tag.MDUpdateType, MDUpdateType.Full)
                   // Repeating group
                   .Add(Tag.NoMDEntryTypes, 3)
                   .Add(Tag.MDEntryType, MDEntryType.Bid)
                   .Add(Tag.MDEntryType, MDEntryType.Offer)
                   .Add(Tag.MDEntryType, MDEntryType.Trade)
                   // Repeating group
                   .Add(Tag.NoRelatedSym, 2)
                   .Add(Tag.Symbol, "EUR/USD")
                   .Add(Tag.Symbol, "GPS/USD");

            return request;
        }

        static void ProcessMarketDataRequestMessage(FlatMessage request)
        {
            Debug.Assert(MsgType.MarketDataRequest == request.Type);
            Console.WriteLine("\nProcessing:\n" + request.ToString(' ') + "\n");

            FlatGroupReader marketDataEntryTypes = new FlatGroupReader(Tag.NoMDEntryTypes);
            marketDataEntryTypes.Wrap(request);

            int index = 0;
            while (marketDataEntryTypes.MoveNext())
            {
                Log("Market Data Entry # " + index + " : MDEntryType = " + marketDataEntryTypes.Get(Tag.MDEntryType));
                index++;
            }
        }

        static FlatMessage CreateMessageWithNestedRepeatingGroups()
        {
            var order = new FlatMessage(ProtocolVersion.Fix44);

            // See https://www.onixs.biz/fix-dictionary/4.4/msgType_D_68.html
            order.Set(Tag.MsgType, MsgType.NewOrderSingle);

            order.Add(Tag.ClOrdID, "ClOrdID value")
                 // Repeating group
                 .Add(Tag.NoPartyIDs, 1)
                 .Add(Tag.PartyID, "Party ID value")
                 // Nested repeating group:
                 .Add(Tag.NoPartySubIDs, 3)
                 .Add(Tag.PartySubID, "PartySubID value0")
                 .Add(Tag.PartySubID, "PartySubID value1")
                 .Add(Tag.PartySubID, "PartySubID value2");

            Log("\n\nMessage with a nested repeating group:\n" + order);

            return order;
        }

        static void ProcessMessageWithNestedRepeatingGroups(FlatMessage order)
        {
            Debug.Assert(MsgType.NewOrderSingle == order.Type);
            Log("\nProcessing:\n" + order.ToString(' ') + "\n");

            FlatGroupReader partiesGroup = new FlatGroupReader(Tag.NoPartyIDs);
            FlatGroupReader partiesSubGroup = new FlatGroupReader(Tag.NoPartySubIDs);

            partiesGroup.Wrap(order);

            while (partiesGroup.MoveNext())
            {
                partiesSubGroup.Wrap(partiesGroup);

                int nestedIndex = 0;
                while (partiesSubGroup.MoveNext())
                {
                    Log("Parties SubGroup # " + nestedIndex + " : PartySubID = " + partiesSubGroup.Get(Tag.PartySubID));
                    nestedIndex++;
                }
            }
        }

        private static string GetLicenseStoreFolder()
        {
            string path = Path.Join(AppContext.BaseDirectory, "../../../../../license");

            if (Directory.Exists(path))
                return path;

            // expecting it run after dotnet publish using default paths
            return Path.Join(AppContext.BaseDirectory, "../../../../../../license");
        }

        private static void Log(string msg)
        {
            Console.Out.WriteLine(msg);
        }
    }
}

In this article
Back to top Copyright © Onix Solutions.
Generated by DocFX