public double Calculate() { // fetch portfolios by using the provider Portfolios = PortfolioProvider.Portfolios; // call market data provider and gathering product parameters ProductParameters = ProductParametersProvider.ProductsParameters; // look over all portfolios and getting the positions IEnumerable <KeyValuePair <Product, long> > allTransactions = Portfolios.SelectMany(x => x.Transactions) .GroupBy(y => y.Product) .Select(z => new KeyValuePair <Product, long>(z.Key, z.Sum(x => x.Position))); Positions = allTransactions.ToDictionary(t => t.Key, t => t.Value); // foreach product do the montecarlo simulation with the target product parameter // and multiply it by the position value and calculate the lost value var lostsValuesByProduct = new Dictionary <string, IEnumerable <double> >(); foreach (var pos in Positions) { long position = pos.Value; ProductParameters parameters = ProductParameters.First(x => x.Product.Equals(pos.Key)); var normalDistribution = new NormalEnumerable(); var input = new MonteCarloInput { Parameters = parameters, Position = position, }; IEnumerable <double> results = normalDistribution.Take(TotalSimulations) .Select(alea => StatisticsUtilities.CalculateLoss(input, alea)) .ToList(); lostsValuesByProduct.Add(pos.Key.Name, results); } // aggregate the lost value for all products IList <double> totals = new List <double>(); Func <IList <double>, string, IList <double> > sumList = (current, key) => Helpers.SumList(current, lostsValuesByProduct[key].ToList()); totals = lostsValuesByProduct.Keys.Aggregate(totals, sumList); // put prices and positions at the portfolio level // choose the var at 99% for 1 day return(StatisticsUtilities.CalculateVar(totals, 0.99)); }