• Version 1.16.0
Show / Hide Table of Contents

Custom Field Generator Sample Project

This sample demonstrates how to generate custom fields.

© Onix Solutions

Source code


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using NLog.Extensions.Logging;
using OnixS.Fix;
using OnixS.Fix.Dictionaries;

namespace CustomFieldGeneratorSample
{
    static class CustomFieldGeneratorSample
    {
        static void Log(string msg)
        {
            Console.Out.WriteLine(msg);
        }

        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");
        }

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static int Main()
        {
            try
            {
                var settings = new EngineSettings()
                {
                    Dictionary = "SampleFixDialectDescription.xml",
                    DisableNetworkLevel = true,
                    LicenseStore = GetLicenseStoreFolder(),
                    LoggerProvider = new NLogLoggerProvider()
                };

                Engine.Init(settings);

                var dictionary = ProtocolVersion.Fix44.ToDictionary();

                string filename = "Tags.cs";

                using (StreamWriter writer = new StreamWriter(filename, false))
                {
                    var tags = GenerateTags(dictionary);
                    writer.WriteLine(tags);
                    writer.WriteLine();
                }

                Log($"{filename} is generated successfully.");

                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>
        /// Generate tags and values for custom fields.
        /// </summary>
        /// <returns> Generated C# code </returns>
        private static string GenerateTags(IMessageInfoDictionary dictionary)
        {
            var tags = GetTags(dictionary);

            var result = new StringBuilder();

            result.AppendLine($"public static class {dictionary.Name}Tag").AppendLine("{");
            foreach (var tag in tags.Values.OrderBy(t => t.Tag))
            {
                string name = IsToken(tag.Name) ? tag.Name : ("Tag" + tag.Tag);
                result.AppendLine($"    public const int {name} = {tag.Tag};");
            }
            result.AppendLine("}");
            return result.ToString();
        }

        private static bool IsToken(string name)
        {
            if (string.IsNullOrEmpty(name))
                return false;

            if (!char.IsLetter(name[0]) && name[0] != '_')
                return false;

            for (int i = 1; i < name.Length; i++)
            {
                if (!char.IsLetterOrDigit(name[i]))
                    return false;
            }
            return true;
        }

        private static Dictionary<int, FieldInfo> GetTags(IMessageInfoDictionary dictionary)
        {
            var tags = new Dictionary<int, FieldInfo>();

            foreach (var messageType in dictionary.MessageTypes)
            {
                var messageInfo = dictionary.GetMessageInfo(messageType);
                GetTags(messageInfo, tags);
            }

            return tags;
        }

        private static void GetTags(FieldContainerInfo fieldContainer, Dictionary<int, FieldInfo> tags)
        {
            foreach (var field in fieldContainer)
            {
                tags[field.Tag] = field;
                if (field.Group != null)
                {
                    GetTags(field.Group, tags);
                }
            }
        }
    }
}

Dialect

<?xml version="1.0" encoding="utf-8" ?>

<Dialect xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://ref.onixs.biz/fix/dialects https://ref.onixs.biz/fix/dialects/dialects-2.19.xsd" xmlns="https://onixs.biz/fix/dialects">


    <FIX version="4.4" mode="override">
        <Message type="SampleCustomFixMessage">
            <Field tag="847" name="TargetStrategy"/>
            <Field tag="168" name="EffectiveTime"/>
            <Group numberOfInstancesTag="957" name="NoStrategyParameters">
                <Field tag="958" name="StrategyParameterName"/>
                <Field tag="959" name="StrategyParameterType"/>
                <Field tag="960" name="StrategyParameterValue"/>
            </Group>
        </Message>
    </FIX>

</Dialect>
In this article
Back to top Copyright © Onix Solutions.
Generated by DocFX