public static Margin Of(Amount amount, List <MarginProduct> productMargins, MarginAddOn addOnMargin) { if (productMargins == null) { throw new ArgumentNullException(nameof(productMargins)); } if (productMargins.Count == 0) { throw new ArgumentException("No product margins have been provided.", nameof(productMargins)); } if (productMargins.Any(x => x == null)) { throw new ArgumentException("One or more product margins are null.", nameof(productMargins)); } List <IMargin> childrenSorted = productMargins .OrderBy(x => (Int32)x.Product) .Cast <IMargin>().ToList(); if (addOnMargin != null) { childrenSorted.Add(addOnMargin); } return(new Margin(amount, childrenSorted)); }
public static MarginAddOn CalculateMarginAddOn(Currency calculationCurrency, List <MarginProduct> productMargins, List <AddOnProductMultiplier> productMultipliers, List <AddOnNotional> notionals, List <AddOnNotionalFactor> notionalFactors, List <AddOnFixedAmount> fixedAmounts) { if (calculationCurrency == null) { throw new ArgumentNullException(nameof(calculationCurrency)); } if (productMargins == null) { throw new ArgumentNullException(nameof(productMargins)); } 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)); } List <MarginAddOnComponent> margins = new List <MarginAddOnComponent>(); margins.AddRange(CalculateMarginsAddOnProduct(productMargins, productMultipliers)); margins.AddRange(CalculateMarginsAddOnNotional(calculationCurrency, notionals, notionalFactors)); if (fixedAmounts.Count > 0) { Amount fixedAmountAmount = Amount.Sum(fixedAmounts.Select(x => x.Amount), calculationCurrency); margins.Add(MarginAddOnFixedAmount.Of(fixedAmountAmount)); } if (margins.Count == 0) { return(null); } Amount addOnMarginAmount = Amount.Sum(margins.Select(x => x.Value), calculationCurrency); MarginAddOn addOnMargin = MarginAddOn.Of(addOnMarginAmount, margins); return(addOnMargin); }
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)); }