예제 #1
0
        /// <summary>Opens a CRIF file and reads its content.</summary>
        /// <param name="filePath">The <see cref="T:System.String"/> representing the file to open for reading.</param>
        /// <returns>An <see cref="System.Collections.Generic.ICollection{T}"/> of <see cref="T:InitialMargin.Core.DataEntity"/> objects defined in the CRIF file.</returns>
        /// <exception cref="T:System.ArgumentException">Thrown when <paramref name="filePath">filePath</paramref> is invalid or does not refer to a CSV file.</exception>
        /// <exception cref="T:System.IO.FileNotFoundException">Thrown when <paramref name="filePath">filePath</paramref> could not be found.</exception>
        /// <exception cref="T:System.IO.InvalidDataException">Thrown when the CRIF file contains invalid or malformed data.</exception>
        public static ICollection <DataEntity> Read(String filePath)
        {
            List <String[]> fieldsMatrix = CsvParser.Parse(filePath, Encoding.UTF8, '\t', false);

            if (fieldsMatrix.Count == 0)
            {
                throw new InvalidDataException($"[{filePath}] The CRIF file is empty.");
            }

            String[] properties = fieldsMatrix.ElementAt(0);
            fieldsMatrix = fieldsMatrix.Skip(1).ToList();

            if (properties.Any(String.IsNullOrWhiteSpace))
            {
                throw new InvalidDataException($"[{filePath}] The CRIF file contains empty column headers.");
            }

            if (s_Properties.Intersect(properties).Count() != s_Properties.Length)
            {
                throw new InvalidDataException($"[{filePath}] The CRIF file does not contain all the required column headers: {String.Join(", ", s_Properties)}.");
            }

            Dictionary <String, Int32> propertiesMapping = new Dictionary <String, Int32>(s_Properties.Length);

            foreach (String property in s_Properties)
            {
                propertiesMapping.Add(property, Array.IndexOf(properties, property));
            }

            List <DataEntity> entities = new List <DataEntity>();

            foreach (var tuple in fieldsMatrix.Select((x, i) => new { Index = i, Value = x }))
            {
                Int32    index  = tuple.Index + 2;
                String[] values = tuple.Value;

                if (values.Length != properties.Length)
                {
                    throw new InvalidDataException($"[{filePath}, Line {index}] The CRIF file contains an entry whose number of columns doesn't match the number of column headers.");
                }

                EntryObject o = ToEntryObject(values, propertiesMapping);

                if ((o.InitialMarginModel != "Schedule") && (o.InitialMarginModel != "SIMM"))
                {
                    throw new InvalidDataException($"[{filePath}, Line {index}] The CRIF file contains an entry with an invalid IMModel property.");
                }

                DataEntity entity = null;

                try
                {
                    switch (o.RiskType)
                    {
                    case "Notional":
                    {
                        if (o.InitialMarginModel == "SIMM")
                        {
                            entity = ReadAddOnNotional(o);
                        }
                        else
                        {
                            entity = ReadNotional(o);
                        }

                        break;
                    }

                    case "Param_AddOnFixedAmount":
                        entity = ReadAddOnFixedAmount(o);
                        break;

                    case "Param_AddOnNotionalFactor":
                        entity = ReadAddOnNotionalFactor(o);
                        break;

                    case "Param_ProductClassMultiplier":
                        entity = ReadProductMultiplier(o);
                        break;

                    case "PV":
                        entity = ReadPresentValue(o);
                        break;

                    case "Risk_BaseCorr":
                        entity = ReadSensitivityBaseCorrelation(o);
                        break;

                    case "Risk_Commodity":
                    case "Risk_CommodityVol":
                        entity = ParseSensitivityCommodity(o);
                        break;

                    case "Risk_CreditNonQ":
                    case "Risk_CreditVolNonQ":
                        entity = ParseSensitivityCreditNonQualifying(o);
                        break;

                    case "Risk_CreditQ":
                    case "Risk_CreditVol":
                        entity = ParseSensitivityCreditQualifying(o);
                        break;

                    case "Risk_Equity":
                    case "Risk_EquityVol":
                        entity = ReadSensitivityEquity(o);
                        break;

                    case "Risk_FX":
                    case "Risk_FXVol":
                        entity = ReadSensitivityFx(o);
                        break;

                    case "Risk_Inflation":
                    case "Risk_InflationVol":
                        entity = ReadSensitivityInflation(o);
                        break;

                    case "Risk_IRCurve":
                    case "Risk_IRVol":
                        entity = ReadSensitivityInterestRate(o);
                        break;

                    case "Risk_XCcyBasis":
                        entity = ReadSensitivityCrossCurrencyBasis(o);
                        break;
                    }
                }
                catch (InvalidDataException e)
                {
                    throw new InvalidDataException($"[{filePath}, Line {index}] {e.Message}");
                }

                if (entity == null)
                {
                    throw new InvalidDataException($"[{filePath}, Line {index}] The CRIF file contains an entry with an invalid RiskType property.");
                }

                entities.Add(entity);
            }

            return(entities);
        }