Example #1
0
        // Gets the prices for all of the securities in a portfolio from IEX Cloud
        private async Task <ICollection <PortfolioSecurity> > GetPrices(PortfolioDetailsViewModel viewModel)
        {
            string token      = GetToken();
            var    client     = _clientFactory.CreateClient();
            var    timePeriod = viewModel.TimePeriod;

            foreach (PortfolioSecurity ps in viewModel.Portfolio.PortfolioSecurities)
            {
                var request = new HttpRequestMessage(HttpMethod.Get,
                                                     $"https://cloud.iexapis.com/stable/stock/{ps.Security.Ticker}/chart/{timePeriod}/?chartCloseOnly=true&chartInterval=21&token={token}");
                var response = await client.SendAsync(request);

                if (response.IsSuccessStatusCode)
                {
                    // Convert the response into price objects and save as a list to the PS's List<Price>
                    var json = await response.Content.ReadAsStreamAsync();

                    List <IEXPrice> IEXPrices = await System.Text.Json.JsonSerializer.DeserializeAsync <List <IEXPrice> >(json);

                    foreach (IEXPrice p in IEXPrices)
                    {
                        ps.Prices.Add(new Price
                        {
                            Date     = p.Date,
                            AdjClose = p.Close
                        });
                    }
                }
            }

            return(viewModel.Portfolio.PortfolioSecurities);
        }
Example #2
0
        // GET: Portfolios/Details/5
        public async Task <IActionResult> Details(int?id, string timePeriod)
        {
            var viewModel = new PortfolioDetailsViewModel();

            viewModel.TimePeriod = timePeriod;

            if (id == null)
            {
                return(NotFound());
            }

            viewModel.Portfolio = await _context.Portfolios
                                  .Include(p => p.User)
                                  .Include(p => p.PortfolioSecurities)
                                  .ThenInclude(p => p.Security)
                                  .Include(p => p.PortfolioSecurities)
                                  .ThenInclude(p => p.AssetClass)
                                  .FirstOrDefaultAsync(p => p.Id == id);

            // Asset Allocation data for pie chart
            Dictionary <string, int> assetAllocation = new Dictionary <string, int>();

            foreach (PortfolioSecurity ps in viewModel.Portfolio.PortfolioSecurities)
            {
                if (!assetAllocation.ContainsKey(ps.AssetClass.Name))
                {
                    assetAllocation[ps.AssetClass.Name] = 0;
                }

                assetAllocation[ps.AssetClass.Name] += ps.Weight;
            }
            // Convert dictionary to json and assign to viewModel
            viewModel.AssetAllocationKeys   = JsonConvert.SerializeObject(assetAllocation.Keys);
            viewModel.AssetAllocationValues = JsonConvert.SerializeObject(assetAllocation.Values);

            // Get the prices for all the securities in the portfolio
            if (timePeriod != null)
            {
                viewModel.Portfolio.PortfolioSecurities = await GetPrices(viewModel);

                List <DateTime> dates = viewModel.Portfolio.PortfolioSecurities.FirstOrDefault().Prices
                                        .Select(p => p.Date).ToList();

                // Iterate over all the dates returned for prices and make entries in Dictionaries
                foreach (DateTime date in dates)
                {
                    viewModel.PortfolioValues[date]   = 100_000;
                    viewModel.MonthlyReturns[date]    = 0;
                    viewModel.CumulativeReturns[date] = 0;
                }

                // Iterate over all the PortfolioSecurities, calculate the weighted monthly return and cumulative return for each security and add it to the dictionary
                decimal monthlyReturn    = 0;
                decimal cumulativeReturn = 0;
                foreach (PortfolioSecurity ps in viewModel.Portfolio.PortfolioSecurities)
                {
                    for (int i = 0; i < ps.Prices.Count(); i++)
                    {
                        if (i != 0)
                        {
                            monthlyReturn = (ps.Prices[i].AdjClose / ps.Prices[i - 1].AdjClose) - 1;
                            viewModel.MonthlyReturns[ps.Prices[i].Date] += monthlyReturn * ps.Weight / 100;

                            cumulativeReturn = (ps.Prices[i].AdjClose / ps.Prices[0].AdjClose) - 1;
                            viewModel.CumulativeReturns[ps.Prices[i].Date] += cumulativeReturn * ps.Weight / 100;
                        }
                    }
                }

                // Iterate over the viewModel's CumulativeReturns dictionary and update the PortfolioValues dictionary with the appropriate value
                //DateTime firstDate = viewModel.PortfolioValues.Keys.First();
                //viewModel.PortfolioValues[firstDate] = 100_000;

                foreach (KeyValuePair <DateTime, decimal> kvp in viewModel.CumulativeReturns)
                {
                    viewModel.PortfolioValues[kvp.Key] = 100_000 * (1 + kvp.Value);
                }

                decimal begValue = viewModel.PortfolioValues.First().Value;
                decimal endValue = viewModel.PortfolioValues.Last().Value;
                viewModel.Return = ((endValue / begValue) - 1) * 100;

                decimal numYears = dates.Count() / 12;

                viewModel.CAGR = (decimal)(Math.Pow((double)(endValue / begValue), (double)(1 / numYears))) - 1;
                viewModel.CAGR = viewModel.CAGR * 100;
                // Calculate the StdDeviation
                List <decimal> monthlyReturns = viewModel.MonthlyReturns.Values.ToList();
                // Remove the first value since the 1st period has no return
                monthlyReturns.Remove(monthlyReturns[0]);
                decimal monthlyStdDev = StdDev(monthlyReturns);
                // Get estimated annualized StdDev
                viewModel.StdDeviation = monthlyStdDev * (decimal)Math.Sqrt(12);
                viewModel.StdDeviation = viewModel.StdDeviation * 100;

                // Set dates
                viewModel.StartDate = viewModel.PortfolioValues.First().Key;
                viewModel.EndDate   = viewModel.PortfolioValues.Last().Key;

                // Convert portfolio values to JSON and set in the viewModel
                viewModel.ChartData = JsonConvert.SerializeObject(viewModel.PortfolioValues);


                return(View(viewModel));
            }

            if (viewModel.Portfolio == null)
            {
                return(NotFound());
            }

            return(View(viewModel));
        }