Build a portfolio volatility web app in 168 lines of Python

Ashish Singal
Pycob
5 min readMar 10, 2023

--

When we look at an investment portfolio, a key metric to look at is its volatility. Volatility is useful as a proxy of risk, and by using some portfolio calculations, we can get metrics such as value at risk and expected shortfall.

Links: Live App | Github | Youtube | Pycob | Google Slides

<yt video>

App demo

We have a single page app with a few main sections. The first section shows the metrics associated with the portfolio. We’ve got three big numbers and four charts, representing the following —

  • Portfolio volatility: Calculated as the historical annualized volatility of the portfolio (code).
  • Portfolio value at risk: Calculated as the 97.5% VAR, which represents the “maximum” annualized loss at a certain confidence level using historical data. (code).
  • Portfolio expected shortfall: A different risk calculation that accounts more for fat tails — where the “maximum” loss is the mean of the worst 2.5% of losses (code).
  • Daily return distribution: A histogram that shows the distribution of the portfolio’s daily returns. We can see a fat left tail here. (code).
  • Portfolio cumulative return: The cumulative return of the portfolio since 2018. (code).
  • Returns vs volatility: A scatterplot of the individual components in the portfolio comparing their returns to their volatility (code).
  • Correlation matrix: Shows the correlations of the individual components fof the portfolio. AAPL and AMZN have the lowest correlation. A more diversified portfolio would look a lot more dark blue (code).

After showing these metrics and charts, we show the user the portfolio and allow them to modify it. The user can choose a new ticker and a new weight to add. Everything will recalculate to reflect the new portfolio.

Code

Let’s dive into the important parts of the code.

First, we initialize the portfolio. To use this in your organization, you would most likely link this up to your database or API that contains your portfolio positions. In our example, we’ll take an equally weighted basket of five tech stocks.

initial_tickers_and_weights = {
"AAPL": 0.2,
"MSFT": 0.2,
"AMZN": 0.2,
"GOOG": 0.2,
"FB": 0.2,
}

Next, let’s look at how we get the data for this. We are using Pycob’s built in secrets manager to store our Snowflake credentials. We have a commercial dataset that we are using for this demo with historical equity prices — the Snowflake query is below.

def get_data(app: cob.App, tickers: list) -> pd.DataFrame:
"""Get the data for the tickers"""
# Get the data
conn = snowflake.connector.connect(
user=app.retrieve_secret("SNOWFLAKE_USER"),
password=app.retrieve_secret("SNOWFLAKE_PASSWORD"),
account=app.retrieve_secret("SNOWFLAKE_ACCOUNT"),
)
cs = conn.cursor()

# Load data for tickers
cur = cs.execute(f"""
SELECT "ticker", "date", "closeadj"
FROM QUANDL.TYPED.SEP
WHERE "ticker" in ({', '.join([f"'{ticker}'" for ticker in tickers])})
ORDER BY "date"
""")

data = cur.fetch_pandas_all()

return data

There are many quantitative financial calculations in the code. We won’t go through all of them to keep this short, but let’s dive into a couple. For example, below, we calculate the portfolio volatility by taking the standard deviation of daily portfolio returns and multiplying that by the square root of the number of trading days in a year (252).

# Get the data
data = get_data(server_request.app, tickers_and_weights.keys())
data = compute_daily_returns(data)
portfolio_return = compute_portfolio_returns(data, tickers_and_weights)


# Calculate the portfolio volatility
portfolio_volatility = portfolio_return.std() * 252 ** 0.5


# Compute the portfolio cumulative return
portfolio_cumulative_return = (1+portfolio_return).cumprod()-1


# Compute portfolio Value at Risk
tail_cutoff = data.groupby("date")["weighted_return"].sum().quantile(0.025)
portfolio_var = tail_cutoff * 252 ** 0.5


# Compute portfolio Expected Shortfall
portfolio_es = portfolio_return[portfolio_return < tail_cutoff].mean() * 252 ** 0.5

Once we do the calculations and build the charts, we need to render them using Pycob. Let’s take a peak into how we do this. We use Pycob’s built in components such as add_container, add_card, and add_header for the large numbers at the top. For the charts, we use add_plotlyfigure. These functions enable us to render the HTML, CSS, and JS for the website in 100% easy to read Python. This is the magic of Pycob.

with page.add_container(grid_columns=3) as risk_stats:
with risk_stats.add_card() as card:
card.add_header(f"{portfolio_volatility:.2%}")
card.add_text("Portfolio Volatility")

with risk_stats.add_card() as card:
card.add_header(f"{portfolio_var:.2%}")
card.add_text("Portfolio Value at Risk")


with risk_stats.add_card() as card:
card.add_header(f"{portfolio_es:.2%}")
card.add_text("Portfolio Expected Shortfall")


with page.add_container(grid_columns=2) as plots1:
plots1.add_plotlyfigure(fig1)
plots1.add_plotlyfigure(fig2)

with page.add_container(grid_columns=2) as plots2:
plots2.add_plotlyfigure(fig3)
plots2.add_plotlyfigure(fig4)

Finally, let’s show the portfolio and allow the user to modify it. Here, we first use add_pandastable to render the existing portfolio tickers and weights, and then render a form that’s used to add a new ticker.

    with page.add_card() as card:
card.add_header("Portfolio Tickers and Weights")
card.add_pandastable(pd.Series(tickers_and_weights).to_frame("weights").reset_index(names="tickers"))
card.add_header("Add Ticker", size=3)
card.add_text("The rest of the portfolio will be rebalanced to maintain the relative weights.")
with card.add_form() as form:
form.add_formtext("Ticker", "ticker", "AAPL")
form.add_formtext("Weight", "weight", "0.2")
form.add_formsubmit("Add Ticker")

Deployment

Now that we have the app running on our local machine, let’s deploy it to Pycob’s cloud hosting so other people in our organization can access it. Deploying is super simple and just takes one step once you have your API key. All you need to do is —

python3 -m pycob.deploy

And wait about 5 mins, and the app is live on the server and ready to go!

Using the Portfolio Volatility app at your organization

There are many modifications and enhancements you may want to make to make this suitable for your organization. This entire app is 100% free and open source, and can be run locally within your environment or hosted externally through Pycob. There may be some changes you’ll want to make —

  1. Many investment management firms have dozens or even hundreds of portfolios and subportfolios they are managing. You’ll want to hook this app to your database or API that gives current positions
  2. You’ll want to replace our Snowflake database with your pricing database / API
  3. You may want to add additional analytics using a library such as QuantLib.

--

--