public string GetReport(Portfolio portfolio, IEnumerable<Category> categories, IEnumerable<CategoryWeight> weights) { var reportBuilder = new StringBuilder(); var quotes = GetQuotes(portfolio); var valuesDict = CalculateValues(portfolio, quotes); var weightsList = weights.ToList(); //DebugPrint(reportBuilder, valuesDict); var total = valuesDict.Values.Where(v => v > 0M).Sum(); reportBuilder.AppendLine(string.Format("Portfolio: {0}", portfolio.Name)); foreach (var category in categories) { Dictionary<string, decimal> calculations = new Dictionary<string, decimal>(); foreach (var kvpair in valuesDict) { var weight = weightsList.Single(w => w.Security.Symbol.Equals(kvpair.Key) && w.Value.Category == category); if (calculations.ContainsKey(weight.Value.Name)) calculations[weight.Value.Name] += kvpair.Value; else calculations.Add(weight.Value.Name, kvpair.Value); } reportBuilder.AppendLine(string.Format("\r\n{0}", category.Name)); foreach (var kvpair in calculations.OrderByDescending(kv => kv.Value)) { reportBuilder.AppendLine(String.Format("{0}: {1:N1}%", kvpair.Key, kvpair.Value / total * 100M)); } } return reportBuilder.ToString(); }