public YearlyReportStockGroupViewModel(YearlyReportStockGroupDTO dto)
 {
     StockGroup = dto;
 }
        private IEnumerable<YearlyReportStockGroupDTO> GetReportStockGroups(int year, Deposit deposit)
        {
            if (!deposit.Trades.Any())
                yield break;

            var tradeGroups =
                from trade in deposit.Trades
                where trade.TradeDate.Year <= year
                group trade by trade.Stock.Splitted into grp
                select new
                {
                    StockName = grp.Key.Name,
                    Trades = grp.OrderBy(p => p.TradeDate)
                };

            foreach (var tradeGroup in tradeGroups)
            {
                var stockGroupItems = new List<YearlyReportStockGroupItemDTO>();

                int buyQuantitySum = 0;
                decimal buyMarketvalueSum = 0;

                int taxFreeBuyQuantitySum = 0;
                decimal taxFreeBuyMarketvalueSum = 0;

                foreach (var trade in tradeGroup.Trades)
                {
                    decimal marketvalue = trade.MarketvalueInclCommission;
                    int quantity = trade.QuantitySplitted();

                    decimal buyValue = 0;
                    decimal sellValue = 0;
                    decimal tradeProfitLoss = 0;

                    if (trade.IsBuy)
                    {
                        if (trade.TradeDate.Year < 2006)
                        {
                            // Aktier købt inden 2006 sælges skattefrit, så beregner den skattefrie beholdning.
                            taxFreeBuyQuantitySum += quantity;
                            taxFreeBuyMarketvalueSum += marketvalue;
                        }
                        else
                        {
                            buyQuantitySum += quantity;
                            buyMarketvalueSum += marketvalue;
                        }

                        buyValue = marketvalue;
                    }
                    else
                    {
                        decimal salesPrice = marketvalue / quantity;
                        Tuple<decimal, decimal> tradeProfitLossItem = null;

                        // Skattefri gevinst bruges ikke til noget pt.
                        // Den burde nok indgå i total indkomst, men ikke i skatteberegningerne.
                        Tuple<decimal, decimal> tradeTaxFreeProfitLossItem = null;

                        if (taxFreeBuyQuantitySum > 0)
                        {
                            int taxedQuantity = quantity - taxFreeBuyQuantitySum;

                            if (taxedQuantity > 0)
                            {
                                // Delvist skattefrit salg. Har både en skattefri og en skattepligtig gevinst.
                                tradeTaxFreeProfitLossItem =
                                    CalculateProfitLoss(ref taxFreeBuyMarketvalueSum, ref taxFreeBuyQuantitySum, taxFreeBuyQuantitySum, salesPrice);

                                tradeProfitLossItem =
                                    CalculateProfitLoss(ref buyMarketvalueSum, ref buyQuantitySum, taxedQuantity, salesPrice);
                            }
                            else
                            {
                                // Fuldt skattefrit salg. Har kun en skattefri gevinst.
                                tradeTaxFreeProfitLossItem =
                                    CalculateProfitLoss(ref taxFreeBuyMarketvalueSum, ref taxFreeBuyQuantitySum, quantity, salesPrice);
                            }
                        }
                        else
                        {
                            // Fuldt skattepligtigt salg.
                            tradeProfitLossItem =
                                CalculateProfitLoss(ref buyMarketvalueSum, ref buyQuantitySum, quantity, salesPrice);
                        }

                        sellValue = marketvalue;
                        buyValue = tradeProfitLossItem.Item1;
                        tradeProfitLoss = tradeProfitLossItem.Item2;
                    }

                    if (trade.TradeDate.Year == year)
                    {
                        var stockGroupItem = new YearlyReportStockGroupItemDTO
                        (
                            description: trade.IsBuy ? "Køb" : "Salg",
                            date: trade.TradeDate.Date,
                            quantity: trade.Quantity,
                            sellValue: sellValue,
                            buyValue: buyValue,
                            profitLoss: tradeProfitLoss,
                            isProfit: tradeProfitLoss >= 0,
                            isSale: !trade.IsBuy
                        );

                        stockGroupItems.Add(stockGroupItem);
                    }
                }

                if (stockGroupItems.Any())
                {
                    var stockProfitLoss = stockGroupItems.Sum(p => p.ProfitLoss);

                    var stockGroup = new YearlyReportStockGroupDTO(
                        header: tradeGroup.StockName,
                        profitLoss: stockProfitLoss,
                        isProfit: stockProfitLoss >= 0,
                        items: stockGroupItems);

                    yield return stockGroup;
                }
            }
        }