public async Task <IActionResult> GetIndexValues(ulong userId)
        {
            var index = IndexTickers.GetAllowedIndexTickers();
            var date  = new List <DateTime>()
            {
                DateTime.Now.AddDays(-30).Date
            };
            await _stockIndexValueService.GetPricesForGivenIndexTickersAndDates(userId, index, date);

            return(Ok());
        }
예제 #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 <LifeTimeComparison> GetLifeTimeComparison(ulong userId,
                                                                     IDbConnection connection = null)
        {
            if (connection == null)
            {
                connection = _connectionService.GetConnection(userId);
            }

            var lifeTimeComparison         = new LifeTimeComparison();
            var indexLifeTimeComparisonMap = new Dictionary <string, IndexLifeTimeComparison>();

            using (connection)
            {
                var purchases = await _stockPurchaseService.GetPurchasesForUserWithStockData(userId, connection);

                var purchaseIdPurchaseMap = purchases.ToDictionary(x => x.PurchaseId);
                var sales = await _stockSaleService.GetSalesByPurchaseIds(userId, purchases.Select(x => x.PurchaseId));

                var purchaseAndSaleDates = new List <DateTime>();
                purchaseAndSaleDates.AddRange(purchases.Select(x => x.Date));
                purchaseAndSaleDates.AddRange(sales.Select(x => x.Date));
                var tickerPricesOnPurchaseDate = await _stockIndexValueService.GetPricesForGivenIndexTickersAndDates(userId, IndexTickers.GetAllowedIndexTickers(), purchaseAndSaleDates);

                var purchasesByIndexTickerAndDates = _stockIndexValueService.OrderIndexValuesByDateAndTicker(tickerPricesOnPurchaseDate);
                var purchaseIsSaleMap = GetPurchaseIdSaleMap(sales);

                foreach (var sale in sales)
                {
                    if (purchaseIdPurchaseMap.ContainsKey(sale.PurchaseId))
                    {
                        var correspondingPurchase = purchaseIdPurchaseMap[sale.PurchaseId];
                        var totalSale             = sale.Price * sale.Quantity;
                        lifeTimeComparison.TotalRealizedGainOrLoss += (totalSale - (correspondingPurchase.Price * sale.Quantity));
                        lifeTimeComparison.TotalSale     += (sale.Quantity * sale.Price);
                        lifeTimeComparison.TotalPurchase += (correspondingPurchase.Price * sale.Quantity);
                        var saleProportion = sale.Quantity / correspondingPurchase.Quantity;
                        foreach (var indexTicker in IndexTickers.GetAllowedIndexTickers())
                        {
                            var priceOnPurchaseDate = purchasesByIndexTickerAndDates[correspondingPurchase.Date.Date][indexTicker];
                            var purchaseQuantity    = (correspondingPurchase.Quantity * correspondingPurchase.Price) / priceOnPurchaseDate;
                            var priceOnSaleDate     = purchasesByIndexTickerAndDates[sale.Date.Date][indexTicker];
                            var saleQuantity        = saleProportion * purchaseQuantity;
                            var realizedGainOrLoss  = (priceOnSaleDate - priceOnPurchaseDate) * (saleQuantity);

                            if (!indexLifeTimeComparisonMap.ContainsKey(indexTicker))
                            {
                                var lifeTimeComparisonForIndex = new IndexLifeTimeComparison();
                                indexLifeTimeComparisonMap.Add(indexTicker, lifeTimeComparisonForIndex);
                            }
                            indexLifeTimeComparisonMap[indexTicker].TotalRealizedGainOrLoss += realizedGainOrLoss;
                            indexLifeTimeComparisonMap[indexTicker].TotalPurchaseUnits      += purchaseQuantity;
                            indexLifeTimeComparisonMap[indexTicker].TotalSaleUnits          += saleQuantity;
                        }
                        correspondingPurchase.Quantity -= sale.Quantity;
                    }
                }

                var tickers = GetDistinctTickers(purchaseIdPurchaseMap.Values).ToList();
                tickers.AddRange(IndexTickers.GetAllowedIndexTickers());
                var lastPrices = await _marketDataService.GetLastStockQuote(tickers);

                var tickerPriceMap = lastPrices.ToDictionary(x => x.Symbol);

                foreach (var purchase in purchaseIdPurchaseMap.Values)
                {
                    if (purchase.Quantity > 0 && tickerPriceMap.ContainsKey(purchase.Stock.Ticker))
                    {
                        lifeTimeComparison.TotalPaperGainOrLoss += ((tickerPriceMap[purchase.Stock.Ticker].Price * purchase.Quantity) - (purchase.Price * purchase.Quantity));
                        lifeTimeComparison.TotalPurchase        += (purchase.Price * purchase.Quantity);
                        foreach (var indexTicker in IndexTickers.GetAllowedIndexTickers())
                        {
                            var indexPurchaseUnits = (purchase.Price * purchase.Quantity) / purchasesByIndexTickerAndDates[purchase.Date.Date][indexTicker];
                            if (!indexLifeTimeComparisonMap.ContainsKey(indexTicker))
                            {
                                var indexLifeTimeComparison = new IndexLifeTimeComparison();
                                indexLifeTimeComparisonMap.Add(indexTicker, indexLifeTimeComparison);
                            }
                            indexLifeTimeComparisonMap[indexTicker].TotalPurchaseUnits   += indexPurchaseUnits;
                            indexLifeTimeComparisonMap[indexTicker].TotalPaperGainOrLoss += ((tickerPriceMap[indexTicker].Price * indexPurchaseUnits) - (purchase.Price * purchase.Quantity));
                        }
                    }
                }
            }

            lifeTimeComparison.IndexLifeTimeComparisonMap = indexLifeTimeComparisonMap;
            foreach (var indexComparison in lifeTimeComparison.IndexLifeTimeComparisonMap.Values)
            {
                indexComparison.TotalGainOrLoss       = indexComparison.TotalPaperGainOrLoss + indexComparison.TotalRealizedGainOrLoss;
                indexComparison.TotalReturnPercentage = (indexComparison.TotalGainOrLoss / lifeTimeComparison.TotalPurchase) * 100;
            }

            lifeTimeComparison.TotalGainOrLoss       = lifeTimeComparison.TotalPaperGainOrLoss + lifeTimeComparison.TotalRealizedGainOrLoss;
            lifeTimeComparison.TotalReturnPercentage = (lifeTimeComparison.TotalGainOrLoss / lifeTimeComparison.TotalPurchase) * 100;

            return(lifeTimeComparison);
        }
        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);
        }