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)); }
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); }
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); }
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); }
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)); }
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)); }
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); }
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); }
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)); }
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))); }
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 }))); }
public abstract MarginSensitivity CalculateMargin(Currency calculationCurrency, FxRatesProvider ratesProvider, SensitivityRisk risk, SensitivityCategory category, List <Sensitivity> sensitivities);
private MarginRisk(SensitivityRisk risk, Amount amount, List <MarginSensitivity> sensitivityMargins) : base(LEVEL, NAME, risk.ToString(), amount, sensitivityMargins) { m_Risk = risk; }