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