예제 #1
0
        /// <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);
        }