예제 #1
0
        public static MarginRisk Of(SensitivityRisk risk, Amount amount, List <MarginSensitivity> sensitivityMargins)
        {
            if (!Enum.IsDefined(typeof(SensitivityRisk), risk))
            {
                throw new InvalidEnumArgumentException("Invalid sensitivity risk specified.");
            }

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

            if (sensitivityMargins.Count == 0)
            {
                throw new ArgumentException("No sensitivity margins have been provided.", nameof(sensitivityMargins));
            }

            if (sensitivityMargins.Any(x => x == null))
            {
                throw new ArgumentException("One or more sensitivity margins are null.", nameof(sensitivityMargins));
            }

            List <MarginSensitivity> sensitivityMarginsSorted = sensitivityMargins
                                                                .OrderBy(x => (Int32)x.Category)
                                                                .ToList();

            return(new MarginRisk(risk, amount, sensitivityMarginsSorted));
        }
예제 #2
0
        private static Amount CalculateCorrelatedSumRisks(Currency calculationCurrency, List <MarginRisk> riskMargins)
        {
            Amount sum = Amount.OfZero(calculationCurrency);

            foreach (MarginRisk marginRisk1 in riskMargins)
            {
                foreach (MarginRisk marginRisk2 in riskMargins)
                {
                    SensitivityRisk risk1 = marginRisk1.Risk;
                    SensitivityRisk risk2 = marginRisk2.Risk;

                    if (risk1 != risk2)
                    {
                        Decimal correlation = ModelParameters.GetCorrelationRisk(risk1, risk2);
                        sum += marginRisk1.Value * marginRisk2.Value * correlation;
                    }
                }
            }

            return(sum);
        }
예제 #3
0
            private static Amount CalculateCorrelatedSumWeights(Currency calculationCurrency, SensitivityRisk risk, List <MarginWeighting> weightingMargins, Dictionary <String, Decimal> thresholdFactors)
            {
                Amount sum = Amount.OfZero(calculationCurrency);

                foreach (MarginWeighting marginWeighting1 in weightingMargins)
                {
                    foreach (MarginWeighting marginWeighting2 in weightingMargins)
                    {
                        Sensitivity sensitivity1 = marginWeighting1.Sensitivity;
                        Sensitivity sensitivity2 = marginWeighting2.Sensitivity;

                        if (sensitivity1 != sensitivity2)
                        {
                            Decimal thresholdFactor1 = thresholdFactors[sensitivity1.Qualifier];
                            Decimal thresholdFactor2 = thresholdFactors[sensitivity2.Qualifier];
                            Decimal concentration    = Math.Min(thresholdFactor1, thresholdFactor2) / Math.Max(thresholdFactor1, thresholdFactor2);

                            Decimal correlationSensitivity = ModelParameters.GetCorrelationSensitivity(risk, sensitivity1, sensitivity2);
                            Decimal correlation            = correlationSensitivity * concentration;

                            sum += marginWeighting1.Value * marginWeighting2.Value * correlation;
                        }
                    }
                }

                return(sum);
            }
예제 #4
0
            private static Amount CalculateCorrelatedSumBuckets(Currency calculationCurrency, SensitivityRisk risk, Dictionary <IBucket, Decimal> thresholdFactors, List <MarginBucket> bucketMargins)
            {
                Dictionary <IBucket, Amount> weightingMarginSums = new Dictionary <IBucket, Amount>();

                foreach (MarginBucket bucketMargin in bucketMargins)
                {
                    Amount weightingMarginsSum = Amount.Sum(bucketMargin.Children.Select(x => x.Value), calculationCurrency);
                    Amount bucketMarginValue   = Amount.Max(Amount.Min(weightingMarginsSum, bucketMargin.Value), -bucketMargin.Value);
                    weightingMarginSums[bucketMargin.Bucket] = bucketMarginValue;
                }

                Amount sum = Amount.OfZero(calculationCurrency);

                foreach (IBucket bucket1 in weightingMarginSums.Keys)
                {
                    foreach (IBucket bucket2 in weightingMarginSums.Keys)
                    {
                        if (bucket1 != bucket2)
                        {
                            Decimal thresholdFactor1 = thresholdFactors[bucket1];
                            Decimal thresholdFactor2 = thresholdFactors[bucket2];
                            Decimal concentration    = Math.Min(thresholdFactor1, thresholdFactor2) / Math.Max(thresholdFactor1, thresholdFactor2);

                            Decimal correlationBucket = ModelParameters.GetCorrelationBucket(risk, bucket1, bucket2);
                            Decimal correlation       = correlationBucket * concentration;

                            sum += weightingMarginSums[bucket1] * weightingMarginSums[bucket2] * correlation;
                        }
                    }
                }

                return(sum);
            }
예제 #5
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);
                Dictionary <IBucket, Dictionary <String, Decimal> > thresholdFactors = new Dictionary <IBucket, Dictionary <String, Decimal> >();

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

                    thresholdFactors[bucket] = sensitivitiesByBucket
                                               .GroupBy(x => new { x.Bucket, x.Qualifier })
                                               .ToDictionary(x => x.Key.Qualifier, x => CalculateThresholdFactor(calculationCurrency, ratesProvider, risk, category, x.ToList()));

                    List <MarginWeighting> weightingMargins = CalculateMarginsWeighting(category, thresholdFactors[bucket], sensitivitiesByBucket);
                    Amount sumSquared         = Amount.Sum(weightingMargins.Select(x => Amount.Square(x.Value)), calculationCurrency);
                    Amount sumCorrelated      = CalculateCorrelatedSumWeights(calculationCurrency, risk, weightingMargins, thresholdFactors[bucket]);
                    Amount bucketMarginAmount = Amount.SquareRoot(sumSquared + sumCorrelated);

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

                List <MarginBucket> bucketMarginsNonResidual = bucketMargins.Where(x => !x.Bucket.IsResidual).ToList();
                Amount sumSquaredNonResidual = Amount.Sum(bucketMarginsNonResidual.Select(x => Amount.Square(x.Value)), calculationCurrency);

                List <MarginBucket> bucketMarginsResidual = bucketMargins.Where(x => x.Bucket.IsResidual).ToList();
                Amount sumSquaredResidual = Amount.Sum(bucketMarginsResidual.Select(x => Amount.Square(x.Value)), calculationCurrency);

                Amount sumCorrelatedNonResidual;

                if ((risk == SensitivityRisk.Rates) && (category == SensitivityCategory.Delta))
                {
                    Dictionary <IBucket, Decimal> bucketThresholdFactors = thresholdFactors.ToDictionary(x => x.Key, x => x.Value.Values.Single());
                    sumCorrelatedNonResidual = CalculateCorrelatedSumBuckets(calculationCurrency, risk, bucketThresholdFactors, bucketMarginsNonResidual);
                }
                else
                {
                    sumCorrelatedNonResidual = CalculateCorrelatedSumBuckets(calculationCurrency, risk, bucketMarginsNonResidual);
                }

                Amount sensitivityMarginAmount = Amount.SquareRoot(sumSquaredNonResidual + sumCorrelatedNonResidual) + Amount.SquareRoot(sumSquaredResidual);

                return(MarginSensitivity.Of(category, sensitivityMarginAmount, bucketMargins));
            }
예제 #6
0
            private static Amount CalculateMarginByBuckets(Currency calculationCurrency, SensitivityRisk risk, Boolean residuals, List <MarginBucket> bucketMargins)
            {
                if (residuals)
                {
                    bucketMargins = bucketMargins.Where(x => x.Bucket.IsResidual).ToList();
                }
                else
                {
                    bucketMargins = bucketMargins.Where(x => !x.Bucket.IsResidual).ToList();
                }

                Amount crossBucketSum         = Amount.Sum(bucketMargins.Select(x => Amount.Square(x.Value)), calculationCurrency);
                Amount crossBucketCorrelation = residuals ? Amount.OfZero(calculationCurrency) : CalculateCorrelatedSumBuckets(calculationCurrency, risk, bucketMargins);

                List <IMargin> weightingMargins = bucketMargins.SelectMany(x => x.Children).ToList();
                Amount         cvr         = Amount.Sum(weightingMargins.Select(x => x.Value), calculationCurrency);
                Amount         cvrAbsolute = Amount.Sum(weightingMargins.Select(x => Amount.Abs(x.Value)), calculationCurrency);

                Decimal theta  = cvrAbsolute.IsZero ? 0m : Amount.Min(cvr / cvrAbsolute, 0m).Value;
                Decimal lambda = ModelParameters.GetCurvatureLambda(theta);
                Amount  kappa  = Amount.SquareRoot(crossBucketSum + crossBucketCorrelation);

                return(Amount.Max(cvr + (lambda * kappa), 0m));
            }
예제 #7
0
            private static Amount CalculateCorrelatedSumWeights(Currency calculationCurrency, SensitivityRisk risk, List <MarginWeighting> weightingMargins)
            {
                Amount sum = Amount.OfZero(calculationCurrency);

                foreach (MarginWeighting marginWeighting1 in weightingMargins)
                {
                    foreach (MarginWeighting marginWeighting2 in weightingMargins)
                    {
                        Sensitivity sensitivity1 = marginWeighting1.Sensitivity;
                        Sensitivity sensitivity2 = marginWeighting2.Sensitivity;

                        if (sensitivity1 != sensitivity2)
                        {
                            Decimal correlation = MathUtilities.Square(ModelParameters.GetCorrelationSensitivity(risk, sensitivity1, sensitivity2));
                            sum += marginWeighting1.Value * marginWeighting2.Value * correlation;
                        }
                    }
                }

                return(sum);
            }
예제 #8
0
            private static Amount CalculateCorrelatedSumBuckets(Currency calculationCurrency, SensitivityRisk risk, List <MarginBucket> bucketMargins)
            {
                Dictionary <IBucket, Amount> weightingMarginSums = new Dictionary <IBucket, Amount>();

                foreach (MarginBucket bucketMargin in bucketMargins)
                {
                    Amount weightingMarginsSum = Amount.Sum(bucketMargin.Children.Select(x => x.Value), calculationCurrency);
                    Amount bucketMarginAmount  = Amount.Max(Amount.Min(weightingMarginsSum, bucketMargin.Value), -bucketMargin.Value);
                    weightingMarginSums[bucketMargin.Bucket] = bucketMarginAmount;
                }

                Amount sum = Amount.OfZero(calculationCurrency);

                foreach (IBucket bucket1 in weightingMarginSums.Keys)
                {
                    foreach (IBucket bucket2 in weightingMarginSums.Keys)
                    {
                        if (bucket1 != bucket2)
                        {
                            Decimal correlation = MathUtilities.Square(ModelParameters.GetCorrelationBucket(risk, bucket1, bucket2));
                            sum += weightingMarginSums[bucket1] * weightingMarginSums[bucket2] * correlation;
                        }
                    }
                }

                return(sum);
            }
예제 #9
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));
            }
예제 #10
0
        private static Decimal CalculateThresholdFactor(Currency calculationCurrency, FxRatesProvider ratesProvider, SensitivityRisk risk, SensitivityCategory category, List <Sensitivity> sensitivities)
        {
            if ((risk == SensitivityRisk.Rates) && (category == SensitivityCategory.Delta))
            {
                sensitivities = sensitivities.Where(x => x.Subrisk != SensitivitySubrisk.CrossCurrencyBasis).ToList();

                if (sensitivities.Count == 0)
                {
                    return(1m);
                }
            }

            Amount sum = Amount.Abs(Amount.Sum(sensitivities.Select(x => x.Amount), calculationCurrency));

            IThresholdIdentifier thresholdIdentifier = sensitivities.Select(y => y.ThresholdIdentifier).Distinct().Single();
            Amount threshold = ratesProvider.Convert(ModelParameters.GetThreshold(risk, category, thresholdIdentifier), calculationCurrency);

            return(Math.Max(1m, MathUtilities.SquareRoot((sum / threshold).Value)));
        }
예제 #11
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 <MarginWeighting> weightingMargins = CalculateMarginsWeighting(SensitivityCategory.BaseCorrelation, sensitivities);
                Amount sumSquared    = Amount.Sum(weightingMargins.Select(x => Amount.Square(x.Value)), calculationCurrency);
                Amount sumCorrelated = CalculateCorrelatedSumWeights(calculationCurrency, weightingMargins);
                Amount amount        = Amount.SquareRoot(sumSquared + sumCorrelated);

                MarginBucket bucketMargin = MarginBucket.Of(Placeholder.Instance, amount, weightingMargins);

                return(MarginSensitivity.Of(SensitivityCategory.BaseCorrelation, amount, (new List <MarginBucket> {
                    bucketMargin
                })));
            }
예제 #12
0
 public abstract MarginSensitivity CalculateMargin(Currency calculationCurrency, FxRatesProvider ratesProvider, SensitivityRisk risk, SensitivityCategory category, List <Sensitivity> sensitivities);
예제 #13
0
 private MarginRisk(SensitivityRisk risk, Amount amount, List <MarginSensitivity> sensitivityMargins) : base(LEVEL, NAME, risk.ToString(), amount, sensitivityMargins)
 {
     m_Risk = risk;
 }