using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Collections.ObjectModel;
using CsvHelper.Configuration;
using CsvHelper.Configuration.Attributes;
using CsvHelper.Expressions;
using CsvHelper.TypeConversion;
static readonly Dictionary<int, string> Values = new Dictionary<int, string>
{2, "Removed Liquidity"},
{3, "Liquidity Routed Out" }
Value = Values.ContainsKey(p) ? p : 0;
public int Value { get; set; }
public override string ToString()
public Liquidity LastLiquidity { get; set; }
LastLiquidity = new Liquidity(0);
public struct TradeLogRec
public Execution execution { set; get; }
public static class CsvSerializationHelper
public static CsvConfiguration CSVConfig =>
new CsvConfiguration(CultureInfo.InvariantCulture)
PrepareHeaderForMatch = a => a.Header == "p" ? nameof(Liquidity.Value) : a.Header,
public class TradeLogRecMap : ClassMap<TradeLogRec>
public static string SerializeToCsvString<TClass, TClassMap>(IEnumerable<TClass> records) where TClassMap : ClassMap<TClass>, new()
var sb = new StringBuilder();
using (var writer = new StringWriter(sb))
using (var csv = new CsvWriter(writer, CSVConfig))
csv.Context.RegisterClassMap<TClassMap>();
csv.WriteRecords(records);
public static List<TClass> DeserializeFromCsvString<TClass, TClassMap>(string csvText) where TClassMap : ClassMap<TClass>, new()
using (var reader = new StringReader(csvText))
using (var csv = new CsvReader(reader, CSVConfig))
csv.Context.RegisterClassMap<TClassMap>();
return csv.GetRecords<TClass>().ToList();
public static List<TradeLogRec> DeserializeTradeLogRecMapFromCsvString(string csvText)
using (var reader = new StringReader(csvText))
return DeserializeTradeLogRecMapFromCsv(reader);
public static List<TradeLogRec> DeserializeTradeLogRecMapFromCsv(TextReader reader)
using (var csv = new CsvReader(reader, CSVConfig))
csv.Context.RegisterClassMap<TradeLogRecMap>();
return csv.GetRecords<TradeLogRec>().ToList();
public static void Test()
var records = new List<TradeLogRec>
new TradeLogRec { execution = new Execution { LastLiquidity = new Liquidity(3) } },
new TradeLogRec { execution = new Execution { LastLiquidity = new Liquidity(2) } },
new TradeLogRec { execution = new Execution { LastLiquidity = new Liquidity(1) } },
new TradeLogRec { execution = new Execution { LastLiquidity = new Liquidity(0) } },
var csvText = CsvSerializationHelper.SerializeToCsvString<TradeLogRec, CsvSerializationHelper.TradeLogRecMap>(records);
Console.WriteLine(csvText);
var newRecords = CsvSerializationHelper.DeserializeTradeLogRecMapFromCsvString(csvText);
Assert.AreEqual(JsonConvert.SerializeObject(records), JsonConvert.SerializeObject(newRecords));
public static void Main()
Console.WriteLine("Environment version: {0} ({1})", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , GetNetCoreVersion());
Console.WriteLine("OS Version: {0}, NewLine: {1}", System.Environment.OSVersion, JsonConvert.SerializeObject(Environment.NewLine));
Console.WriteLine("{0} version: {1}", typeof(CsvReader).Assembly.GetName().Name, typeof(CsvReader).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");
public static string GetNetCoreVersion()
var assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly;
var assemblyPath = assembly.Location.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
return assemblyPath[netCoreAppIndex + 1];