Skip to content

Get predicted returns for your chosen basket of stocks to help guide your investment decisions.

Notifications You must be signed in to change notification settings

rahulakrish/portfolio_builder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Objective

To help the average investor build a portfolio of stock and ensure maximum returns to achieve his/her goals. The aim here is to provide the investor an overview of performance of each stock belonging to the portfolio, portfolio performance and predict future peformance based on historical data thereby helping them make an informed decision.

This notebook is only serves as a demonstration and should not be miscontrued for financial advice. As with any investment, there is an element of risk and returns can never be guaranteed.

Optimal portfolio build will also be demonstrated using a principle called Modern Portfolio Theory, a model introduced by economist Harry Markowtiz in 1952. The Modern Portfolio Theory (MPT) refers to an investment theory that allows investors to assemble an asset portfolio that maximizes expected return for a given level of risk. The theory assumes that investors are risk-averse; for a given level of expected return, investors will always prefer the less risky portfolio.

PyPortfoliOpt is a Python library that will be used for this purpose.

Methodology

  1. Data of the chosen stock from 2019-till will be scraped from Yahoo Finance using python's yfinance(documentation can be found here and YahooFinancials (documentation can be found here).

  2. Conduct EDA including stock performance, risk, growth etc. .

  3. Different machine learning models will then be built to predict future stock price. Their errors will be compared and the model with the least error will be used to predict future stock performance.

  4. Based on predicted data, optimal portfolios will be built.

EDA

For demonstrative purposes, let's build a porfiolio of stock of the following companies: General Electric, J.P.Morgan, Microsoft and Procter & Gamble.

Stock Performance

Screenshot 2023-11-20 124528

Perhaps unsurpisingly, MSFT posted the highest growth.

Average Daily return

Comparing the avaerage daily return of the portfolio against the S&P 500:

Screenshot 2023-11-20 124900

WE can see that the portfolio slightly out performs the S&P 500.

Growth

Next, let's look at cumulative growth. Cumulative returns included compounded results of reinvesting interest, dividens and capital gains. This can be better understood by tracking an invesment of $1000 in each stock at the beginning and checking for the current value:

Screenshot 2023-11-20 125050

For MSFT, we can see that $1000 invested in 2019 would've grown to approx. $3600, netting a cumulative return of nearly 260%!

Portfolio Cumulative Return

Now that we've seen how the individual stocks have performed over time, similarly, let's check how a portfolio of these stocks would've performed and compare it to the S&P 500:

image

From the graph, we can see that the cumulative return of the portfolio is approx. $2500. This means an initial investment of $1000 would've grown to $2500. In terms of percentage, that equates to 150%. The S&P 500 in comparison has grown only 75%.

Dividend History

A Dividend is the distirbution's of the company's profit to it's shareholders. Not every company pays dividends. Companies can also choose to re-invest their profits for future growth than reward shareholders. For an investor, investing in a company that pays dividends is an easy way to earn extra income on top of their initial investment. Shown here is the dividend for MSFT:

image

A history of rising dividend signifies strong performance, confidence in the future and bodes well for investors.

Risk

Beta Value

Beta value of a stock is used to signify risk . By comparing the stock movement relative to the overall market such as the S&P 500, the stock can be classified as risky or not. By definition, the market has a beta value of 1.0. If the beta value of the stock is greater than 1.0, then it is classified as risky and not so if the value is less than 1.0. Shown here is the beta value of MSFT:

image

Portfolio Risk

Portfolio risk can be calculated using the covariance matrix. Portfolio variance takes into account individual variance, weights and their correlation.

The risk of a portfolio is not simply the weighted variance of the individual assets. Since the stocks are correlated, it becomes more complicated. The correlation between assets tell us how they move related to each other and therefore, the risk should also account for the correlation.

The standard deviation of a portfolio is a measure of its risk or volatility. It quantifies how much the returns of the portfolio tend to deviate from the average (mean) return over a specific time period. A higher standard deviation indicates greater volatility, and vice-versa.

image

From the plot, it is clear to see that GE (17.3%) is the most volatile stock compared to the others. Also, GE and JPM are highly co-related meaning their performances are fairly similar . Ideally, we want to look for companies whose performances are not related. This helps further reduce risk help insulate the portfolio from market fluctations.

Interpreting risk

The high standard deviation of 23.4% signifies that the portfolio has experienced significant price or return fluctuations. These fluctuations can be both positive and negative, and they can be substantial. Investors with a lower risk tolerance may find such volatility concerning.

On the flip side, despite the high-risk profile, the portfolio has generated an impressive return of 135% over the 5 year period.

Hence, the interpretation of the portfolio's risk depends upon the investor. Investors with a higher risk tolerance may be more comfortable with the portfolio's volatility if it leads to higher returns, while those with lower risk tolerance may find the risk level less acceptable.

Modern Portfolio Theory

The modern portfolio theory (MPT) is a practical method for selecting investments in order to maximize their overall returns within an acceptable level of risk. This mathematical framework is used to build a portfolio of investments that maximize the amount of expected return for the collective given level of risk.

American economist Harry Markowitz pioneered this theory in his paper "Portfolio Selection," which was published in the Journal of Finance in 1952. He was later awarded a Nobel Prize for his work on modern portfolio theory.

A key component of the MPT theory is diversification. Most investments are either high risk and high return or low risk and low return. Markowitz argued that investors could achieve their best results by choosing an optimal mix of the two based on an assessment of their individual tolerance to risk.

Source: Modern Portfolio Theory

PyPortfolioOpt

PyPortfolioOpt is a library that implements portfolio optimization methods, including classical mean-variance optimization techniques and Black-Litterman allocation, as well as more recent developments in the field like shrinkage and Hierarchical Risk Parity.

More information can be found here and here

We will be using PyPortfolioOpt to optimize our portfolio.

Efficient Frontier

is a graphical representation of portfolio risk(standard deviation) vs return.

  • At every level of return, investors can create a portfolio that offers the lowest possible risk.

  • For every level of risk, investors can create a portfolio that offers the highest return.

  • Any portfolio that falls outside the Efficient Frontier is considered sub-optimal for one of two reasons: it carries too much risk relative to its return, or too little return relative to its risk.

PyPfOpt has different constraints for portfolio build but for now, let's look at two options : a portfolio for maximum Sharpe value and one that minimizes volatility.

Efficient Frontier for Max Sharpe

The Sharpe Ratio is a measure of risk-adjusted performance for an investment or a portfolio. Simply put, the Sharpe Ratio calculates the excess return per unit of risk. A higher Sharpe Ratio indicates a better risk-adjusted performance. Investors generally prefer investments or portfolios with higher Sharpe Ratios because they provide a better return for the amount of risk taken.

image

Efficient Frontier for Min Volatility

image

We can see how the two approaches produce different results.

How much to invest and how to divvy it all up?

Based on the weights, latest price and amount invested, the next step is to ensure that the amount invested is maximized for each asset's allocated weight.

For eg. if the stock price of GE is $100 and the total amount invested is $1000, per the allocation, we have to invest 4.8% in GE which equates to $48.

We can use the DiscreteAllocation class for this. It prioritzies buying shares of the asset that is furthest away from the allocation i.e if the portfolio calls for bying 10 shares of an asset, but with the allocation we have only 6 shares, the other asset allocations are sacrificed to reduce the gap. This way, the left over money is minimized.

We will be using $1800 as an example and like earlier compare portfolios for max sharpe and min volatility.

Max Sharpe:

image

Min Volatility

image

Future price prediction - Time Series Modeling

Now that we have some insight on each stock and how to optimally build a portfolio, the next step is to predict future performance of the stocks that belong to the portfolio.

To make predictions, we will build a series of time-series models and select the model with the least RMSE.

We will be using 'AAPL' data for demonstrative purposes.

Stationarity Check

Time series models are usually built on the premise that models are stationary i.e there are patters to the data and by analyzing these patterns, future performance can be predicted with a degree of certainity. However, this rarely happens in real life. There is always some trend or seasonality or a combination of both in the data.Hence the first step is to check for stationarity and then convert non-stationary to stationary data.

By simply taking the difference, we can remove non-stationarity from the data set. We can see from the above plot that the mean though not perfectly flat is fairly linear signifying that we have removed the trend. Since the p-value from the Dickey-Fuller is lesser than the significance value, we can reject the null-hypothesis and thus conclude that the data is now stationary.

image

Model predictions

Next step is to build different models to predict future price and select the model with the least RMSE

image

From the plot, we can see that the FB Prophet model clearly outshines the rest with a RMSE score of $5.12 . Hence, we will use that for making predictions for stocks in our portfolio.

Predicting, the price of AAPL for the next year:

image

Building Portfolio

Shown here is the predicted price of another stock in the portfolio: Procter & Gamble (PG)

image

Predictions of portfolio

Next step is to predict portfolio performance:

image

Applying Modern Portfolio Theory

We now need to calculate the efficient frontier for max_sharpe and min_volatilty based on our predictions.

Max Sharpe

image

From the above, we can see that the , based on forecast returns, if we look to maximize the sharpe ratio, we can expect an annual return of 28%.

Using the same intial amount of $1800, the recommended allocation would have no investment in J.P.Morgan and the left over amount would be $38.73

Min Volatility

image

For minimun volatility, we can see the difference in allocation when compared to the portfolio optimized for max_sharpe.

By playing around with different stocks, investment amount and model constraints, we can generate different portfolios and choose that best fits our outlook.

Conclusions

  1. All the models are purely mathematical models and cannot take into account black swan events.
  2. Obviously, the strength of the forecast is goverened by the model. Shown here is only a basic model with only historical stock price used to predict future price. More features and more sophisticated models can developed to make more realistic and accurate predictions.
  3. Similarly, the PyPfopt library optimization was done only for maximum sharpe and minimum volatility. There are more options that the user can play with to generate more portfolios.

Appendix

How to use the notebook:

  1. Assign stocks into the following line: portfolio,portfolio_df = stocks('GE,JPM,MSFT,PG'). In place of 'GE,JPM,MSFT,PG', put in stocks of your choice.

  2. Run the following functions to get historical portfolio data:

  • stock_performace(portfolio) - plot performace of each stock in the portfolio from 2019 till date.
  • get_average_returns(portfolio) - plot average return of the portfolio in comparision to the S&P 500.
  • get_ind_cum_return(portfolio) - plot hypothetical growth of $1000 invested in each stock.
  • get_portfolio_cumulative_return(portfolio) - plot hypothetical growth of $1000 invested in the portfolio.
  • get_dividend(portfolio) - plot dividend data for each stock in the portfolio
  • calculate_beta(portfolio) - plot each stock in the portfolio
  • covariance(portfolio) - plot portfolio risk
  • hist_returns(portfolio) - plot trends in the returns of the portfolio
  • sharpe_df,sharpe_weights = ef_max_sharpe(portfolio_df) - efficient frontier optimizing for max sharpe value. sharpe_df will output portfolio performace and sharpe_weights will list out optimal allocation of $1800 in the portfolio and also the leftover money.
  • vol_df,min_vol_weights = ef_min_volatility(portfolio_df) - efficient frontier optimizing for min volatility.vol_df will output portfolio performance and min_vol_weights will list out optimal allocation.

The functions listed above only plot data based on historical performance and merely serve as a guide. The following functions are to predict future performance:

  • Assign forecast_portfolio = plot_forecast_price(portfolio) and run. This will plot future stock price for each stock in the portfolio based on historical stock price
  • returns_forecast(forecast_portfolio) - plot future portfolio performance
  • forecast_sharpe(forecast_portfolio) - output portfolio performance and allocation optimized for max sharpe value

forecast_volatility(forecast_portfolio) - output portfolio performance and allocation optimized for min volatility.

About

Get predicted returns for your chosen basket of stocks to help guide your investment decisions.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published