public static MarginProduct CalculateMarginProduct(DateTime valuationDate, Currency calculationCurrency, Product product, List <Notional> notionals, List <PresentValue> presentValues) { if (calculationCurrency == null) { throw new ArgumentNullException(nameof(calculationCurrency)); } if (!Enum.IsDefined(typeof(Product), product)) { throw new InvalidEnumArgumentException("Invalid product specified."); } if (notionals == null) { throw new ArgumentNullException(nameof(notionals)); } if (presentValues == null) { throw new ArgumentNullException(nameof(presentValues)); } Amount netReplacementCost = Amount.Max(Amount.Sum(presentValues.Select(x => - x.Amount), calculationCurrency), 0m); Amount grossReplacementCost = Amount.Sum(presentValues.Select(x => Amount.Max(-x.Amount, 0m)), calculationCurrency); Decimal ngRatio = grossReplacementCost.IsZero ? 1m : (netReplacementCost / grossReplacementCost).Value; Amount marginAmountGross = Amount.Sum(notionals.Select(x => Amount.Abs(x.Amount) * ScheduleParameters.GetNotionalFactor(valuationDate, x)), calculationCurrency); Decimal marginFactor = ScheduleParameters.GetMarginFactor(ngRatio); Amount marginAmountNet = marginAmountGross * marginFactor; return(MarginProduct.Of(product, marginAmountNet)); }
public void Amount_Abs_HoldsKeepPrecisionFlag() { Commodity commodity1 = new Commodity(CommodityPool.Current, new CommodityBase("AAHKPF1")); Amount amt1 = new Amount(Quantity.FromLong(10).SetKeepPrecision(true), null); Amount result = amt1.Abs(); Assert.IsTrue(result.KeepPrecision); }
private MarginTotal Process(List <Notional> notionals, List <PresentValue> presentValues) { if (notionals == null) { throw new ArgumentNullException(nameof(notionals)); } if (presentValues == null) { throw new ArgumentNullException(nameof(presentValues)); } List <ScheduleObject> scheduleObjects = SanitizeData(notionals, presentValues); if (scheduleObjects.Count == 0) { return(MarginTotal.Of(m_ValuationDate, m_CalculationCurrency)); } HashSet <Product> products = new HashSet <Product>(); List <Notional> notionalsNetted = new List <Notional>(scheduleObjects.Count); List <PresentValue> presentValuesNetted = new List <PresentValue>(scheduleObjects.Count); foreach (ScheduleObject obj in scheduleObjects) { Amount notionalsSum = Amount.Abs(Amount.Sum(obj.Notionals.Select(x => x.Amount), m_CalculationCurrency)); notionalsNetted.Add(Notional.Of(obj.Product, notionalsSum, RegulationsInfo.Empty, obj.TradeInfo)); Amount presentValuesSum = Amount.Sum(obj.PresentValues.Select(x => x.Amount), m_CalculationCurrency); presentValuesNetted.Add(PresentValue.Of(obj.Product, presentValuesSum, RegulationsInfo.Empty, obj.TradeInfo)); products.Add(obj.Product); } List <MarginProduct> productMargins = new List <MarginProduct>(products.Count); foreach (Product product in products.OrderBy(x => x)) { List <Notional> notionalsByProduct = notionalsNetted.Where(x => x.Product == product).ToList(); List <PresentValue> presentValuesByProduct = presentValuesNetted.Where(x => x.Product == product).ToList(); MarginProduct productMargin = ScheduleCalculations.CalculateMarginProduct(m_ValuationDate, m_CalculationCurrency, product, notionalsByProduct, presentValuesByProduct); productMargins.Add(productMargin); } Margin scheduleMargin = ScheduleCalculations.CalculateMargin(m_ValuationDate, m_CalculationCurrency, productMargins, notionals, presentValues); return(MarginTotal.Of(m_ValuationDate, m_CalculationCurrency, scheduleMargin)); }
public void Amount_Abs_ReturnsNewAmountWithAbsoluteValue() { Commodity commodity1 = new Commodity(CommodityPool.Current, new CommodityBase("base-1")); Amount amount1 = new Amount(10, commodity1); Amount amount2 = new Amount(-10, commodity1); Amount result1 = amount1.Abs(); Amount result2 = amount2.Abs(); Assert.AreEqual(10, result1.Quantity.ToLong()); Assert.AreEqual(10, result2.Quantity.ToLong()); Assert.IsTrue(Object.ReferenceEquals(result1, amount1)); // If the value is not changed, return the original object Assert.IsFalse(Object.ReferenceEquals(result2, amount2)); }
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))); }
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)); }
public CostBreakdown Exchange(Amount amount, Amount cost, bool isPerUnit = false, bool addPrice = true, DateTime?moment = null, string tag = null) { Logger.Debug("commodity.prices.add", () => String.Format("exchange: {0} for {1}", amount, cost)); Logger.Debug("commodity.prices.add", () => String.Format("exchange: is-per-unit = {0}", isPerUnit)); if (moment.HasValue) { Logger.Debug("commodity.prices.add", () => String.Format("exchange: moment = {0}", moment.Value)); } if (tag != null) { Logger.Debug("commodity.prices.add", () => String.Format("exchange: tag = {0}", tag)); } Commodity commodity = amount.Commodity; Annotation currentAnnotation = null; if (commodity.IsAnnotated) { currentAnnotation = ((AnnotatedCommodity)commodity).Details; } Amount perUnitCost = isPerUnit || amount.IsRealZero ? cost.Abs() : (cost / amount).Abs(); if (!cost.HasCommodity) { perUnitCost.ClearCommodity(); } Logger.Debug("commodity.prices.add", () => String.Format("exchange: per-unit-cost = {0}", perUnitCost)); // Do not record commodity exchanges where amount's commodity has a // fixated price, since this does not establish a market value for the // base commodity. if (addPrice && !perUnitCost.IsRealZero && (currentAnnotation == null || !(currentAnnotation.Price != null && currentAnnotation.IsPriceFixated)) && commodity.Referent != perUnitCost.Commodity.Referent) { Exchange(commodity, perUnitCost, moment ?? TimesCommon.Current.CurrentTime); } CostBreakdown breakdown = new CostBreakdown(); breakdown.FinalCost = !isPerUnit ? cost : cost *amount.Abs(); Logger.Debug("commodity.prices.add", () => String.Format("exchange: final-cost = {0}", breakdown.FinalCost)); if (currentAnnotation != null && currentAnnotation.Price != null) { breakdown.BasisCost = (currentAnnotation.Price * amount).Unrounded(); } else { breakdown.BasisCost = breakdown.FinalCost; } Logger.Debug("commodity.prices.add", () => String.Format("exchange: basis-cost = {0}", breakdown.BasisCost)); Annotation annotation = new Annotation(perUnitCost, moment.HasValue ? (Date)moment.Value.Date : default(Date), tag); annotation.IsPriceCalculated = true; if (currentAnnotation != null && currentAnnotation.IsPriceFixated) { annotation.IsPriceFixated = true; } if (moment.HasValue) { annotation.IsDateCalculated = true; } if (!string.IsNullOrEmpty(tag)) { annotation.IsTagCalculated = true; } breakdown.Amount = new Amount(amount, annotation); Logger.Debug("commodity.prices.add", () => String.Format("exchange: amount = {0}", breakdown.Amount)); return(breakdown); }
private static List <MarginAddOnComponent> CalculateMarginsAddOnNotional(Currency calculationCurrency, List <AddOnNotional> notionals, List <AddOnNotionalFactor> notionalFactors) { if ((notionals.Count == 0) || (notionalFactors.Count == 0)) { return(new List <MarginAddOnComponent>(0)); } List <MarginAddOnComponent> margins = new List <MarginAddOnComponent>(); Dictionary <String, Decimal> notionalFactorsMap = notionalFactors .GroupBy(x => x.Qualifier) .ToDictionary(x => x.Key, x => x.Single().Parameter); Dictionary <String, Amount> notionalsMap = notionals .Where(x => notionalFactorsMap.ContainsKey(x.Qualifier)) .GroupBy(x => x.Qualifier) .ToDictionary(x => x.Key, x => Amount.Sum(x.Select(n => Amount.Abs(n.Amount)), calculationCurrency)); foreach (KeyValuePair <String, Decimal> entry in notionalFactorsMap) { if (!notionalsMap.ContainsKey(entry.Key)) { continue; } Amount notionalAmount = notionalsMap[entry.Key] * entry.Value; margins.Add(MarginAddOnNotional.Of(entry.Key, notionalAmount)); } return(margins); }
public long ToXactAmt() => Math.Sign(Amount) * (at.Fraction.Expand((decimal)Amount.Abs()) * 100 + Currency.ToByte());
/// <summary>Calculates the worst total margin among all the regulations for the specified regulation role, value entities and parameter entities.</summary> /// <param name="regulationRole">An enumerator value of type <see cref="T:InitialMargin.Core.RegulationRole"/> that specifies the target regulation role.</param> /// <param name="values">The <see cref="System.Collections.Generic.ICollection{T}"/> of <see cref="T:InitialMargin.Core.DataValue"/> objects representing the target value entities.</param> /// <param name="parameters">The <see cref="System.Collections.Generic.ICollection{T}"/> of <see cref="T:InitialMargin.Core.DataParameter"/> objects representing the target parameter entities.</param> /// <returns>A <see cref="T:InitialMargin.Core.MarginTotal"/> object representing the worst total margin among all the regulations.</returns> /// <exception cref="T:System.ArgumentNullException">Thrown when <paramref name="values">values</paramref> is <c>null</c> or when <paramref name="parameters">parameters</paramref> is <c>null</c>.</exception> /// <exception cref="T:System.ComponentModel.InvalidEnumArgumentException">Thrown when <paramref name="regulationRole">regulationRole</paramref> is undefined.</exception> public MarginTotal CalculateDetailedWorstOf(RegulationRole regulationRole, ICollection <DataValue> values, ICollection <DataParameter> parameters) { IDictionary <Regulation, MarginTotal> result = CalculateDetailedByRole(regulationRole, values, parameters); return(result.Select(x => x.Value).OrderByDescending(x => Amount.Abs(x.Value)).ThenBy(x => x.Regulation).FirstOrDefault()); }