/// <summary> /// Calculates open positions. /// </summary> /// <returns>Detailed information about open positions.</returns> public IDetailedOpenPositionOverview CalculateOpenPositions() { var calculateProfit = new Func <IOpenPosition, IQuotation, IProfit>((pos, quote) => _transactionPerformanceService.GetProfit( pos.Shares * pos.PricePerShare, pos.OrderCosts, pos.Shares * (quote?.Close ?? 0), 0m, 0m)); var result = new DetailedOpenPositionOverview { OpenPositions = _queryDispatcher.Execute(new OpenPositionsAllQuery()) .Select(pos => { var quote = _queryDispatcher.Execute(new StockQuotationsLatestByIdQuery(pos.ProductId)); return(new DetailedOpenPosition(_queryDispatcher.Execute(new StockByIdQuery(pos.ProductId))) { AveragePricePerShare = pos.PricePerShare, FirstOrderDate = pos.FirstOrderDate, PositionSize = pos.PositionSize, Shares = pos.Shares, CurrentQuotation = quote, Profit = calculateProfit(pos, quote), OrderCosts = pos.OrderCosts }); }).ToList() }; result.Summary = new DetailedOpenPositionSummary { PositionSize = result.OpenPositions.Sum(o => o.PositionSize), Profit = _transactionPerformanceService.GetProfit( result.OpenPositions.Sum(o => o.PositionSize), 0m, result.OpenPositions.Sum(o => (o.CurrentQuotation?.Close ?? 0) * o.Shares), 0m, 0m) }; return(result); }
/// <summary> /// Calculates open positions. /// </summary> /// <returns>Detailed information about open positions.</returns> public IDetailedOpenPositionOverview CalculateOpenPositions() { var beginOfYear = new DateTime(DateTime.Now.Year, 1, 1, 0, 0, 0); var calculateProfit = new Func <IOpenPosition, IQuotation, IProfit>((pos, quote) => _transactionPerformanceService.GetProfit( pos.Shares * pos.PricePerShare, pos.OrderCosts, pos.Shares * (quote?.Close ?? 0), 0m, 0m)); var calculateYtdProfit = new Func <IOpenPosition, IStock, IQuotation, IProfit>((pos, stock, quote) => { var buyingQuote = _queryDispatcher.Execute(new StockQuotationsLastBeforeDateByIdQuery(stock.Id, beginOfYear)); if (buyingQuote == null || quote == null) { return(new Profit(0, 0)); } //Add dividend revenue var query = new TransactionAllQuery() .Register(new TransactionStartDateFilter(beginOfYear)) .Register(new TransactionEndDateFilter(DateTime.Now)) .Register(new TransactionStockFilter(stock)) .Register(new TransactionDividendFilter(true)); var dividends = _queryDispatcher.Execute(query) .OfType <IDividendTransaction>().Sum(t => t.PositionSize - t.Taxes - t.OrderCosts); return(_transactionPerformanceService.GetProfit( pos.Shares * buyingQuote.Close, pos.OrderCosts, pos.Shares * quote.Close + dividends, 0m, 0m)); }); var result = new DetailedOpenPositionOverview { OpenPositions = _queryDispatcher.Execute(new OpenPositionsAllQuery()) .Select(pos => { var stock = _queryDispatcher.Execute(new StockByIdQuery(pos.ProductId)); var quote = stock.Quotations.OrderByDescending(q => q.Date).FirstOrDefault(); return(new DetailedOpenPosition(stock) { AveragePricePerShare = pos.PricePerShare, FirstOrderDate = pos.FirstOrderDate, PositionSize = pos.PositionSize, Shares = pos.Shares, CurrentQuotation = quote, Profit = calculateProfit(pos, quote), YearToDateProfit = calculateYtdProfit(pos, stock, quote), OrderCosts = pos.OrderCosts }); }).ToList() }; result.Summary = new DetailedOpenPositionSummary { PositionSize = result.OpenPositions.Sum(o => o.PositionSize), Profit = _transactionPerformanceService.GetProfit( result.OpenPositions.Sum(o => o.PositionSize), 0m, result.OpenPositions.Sum(o => (o.CurrentQuotation?.Close ?? 0) * o.Shares), 0m, 0m) }; return(result); }