Esempio n. 1
0
        private Dictionary <string, decimal> CalculateHypotheticalPurchaseQuantity(decimal perDayInvestment,
                                                                                   IEnumerable <string> stockTickers,
                                                                                   IEnumerable <DateTime> dates,
                                                                                   IEnumerable <StockIndexValue> stockIndexValues)
        {
            var dateTickerPriceMap = _stockIndexValueService.OrderIndexValuesByDateAndTicker(stockIndexValues);
            var unitCount          = new Dictionary <string, decimal>();

            foreach (var ticker in stockTickers)
            {
                unitCount[ticker] = 0.00m;
            }

            foreach (var ticker in stockTickers)
            {
                foreach (var date in dates)
                {
                    var price = GetCurrentPrice(dateTickerPriceMap, date.Date, ticker);
                    if (price == 0.00m)
                    {
                        price = GetPreviousPrice(dateTickerPriceMap, date.Date, ticker);
                    }
                    if (price == 0.00m)
                    {
                        price = GetNextPrice(dateTickerPriceMap, date.Date, ticker);
                    }
                    if (price != 0.00m)
                    {
                        unitCount[ticker] += (perDayInvestment / price);
                    }
                }
            }

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