Intro to Risk Measures in Finance

Isai Guizar


This document is intended for educational purposes as part of my Risk Financial Management course at Tec de Monterrey. For any questions or suggestions, feel free to contact me at iguizar@tec.mx.


1 Intro

Risk measurement is a fundamental aspect of financial risk management. Two widely used measures are Value at Risk (VaR) and Expected Shortfall (ES). These measures help to quantify potential losses and inform risk management decisions. I introduce the two measures in this document.

2 Value at Risk (VaR)

Value at Risk (VaR) estimates the potential loss in value of an asset or a portfolio over a given time period for a specified confidence level. It answers the question:

What is the worst expected loss over a given time horizon at a specific confidence level?, in other words: What loss level is such that we are \(X\%\) confident it will not be exceeded in \(T\) business days?

VaR is a sigle number that can be derived from the probability distribution of returns (gains and losses) during time \(T\), by definition, however, it focuses on potential losses rather than gains.

Under Basel II, capital for credit risk and operational risk is based on a one-year 99.9% VaR. The capital required for market risk, comes from multiples of a 10-day horizon at a 99% level of confidence.

Under the simplified assumption that returns are normally distributed with mean \(\mu \ge0\), and standard deviation \(\sigma\), the VaR at \(X\%\) level of confidence is:

\[ VaR(X\%) = N^{-1}(1-X\%) \]

where \(N(\cdot)\) is the normal distribution with mean \(\mu\) and standard deviation \(\sigma\).

What is the same:

\[ VaR(X\%)= \mu + \sigma \cdot \Phi^{-1}(1-X\%) \] where \(\Phi(\cdot)\) is the standard normal standard distribution.


Example

Let’s assume a portfolio consisting of a single asset, the historical data of daily log returns have a mean of 2% and a standard deviation of 10%. Compute the 1-day 99% VaR.


Import the libraries

import numpy  as np
import pandas as pd
import scipy.stats as st
import matplotlib.pyplot as plt

Visualize the distribution

mu = 0.02
sd = 0.10

# Generate synthetic daily returns to visualize the distribution
np.random.seed(123)
daily_returns = np.random.normal(loc = mu, scale = sd, size=5*252)  # 252 trading days

# To plot the distribution
x_alt = np.linspace(min(daily_returns), max(daily_returns), 100)
pdf_alt = (1/(sd * np.sqrt(2 * np.pi))) * np.exp(-0.5 * ((x_alt - mu)/sd)**2)


plt.figure(figsize=(7, 5))
plt.hist(daily_returns, bins='auto', color = 'lightblue', alpha=0.75, density=True)
plt.plot(x_alt, pdf_alt, color='red', linewidth=2, label='distribution')
plt.legend()

plt.title("Daily log Returns of the Portfolio")
plt.xlabel("Returns")
plt.ylabel("Frequency")

plt.show()

Calculate the VaR

X = 0.99   # Confidence level

VaR1 = st.norm.ppf(1-X,loc=mu, scale=sd)
VaR2 = mu + sd*st.norm.ppf(1 - X)

print(f"1-day 99% VaR: {-(np.exp(VaR1)-1):.2%}")
print(f"1-day 99% VaR: {-(np.exp(VaR1)-1):.2%}")
1-day 99% VaR: 19.15%
1-day 99% VaR: 19.15%

Interpretation: We are 99% confident that the asset will not lose more than 19.15% over one day.


Caution

Please refer to the section A brief note on returns to clarify why a simple rate of return, \(R_t\), is calculated as: \(exp^{r_t}-1\), when \(r_t\) is the log return.


Plot the VaR

plt.figure(figsize=(7, 5))

plt.hist(daily_returns, bins='auto', color = 'lightblue', alpha=0.75, density=True)
plt.plot(x_alt, pdf_alt, color='red', linewidth=2, label='distribution')
plt.axvline(VaR1, color='red', linestyle='dashed', label='VaR 99%')
plt.legend()

plt.title("Daily log Returns of the Portfolio + VaR")
plt.xlabel("Returns")
plt.ylabel("Frequency")

plt.show()

3 Expected Shortfall

Basel II faced criticism for underestimating tail risks and failing to account for extreme market conditions, as seen during the 2008 financial crisis. To address these issues, Basel III introduced several enhancements, including Expected Shortfall. The Expected Shortfall (ES), also known as conditional VaR or tail loss, measures the expected loss in the worst-case scenario beyond the VaR threshold. It provides a more comprehensive risk measure than VaR by accounting for tail risks.

Expected shortfall answers the question: If things do get bad, what is the expected loss?

It indicates the expected loss during time \(T\) conditional on the loss being greater than the \(Xth\) percentile of the loss distribution.

While VaR is the loss level that will not be exceeded with a specified probability, the Expected shortfall is the expected loss given that the loss is greater than the VaR level.

Under the simplified assumption that returns are normally distributed with mean \(\mu \ge0\), and standard deviation \(\sigma\), the ES at \(X\%\) level of confidence is:

\[ ES(X\%) = \mu - \sigma \cdot \frac{\phi \Big(\Phi^{-1}(1-X\%)\Big)}{1-X\%} \]


Example

Let’s assume a portfolio consisting of a single asset, the historical data of daily log returns have a mean of 2% and a standard deviation of 10%. We’ll compute the 1-day 99% expected shortfall.


Expected Shortfall Calculation

z  = st.norm.ppf(1-X)
ES1 = mu - sd * st.norm.pdf(z) / (1-X)  

print(f"The Expected Shortfall (ES) is: {-(np.exp(ES1)-1):.2%}")
The Expected Shortfall (ES) is: 21.85%

Interpretation: If the VaR (19.15%) is exceed over one day, the average loss would be of 21.85%.

plt.figure(figsize=(7, 5))

plt.hist(daily_returns, bins='auto', color = 'lightblue', alpha=0.75, density=True)
plt.plot(x_alt, pdf_alt, color='red', linewidth=2, label='distribution')
plt.axvline(VaR1, color='red',    linestyle='dashed', label='VaR 99%')
plt.axvline(ES1, color='orange', linestyle='dashed', label='ES 99%')
plt.legend()

plt.title("Daily log Returns of the Portfolio, VaR & ES")
plt.xlabel("Returns")
plt.ylabel("Frequency")

plt.show()

Note: We could also use the fact that we have simulated the historic returns to approximate the ES as the mean beyond the VaR as follows:

ES2 = daily_returns[daily_returns <= VaR1].mean()

print(f"The Expected Shortfall (ES) is: {-(np.exp(ES2)-1):.2%}")
The Expected Shortfall (ES) is: 21.97%


4 Application

We will fetch data for the SP500 from the Federal Reserve Economic Data (FRED) to analyze the risk of the index using Python. The index includes 500 leading companies in leading industries of the U.S. economy.


Install the library pandas-datareader that will help us get access to data from the Federal Reserve (FRED). You only have to do it once.

!pip install pandas-datareader

Import the library

import pandas_datareader.data as web

Obtain and clean data

# Fetch the data
symbol = 'SP500'
start_date = '2021-01-01'
end_date   = '2025-01-01'

SP = web.DataReader(symbol, 'fred', start=start_date, end=end_date)
SP = SP.dropna()

# Convert index to datetime and rename columns
SP.index = pd.to_datetime(SP.index)
SP.rename(columns={symbol: 'Price'}, inplace=True)
SP.head(10) # show the first 10 rows
Price
DATE
2021-01-04 3700.65
2021-01-05 3726.86
2021-01-06 3748.14
2021-01-07 3803.79
2021-01-08 3824.68
2021-01-11 3799.61
2021-01-12 3801.19
2021-01-13 3809.84
2021-01-14 3795.54
2021-01-15 3768.25

Plot the time series

plt.figure(figsize=(7,5))

plt.plot(SP.index, SP['Price'], color = 'steelblue', label='SP500 Index')

plt.xlabel("Date")
plt.ylabel("Index Value")
plt.title("SP500 Market Index")
plt.legend()

plt.show()

Calculate and plot daily log returns

SP['Return'] = np.log(SP['Price']).diff()
SP.dropna(inplace=True)

# Plot daily returns
plt.figure(figsize=(7,5))

plt.plot(SP.index, SP['Return'], color = 'steelblue', label="Log Returns")
plt.xlabel("Date")
plt.ylabel("Daily log Return")
plt.title("Daily Log Returns of the SP500 Market Index")
plt.legend()
plt.show()

Compute the mean (\(\mu\)) and standard deviation (\(\sigma\))

mu = SP['Return'].mean()
sd = SP['Return'].std()

print(f"The mean of the daily log returns is: {mu:.4%}")
print(f"The standard deviation of the daily log returns is: {sd:.4%}")
The mean of the daily log returns is: 0.0461%
The standard deviation of the daily log returns is: 1.0396%

Calculate the Value-at-risk at a 95% confidence level

X = 0.95   # Confidence level
VaR = mu + sd*st.norm.ppf(1 - X)

print(f"1-day 95% VaR: {-(np.exp(VaR)-1):.2%}")
1-day 95% VaR: 1.65%

Calculate the Expected Shortfall

z  = st.norm.ppf(1-X)
ES = mu - sd * st.norm.pdf(z) / (1-X)  

print(f"The Expected Shortfall (ES) is: {-(np.exp(ES)-1):.2%}")
The Expected Shortfall (ES) is: 2.08%


If USD 1.45mill were invested in this asset, the monetary VaR and ES, would be estimated as:

K = 1.45
VaR_Mon = K*(np.exp(VaR)-1)
ES_Mon  = K*(np.exp(ES) - 1)
print(f"Daily 95% VaR: ${-1000000*VaR_Mon:,.2f}")
print(f"Daily 95% Expected Shortfall: ${-1000000*ES_Mon:,.2f} ")
Daily 95% VaR: $23,925.32
Daily 95% Expected Shortfall: $30,106.65 




A brief note on returns

Let \(P_t\) denote the price of an asset in time \(t\). The simple or discrete net rate of return on an investment in this asset, between date \(t-1\) and \(t\), is defined as:

\[\begin{equation*} R_t = \frac{P_t-P_{t-1}}{P_{t-1}} = \frac{P_t}{P_{t-1}}-1 \end{equation*}\]

The gross rate of return is: \[\begin{equation*} R_t +1 = \frac{P_t-P_{t-1}}{P_{t-1}}+1 = \frac{P_t}{P_{t-1}} \end{equation*}\]

But \(R_t\) is not symmetric. It will never be less than 1 (never lose more than 100%), but could take any positive value, which motivates the use of log returns.

Recall, Taylor’s rule: \[\begin{equation*} e^x = 1 + x +\frac{x^2}{2!} + \frac{x^3}{3!}+.... \end{equation*}\]

So that, for \(x\) small: \(e^x \approx 1 + x\)

In the previous approximation, let \(x\) be the net rate of return at time \(t\), \(R_t\), so that \(e^{R_t} \approx 1 + R_t \approx 1+ \Big[\frac{P_t}{P_{t-1}}-1\Big]\)

Then,

\[\begin{equation*} R_t \approx ln\Big(\frac{P_t}{P_{t-1}} \Big) \end{equation*}\]

the rate of return, \(ln\Big(\frac{P_t}{P_{t-1}}\Big)\), is the log or continuously compounded rate of return between date \(t-1\) and \(t\), to avoid confusion called it \(r_t\)

Compounded return

From continuously compounded to simple rates of net return.

Since \(r_t\) is the log rate of return:

\[\begin{equation*} e^{r_t} = 1 + R_t \end{equation*}\]

The simple rate of return is: \[\begin{equation*} R_t = e^{r_t} - 1 \end{equation*}\]

Multi-period returns

Let \(r_t\) be the monthly log rate of return. To calculate the compounded anual rate of return, \(r(12)\):

\[\begin{equation*} r(12) = r_{12} + r_{11} + \cdots + r_1 \end{equation*}\]

More generally, \[\begin{equation*} r(n) = r_n + r_{n-1} + \cdots + r_{1} \end{equation*}\] and \[\begin{equation*} R(n) = exp(r_n + r_{n-1} + \cdots + r_{1}) -1 \end{equation*}\]