Пример #1
0
        public void TestOutputCsv(RegulationRole regulationRole, String csvFile)
        {
            FxRatesProvider ratesProvider = m_TestsFixture.RatesProvider;
            ReadOnlyCollection <DataEntity> dataEntities = m_TestsFixture.DataEntities;
            OutputWriterCsv writer = m_TestsFixture.WriterCsv;

            Engine engine = Engine.Of(Currency.Usd, ratesProvider);

            String csvExpectedFile = Utilities.GetStaticFilePath(csvFile);
            String csvActualFile   = Utilities.GetRandomFilePath(".csv");

            MarginTotal margin = engine.CalculateDetailed(regulationRole, dataEntities);

            writer.Write(csvActualFile, margin);

            String expected = Utilities.ComputeHash(File.ReadAllText(csvExpectedFile));
            String actual   = Utilities.ComputeHash(File.ReadAllText(csvActualFile));

            try
            {
                File.Delete(csvActualFile);
            }
            catch { }

            Assert.Equal(expected, actual);
        }
Пример #2
0
        /// <summary>Writes the specified calculation result into the specified plain-text file.</summary>
        /// <param name="filePath">The <see cref="T:System.String"/> representing the file to write to.</param>
        /// <param name="margin">The <see cref="T:InitialMargin.Core.MarginTotal"/> object to write.</param>
        /// <exception cref="T:System.ArgumentException">Thrown when <paramref name="filePath">filePath</paramref> is invalid or does not refer to a plain-text file.</exception>
        /// <exception cref="T:System.ArgumentNullException">Thrown when <paramref name="margin">margin</paramref> is <c>null</c>.</exception>
        public void Write(String filePath, MarginTotal margin)
        {
            if (String.IsNullOrWhiteSpace(filePath))
            {
                throw new ArgumentException("Invalid file path specified.", nameof(filePath));
            }

            if (!s_ValidExtensions.Contains(Path.GetExtension(filePath).ToUpperInvariant()))
            {
                throw new ArgumentException($"Invalid file extension specified (accepted extensions are: {String.Join(", ", s_ValidExtensions).Replace(".", String.Empty)}).", nameof(filePath));
            }

            if (margin == null)
            {
                throw new ArgumentNullException(nameof(margin));
            }

            StringBuilder builder = new StringBuilder("Total");

            builder.AppendLine($" = {Amount.Round(margin.Value, 2).ToString(m_FormatProvider, CurrencyCodeSymbol.None)}");

            if (margin.ChildrenCount > 0)
            {
                Int32 lastIndex = margin.ChildrenCount - 1;

                for (Int32 i = 0; i < margin.ChildrenCount; ++i)
                {
                    WriteTreeNodeChild(margin.Children[i], builder, String.Empty, (i == lastIndex));
                }
            }

            String result = builder.ToString().Trim();

            File.WriteAllText(filePath, result, m_Encoding);
        }
Пример #3
0
        /// <summary>Writes the specified calculation result into the specified CSV file, using the specified delimiter.</summary>
        /// <param name="filePath">The <see cref="T:System.String"/> representing the file to write to.</param>
        /// <param name="margin">The <see cref="T:InitialMargin.Core.MarginTotal"/> object to write.</param>
        /// <param name="delimiter">The <see cref="T:System.Char"/> representing the delimiter.</param>
        /// <exception cref="T:System.ArgumentException">Thrown when <paramref name="filePath">filePath</paramref> is invalid or does not refer to a CSV file, or when <paramref name="delimiter">delimiter</paramref> is invalid (see <see cref="M:InitialMargin.IO.CsvUtilities.IsValidDelimiter(System.Char)"/>).</exception>
        /// <exception cref="T:System.ArgumentNullException">Thrown when <paramref name="margin">margin</paramref> is <c>null</c>.</exception>
        public void Write(String filePath, MarginTotal margin, Char delimiter)
        {
            if (String.IsNullOrWhiteSpace(filePath))
            {
                throw new ArgumentException("Invalid file path specified.", nameof(filePath));
            }

            if (Path.GetExtension(filePath).ToUpperInvariant() != ".CSV")
            {
                throw new ArgumentException("The specified file must be a CSV.", nameof(filePath));
            }

            if (margin == null)
            {
                throw new ArgumentNullException(nameof(margin));
            }

            if (!CsvUtilities.IsValidDelimiter(delimiter))
            {
                throw new ArgumentException($"Invalid delimiter specified (accepted delimiters are: {CsvUtilities.ValidDelimiters}).", nameof(delimiter));
            }

            List <String[]> fieldsMatrix = new List <String[]>();

            WriteCsvRecursive(margin, fieldsMatrix);

            String result = CsvUtilities.FinalizeFieldsMatrix(s_CsvHeaderFields, fieldsMatrix, delimiter, Environment.NewLine);

            File.WriteAllText(filePath, result, m_Encoding);
        }
Пример #4
0
        /// <summary>Calculates the total margin of each regulation for the specified regulation role, value entities and parameter entities.</summary>
        /// <param name="regulationRole">An enumerator value of type <see cref="T:InitialMargin.Core.RegulationRole"/> that specifies the target regulation role.</param>
        /// <param name="values">The <see cref="System.Collections.Generic.ICollection{T}"/> of <see cref="T:InitialMargin.Core.DataValue"/> objects representing the target value entities.</param>
        /// <param name="parameters">The <see cref="System.Collections.Generic.ICollection{T}"/> of <see cref="T:InitialMargin.Core.DataParameter"/> objects representing the target parameter entities.</param>
        /// <returns>An <see cref="System.Collections.Generic.IDictionary{TKey,TValue}"/> of pairs defined by <see cref="T:InitialMargin.Core.Regulation"/> keys and <see cref="T:InitialMargin.Core.Amount"/> values representing the regulation/margin couples.</returns>
        /// <exception cref="T:System.ArgumentNullException">Thrown when <paramref name="values">values</paramref> is <c>null</c> or when <paramref name="parameters">parameters</paramref> is <c>null</c>.</exception>
        /// <exception cref="T:System.ComponentModel.InvalidEnumArgumentException">Thrown when <paramref name="regulationRole">regulationRole</paramref> is undefined.</exception>
        public IDictionary <Regulation, MarginTotal> CalculateDetailedByRole(RegulationRole regulationRole, ICollection <DataValue> values, ICollection <DataParameter> parameters)
        {
            if (!Enum.IsDefined(typeof(RegulationRole), regulationRole))
            {
                throw new InvalidEnumArgumentException("Invalid regulation role specified.");
            }

            if (values == null)
            {
                throw new ArgumentNullException(nameof(values));
            }

            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            List <Regulation> regulations = values.SelectMany(x => SelectRegulations(x, regulationRole))
                                            .Concat(parameters.SelectMany(x => SelectRegulations(x, regulationRole)))
                                            .OrderBy(x => x)
                                            .Distinct().ToList();

            if (regulations.Count == 0)
            {
                return(new Dictionary <Regulation, MarginTotal>());
            }

            List <DataValue> valuesFinal = values.Where(x => !(x is PresentValue) && !(x is Sensitivity)).Select(x => (DataValue)x.Clone())
                                           .Concat(values.OfType <PresentValue>().Select(x => AdjustedClone(x, regulationRole)))
                                           .Concat(values.OfType <Sensitivity>().Select(x => AdjustedClone(x, regulationRole)))
                                           .ToList();

            List <DataParameter> parametersFinal = parameters
                                                   .Select(x => (DataParameter)x.Clone())
                                                   .ToList();

            Dictionary <Regulation, MarginTotal> result = new Dictionary <Regulation, MarginTotal>();

            foreach (Regulation regulation in regulations)
            {
                List <DataValue>     valuesByRegulation     = valuesFinal.Where(x => SelectRegulations(x, regulationRole).Contains(regulation)).ToList();
                List <DataParameter> parametersByRegulation = parametersFinal.Where(x => SelectRegulations(x, regulationRole).Contains(regulation)).ToList();

                List <IMargin> margins = new List <IMargin>(m_Processors.Count);

                foreach (Processor processor in m_Processors)
                {
                    margins.Add(processor.Process(valuesByRegulation, parametersByRegulation));
                }

                result[regulation] = MarginTotal.Of(regulationRole, regulation, m_ValuationDate, m_CalculationCurrency, margins);
            }

            return(result);
        }
Пример #5
0
        private MarginTotal Process(List <Notional> notionals, List <PresentValue> presentValues)
        {
            if (notionals == null)
            {
                throw new ArgumentNullException(nameof(notionals));
            }

            if (presentValues == null)
            {
                throw new ArgumentNullException(nameof(presentValues));
            }

            List <ScheduleObject> scheduleObjects = SanitizeData(notionals, presentValues);

            if (scheduleObjects.Count == 0)
            {
                return(MarginTotal.Of(m_ValuationDate, m_CalculationCurrency));
            }

            HashSet <Product>   products            = new HashSet <Product>();
            List <Notional>     notionalsNetted     = new List <Notional>(scheduleObjects.Count);
            List <PresentValue> presentValuesNetted = new List <PresentValue>(scheduleObjects.Count);

            foreach (ScheduleObject obj in scheduleObjects)
            {
                Amount notionalsSum = Amount.Abs(Amount.Sum(obj.Notionals.Select(x => x.Amount), m_CalculationCurrency));
                notionalsNetted.Add(Notional.Of(obj.Product, notionalsSum, RegulationsInfo.Empty, obj.TradeInfo));

                Amount presentValuesSum = Amount.Sum(obj.PresentValues.Select(x => x.Amount), m_CalculationCurrency);
                presentValuesNetted.Add(PresentValue.Of(obj.Product, presentValuesSum, RegulationsInfo.Empty, obj.TradeInfo));

                products.Add(obj.Product);
            }

            List <MarginProduct> productMargins = new List <MarginProduct>(products.Count);

            foreach (Product product in products.OrderBy(x => x))
            {
                List <Notional>     notionalsByProduct     = notionalsNetted.Where(x => x.Product == product).ToList();
                List <PresentValue> presentValuesByProduct = presentValuesNetted.Where(x => x.Product == product).ToList();
                MarginProduct       productMargin          = ScheduleCalculations.CalculateMarginProduct(m_ValuationDate, m_CalculationCurrency, product, notionalsByProduct, presentValuesByProduct);

                productMargins.Add(productMargin);
            }

            Margin scheduleMargin = ScheduleCalculations.CalculateMargin(m_ValuationDate, m_CalculationCurrency, productMargins, notionals, presentValues);

            return(MarginTotal.Of(m_ValuationDate, m_CalculationCurrency, scheduleMargin));
        }
Пример #6
0
        /// <summary>Calculates the total margin for the specified regulation role, value entities and parameter entities.</summary>
        /// <param name="regulationRole">An enumerator value of type <see cref="T:InitialMargin.Core.RegulationRole"/> that specifies the target regulation role.</param>
        /// <param name="values">The <see cref="System.Collections.Generic.ICollection{T}"/> of <see cref="T:InitialMargin.Core.DataValue"/> objects representing the target value entities.</param>
        /// <param name="parameters">The <see cref="System.Collections.Generic.ICollection{T}"/> of <see cref="T:InitialMargin.Core.DataParameter"/> objects representing the target parameter entities.</param>
        /// <returns>A <see cref="T:InitialMargin.Core.MarginTotal"/> object representing the total margin.</returns>
        /// <exception cref="T:System.ArgumentNullException">Thrown when <paramref name="values">values</paramref> is <c>null</c> or when <paramref name="parameters">parameters</paramref> is <c>null</c>.</exception>
        /// <exception cref="T:System.InvalidOperationException">Thrown when <paramref name="values">values</paramref> contains elements defined on different regulations or when <paramref name="parameters">parameters</paramref> contains elements defined on different regulations.</exception>
        /// <exception cref="T:System.ComponentModel.InvalidEnumArgumentException">Thrown when <paramref name="regulationRole">regulationRole</paramref> is undefined.</exception>
        public MarginTotal CalculateDetailed(RegulationRole regulationRole, ICollection <DataValue> values, ICollection <DataParameter> parameters)
        {
            if (!Enum.IsDefined(typeof(RegulationRole), regulationRole))
            {
                throw new InvalidEnumArgumentException("Invalid regulation role specified.");
            }

            if (values == null)
            {
                throw new ArgumentNullException(nameof(values));
            }

            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            List <Regulation> regulations = values.SelectMany(x => SelectRegulations(x, regulationRole))
                                            .Concat(parameters.SelectMany(x => SelectRegulations(x, regulationRole)))
                                            .OrderBy(x => x)
                                            .Distinct().ToList();

            if (regulations.Count > 1)
            {
                throw new InvalidOperationException($"All data entities must either have no regulations defined or belong to a single {((regulationRole == RegulationRole.Pledgor) ? "post" : "collect")} regulation.");
            }

            List <DataValue> valuesFinal = values.Where(x => !(x is PresentValue) && !(x is Sensitivity)).Select(x => (DataValue)x.Clone())
                                           .Concat(values.OfType <PresentValue>().Select(x => AdjustedClone(x, regulationRole)))
                                           .Concat(values.OfType <Sensitivity>().Select(x => AdjustedClone(x, regulationRole)))
                                           .ToList();

            List <DataParameter> parametersFinal = parameters
                                                   .Select(x => (DataParameter)x.Clone())
                                                   .ToList();

            List <IMargin> margins = new List <IMargin>(m_Processors.Count);

            foreach (Processor processor in m_Processors)
            {
                margins.Add(processor.Process(valuesFinal, parametersFinal));
            }

            return(MarginTotal.Of(regulationRole, regulations.Single(), m_ValuationDate, m_CalculationCurrency, margins));
        }
Пример #7
0
        private MarginTotal Process(List <Sensitivity> sensitivities, List <AddOnProductMultiplier> productMultipliers, List <AddOnNotional> notionals, List <AddOnNotionalFactor> notionalFactors, List <AddOnFixedAmount> fixedAmounts)
        {
            if (sensitivities == null)
            {
                throw new ArgumentNullException(nameof(sensitivities));
            }

            if (productMultipliers == null)
            {
                throw new ArgumentNullException(nameof(productMultipliers));
            }

            if (notionals == null)
            {
                throw new ArgumentNullException(nameof(notionals));
            }

            if (notionalFactors == null)
            {
                throw new ArgumentNullException(nameof(notionalFactors));
            }

            if (fixedAmounts == null)
            {
                throw new ArgumentNullException(nameof(fixedAmounts));
            }

            ModelObject?modelObject = SanitizeData(sensitivities, productMultipliers, notionals, notionalFactors, fixedAmounts);

            if (!modelObject.HasValue)
            {
                return(MarginTotal.Of(m_ValuationDate, m_CalculationCurrency));
            }

            ModelObject modelObjectValue = modelObject.Value;

            sensitivities      = modelObjectValue.Sensitivities;
            notionals          = modelObjectValue.Notionals;
            notionalFactors    = modelObjectValue.NotionalFactors;
            productMultipliers = modelObjectValue.ProductMultipliers;
            fixedAmounts       = modelObjectValue.FixedAmounts;

            List <Sensitivity> sensitivitiesVega = sensitivities
                                                   .RemoveAllAndGet(x => x.Category == SensitivityCategory.Vega)
                                                   .ToList();

            if (sensitivitiesVega.Count > 0)
            {
                List <Sensitivity> sensitivitiesCurvature = sensitivitiesVega
                                                            .Select(x => x.ToCurvature(ModelCalculations.CalculateCurvatureAmount(x)))
                                                            .ToList();

                List <Sensitivity> sensitivitiesVolatilityWeighted = sensitivitiesVega
                                                                     .Concat(sensitivitiesCurvature)
                                                                     .ToList();

                foreach (Sensitivity sensitivity in sensitivitiesVolatilityWeighted)
                {
                    sensitivity.ChangeAmount(sensitivity.Amount * ModelParameters.GetWeightVolatility(sensitivity));
                }

                sensitivities.AddRange(sensitivitiesVolatilityWeighted);
            }

            List <Sensitivity> sensitivitiesNetted = ModelCalculations.NetSensitivities(m_CalculationCurrency, sensitivities);

            List <MarginProduct> productMargins = ModelCalculations.CalculateMarginsProduct(m_CalculationCurrency, m_RatesProvider, sensitivitiesNetted);
            Amount productMarginsAmount         = Amount.Sum(productMargins.Select(x => x.Value), m_CalculationCurrency);

            MarginAddOn addOnMargin       = ModelCalculations.CalculateMarginAddOn(m_CalculationCurrency, productMargins, productMultipliers, notionals, notionalFactors, fixedAmounts);
            Amount      addOnMarginAmount = addOnMargin?.Value ?? Amount.OfZero(m_CalculationCurrency);

            Amount modelMarginAmount = productMarginsAmount + addOnMarginAmount;
            Margin modelMargin       = Margin.Of(modelMarginAmount, productMargins, addOnMargin);

            return(MarginTotal.Of(m_ValuationDate, m_CalculationCurrency, modelMargin));
        }
Пример #8
0
 /// <summary>Writes the specified calculation result into the specified CSV file, using the default delimiter (see <see cref="P:InitialMargin.IO.CsvUtilities.DefaultDelimiter"/>).</summary>
 /// <param name="filePath">The <see cref="T:System.String"/> representing the file to write to.</param>
 /// <param name="margin">The <see cref="T:InitialMargin.Core.MarginTotal"/> object to write.</param>
 public void Write(String filePath, MarginTotal margin)
 {
     Write(filePath, margin, CsvUtilities.DefaultDelimiter);
 }