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); }
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); }