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)); }