Esempio n. 1
0
        public async Task <IEnumerable <StockAnnualizedReturn> > GetAnnualizedReturnForCurrentHoldings(ulong userId, uint?monthsSincePurchase)
        {
            var toDate          = monthsSincePurchase == null ? DateTime.MaxValue : DateTime.Today.AddMonths((int)-monthsSincePurchase);
            var currentHoldings = await _stockHoldingService.GetAllHoldingsForUser(userId);

            var purchaseIds  = ExtractPurchaseIds(currentHoldings);
            var purchaseTask = _stockPurchaseService.GetPurchasesByIdFilteredByDates(userId, purchaseIds, DateTime.MinValue, toDate);
            var purchases    = await purchaseTask;
            var stockIds     = FilterStockIds(purchases, currentHoldings);
            var stockTask    = _stockService.GetStocksById(userId, stockIds);
            var stocks       = await stockTask;

            var tickers         = stocks.Select(x => x.Ticker);
            var stockQuotesTask = _marketDataService.GetLastStockQuote(tickers);
            var stockQuotes     = await stockQuotesTask;


            var stockReturnModel = BuildStockReturnModel(stocks.ToDictionary(x => x.StockId),
                                                         purchases.ToDictionary(x => x.PurchaseId),
                                                         stockQuotes.ToDictionary(x => x.Symbol),
                                                         currentHoldings);

            ComputeAnnualizedReturn(stockReturnModel);

            stockReturnModel = stockReturnModel.OrderByDescending(x => x.AnnualizedReturn);

            return(stockReturnModel);
        }
Esempio n. 2
0
        public async Task <DailyIndexInvestmentOutcome> GetReturnsForDailyInvestment(ulong userId, IEnumerable <string> indexTickers)
        {
            var outcome                   = new DailyIndexInvestmentOutcome();
            var tickerValueMap            = new Dictionary <string, decimal>();
            var ticketReturnPercentageMap = new Dictionary <string, decimal>();
            var purchaseTask              = _stockPurchaseService.GetPurchasesForUser(userId);
            var holdingTask               = _stockHoldingService.GetAllHoldingsForUser(userId);
            var purchases                 = await purchaseTask;
            var holdings                  = await holdingTask;
            var totalCapitalSpent         = holdings.Sum(x => x.HoldingDetails.Sum(y => y.Price * y.Quantity));

            if (purchases.Count() > 0)
            {
                var currentIndexPricesTask = _marketDataService.GetLastStockQuote(indexTickers);
                var firstPurchaseDate      = purchases.OrderBy(x => x.Date).First();
                var dates            = GetDatesForAddingInvestment(firstPurchaseDate.Date);
                var perDayInvestment = totalCapitalSpent / dates.Count();
                var prices           = await _stockIndexValueService.GetPricesForGivenIndexTickersAndDates(userId, indexTickers, dates);

                var tickerUnits        = CalculateHypotheticalPurchaseQuantity(perDayInvestment, indexTickers, dates, prices);
                var currentIndexPrices = await currentIndexPricesTask;

                foreach (var indexPrice in currentIndexPrices)
                {
                    tickerValueMap[indexPrice.Symbol]            = Math.Round(indexPrice.Price * tickerUnits[indexPrice.Symbol], 2);
                    ticketReturnPercentageMap[indexPrice.Symbol] = Math.Round(((tickerValueMap[indexPrice.Symbol] - totalCapitalSpent) / totalCapitalSpent) * 100, 2);
                }

                outcome.HypotheticalCurrentValues    = tickerValueMap;
                outcome.InvestmentPerDay             = perDayInvestment;
                outcome.TotalInvestment              = totalCapitalSpent;
                outcome.TotalNumberOfDays            = dates.Count();
                outcome.HypotheticalReturnPercentage = ticketReturnPercentageMap;
            }

            return(outcome);
        }
        public async Task <IEnumerable <StockComparisonToIndex> > GetComparisonWithIndex(ulong userId,
                                                                                         IEnumerable <string> indexTickers,
                                                                                         DateTime from = default(DateTime),
                                                                                         DateTime to   = default(DateTime))
        {
            var stockIndexComparisons = new List <StockComparisonToIndex>();
            var holdings = await _stockHoldingService.GetAllHoldingsForUser(userId);

            var stockIds            = GetStockIdsFromHolding(holdings);
            var stockTask           = _stockService.GetStocksById(userId, stockIds);
            var purchaseIds         = GetPurchaseIdsFromHolding(holdings);
            var stocks              = await stockTask;
            var purchaseTask        = GetPurchases(userId, purchaseIds, from, to);
            var purchases           = await purchaseTask;
            var stockIdsInPurchases = purchases.Select(x => x.StockId).Distinct();
            var tickers             = GetTickerFromStockInformation(stocks.Where(x => stockIdsInPurchases.Contains(x.StockId))).ToList();

            tickers.AddRange(indexTickers);
            var stockQuoteTask   = _marketDataService.GetLastStockQuote(tickers);
            var stockIdTickerMap = MapStockIdToTicker(stocks);
            var purchaseDates    = GetPurchaseDates(purchases);
            var indexValues      = await _stockIndexValueService.GetPricesForGivenIndexTickersAndDates(userId, indexTickers, purchaseDates);

            var dateIndexValueMap   = MapIndexValuesToDate(indexValues);
            var stockQuotes         = await stockQuoteTask;
            var tickerStockQuoteMap = stockQuotes.ToDictionary(x => x.Symbol);


            foreach (var purchase in purchases)
            {
                var ticker = stockIdTickerMap[purchase.StockId];
                if (!tickerStockQuoteMap.ContainsKey(ticker))
                {
                    continue;
                }
                var stockPriceToday      = tickerStockQuoteMap[ticker].Price;
                var stockIndexComparison = new StockComparisonToIndex();
                stockIndexComparison.Ticker                     = ticker;
                stockIndexComparison.CurrentPrice               = stockPriceToday;
                stockIndexComparison.PurchaseDate               = purchase.Date;
                stockIndexComparison.PurchasePrice              = purchase.Price;
                stockIndexComparison.Quantity                   = purchase.Quantity;
                stockIndexComparison.TotalPriceDifference       = Decimal.Round((stockPriceToday - purchase.Price) * purchase.Quantity, 4);
                stockIndexComparison.PriceDifferencePerQuantity = stockPriceToday - purchase.Price;
                stockIndexComparison.TotalPurchasePrice         = purchase.Price * purchase.Quantity;
                stockIndexComparison.TotalCurrentPrice          = stockPriceToday * purchase.Quantity;
                stockIndexComparison.PercentageChange           = Decimal.Round((stockIndexComparison.TotalPriceDifference / stockIndexComparison.TotalPurchasePrice) * 100, 4);
                stockIndexComparison.IndexesDifference          = new List <IndexDifference>();

                foreach (var indexTicker in indexTickers)
                {
                    var indexPriceToday             = tickerStockQuoteMap[indexTicker].Price;
                    var indexPriceOnPurchaseDate    = dateIndexValueMap[purchase.Date.Date][indexTicker];
                    var stockPriceToIndexPriceRatio = stockIndexComparison.PurchasePrice / indexPriceOnPurchaseDate;
                    var indexDifference             = new IndexDifference();
                    indexDifference.CurrentPrice               = indexPriceToday;
                    indexDifference.IndexTicker                = indexTicker;
                    indexDifference.PurchaseQuantity           = stockPriceToIndexPriceRatio * purchase.Quantity;
                    indexDifference.PriceDifferencePerQuantity = Decimal.Round((indexPriceToday - indexPriceOnPurchaseDate) * stockPriceToIndexPriceRatio, 4);
                    indexDifference.TotalPriceDifference       = Decimal.Round((indexPriceToday - indexPriceOnPurchaseDate) * indexDifference.PurchaseQuantity, 4);
                    indexDifference.PriceOnPurchaseDate        = indexPriceOnPurchaseDate;
                    indexDifference.TotalPurchasePrice         = indexDifference.PriceOnPurchaseDate * indexDifference.PurchaseQuantity;
                    indexDifference.PercentageChange           = Decimal.Round((indexDifference.TotalPriceDifference / indexDifference.TotalPurchasePrice) * 100, 4);
                    indexDifference.TotalCurrentPrice          = indexDifference.CurrentPrice * indexDifference.PurchaseQuantity;
                    stockIndexComparison.IndexesDifference.Add(indexDifference);
                }

                stockIndexComparisons.Add(stockIndexComparison);
            }

            return(stockIndexComparisons);
        }