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));
        }
Example #2
0
        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);
        }
Example #3
0
        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));
        }
Example #4
0
        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));
        }
Example #5
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)));
        }
Example #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));
            }
Example #7
0
        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);
        }
Example #8
0
        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);
        }
Example #9
0
 public long ToXactAmt()
 => Math.Sign(Amount) * (at.Fraction.Expand((decimal)Amount.Abs()) * 100 + Currency.ToByte());
Example #10
0
        /// <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());
        }