Example #1
0
            public override MarginSensitivity CalculateMargin(Currency calculationCurrency, FxRatesProvider ratesProvider, SensitivityRisk risk, SensitivityCategory category, List <Sensitivity> sensitivities)
            {
                if (calculationCurrency == null)
                {
                    throw new ArgumentNullException(nameof(calculationCurrency));
                }

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

                if (!Enum.IsDefined(typeof(SensitivityRisk), risk))
                {
                    throw new InvalidEnumArgumentException("Invalid sensitivity risk specified.");
                }

                if (!Enum.IsDefined(typeof(SensitivityCategory), category))
                {
                    throw new InvalidEnumArgumentException("Invalid sensitivity category specified.");
                }

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

                List <IBucket>      buckets       = sensitivities.Select(x => x.Bucket).Distinct().OrderBy(x => x.Name).ToList();
                List <MarginBucket> bucketMargins = new List <MarginBucket>(buckets.Count);

                foreach (IBucket bucket in buckets)
                {
                    List <Sensitivity> sensitivitiesByBucket = sensitivities.Where(x => x.Bucket == bucket).ToList();

                    List <MarginWeighting> weightingMargins = CalculateMarginsWeighting(SensitivityCategory.Curvature, sensitivitiesByBucket);
                    Amount sumSquared         = Amount.Sum(weightingMargins.Select(x => Amount.Square(x.Value)), calculationCurrency);
                    Amount sumCorrelated      = CalculateCorrelatedSumWeights(calculationCurrency, risk, weightingMargins);
                    Amount bucketMarginAmount = Amount.SquareRoot(sumSquared + sumCorrelated);

                    bucketMargins.Add(MarginBucket.Of(bucket, bucketMarginAmount, weightingMargins));
                }

                Amount marginNonResidual       = CalculateMarginByBuckets(calculationCurrency, risk, false, bucketMargins);
                Amount marginResidual          = CalculateMarginByBuckets(calculationCurrency, risk, true, bucketMargins);
                Amount sensitivityMarginAmount = ModelParameters.GetCurvatureScaleFactor(risk) * (marginNonResidual + marginResidual);

                return(MarginSensitivity.Of(SensitivityCategory.Curvature, sensitivityMarginAmount, bucketMargins));
            }