Execute the following steps to estimate the value-at-risk using Monte Carlo.
- Import the libraries:
import numpy as np
import pandas as pd
import yfinance as yf
import seaborn as sns
- Define the parameters that will be used for this exercise:
RISKY_ASSETS = ['GOOG', 'FB']
SHARES = [5, 5]
START_DATE = '2018-01-01'
END_DATE = '2018-12-31'
T = 1
N_SIMS = 10 ** 5
- Download the data from Yahoo Finance:
df = yf.download(RISKY_ASSETS, start=START_DATE,
end=END_DATE, adjusted=True)
- Calculate the daily returns:
adj_close = df['Adj Close']
returns = adj_close.pct_change().dropna()
plot_title = f'{" vs. ".join(RISKY_ASSETS)} returns: {START_DATE} -
{END_DATE}'
returns.plot(title=plot_title)
We also plot the calculated returns and calculate the Pearson's correlation of the two series:
The correlation between the two series is 0.62.
- Calculate the covariance matrix:
cov_mat = returns.cov()
- Perform the Cholesky decomposition of the covariance matrix:
chol_mat = np.linalg.cholesky(cov_mat)
- Draw the correlated random numbers from the Standard Normal distribution:
rv = np.random.normal(size=(N_SIMS, len(RISKY_ASSETS)))
correlated_rv = np.transpose(np.matmul(chol_mat, np.transpose(rv)))
- Define the metrics that will be used for simulations:
r = np.mean(returns, axis=0).values
sigma = np.std(returns, axis=0).values
S_0 = adj_close.values[-1, :]
P_0 = np.sum(SHARES * S_0)
- Calculate the terminal price of the considered stocks:
S_T = S_0 * np.exp((r - 0.5 * sigma ** 2) * T +
sigma * np.sqrt(T) * correlated_rv)
- Calculate the terminal portfolio value and the portfolio returns:
P_T = np.sum(SHARES * S_T, axis=1)
P_diff = P_T - P_0
- Calculate the VaR for the selected confidence levels:
P_diff_sorted = np.sort(P_diff)
percentiles = [0.01, 0.1, 1.]
var = np.percentile(P_diff_sorted, percentiles)
for x, y in zip(percentiles, var):
print(f'1-day VaR with {100-x}% confidence: {-y:.2f}$')
Running the preceding code results in the following output:
1-day VaR with 99.99% confidence: 8.49$
1-day VaR with 99.9% confidence: 7.23$ 1-day VaR with 99.0% confidence: 5.78$
- Present the results on a graph:
ax = sns.distplot(P_diff, kde=False)
ax.set_title('''Distribution of possible 1-day changes
in portfolio value
1-day 99% VaR''', fontsize=16)
ax.axvline(var[2], 0, 10000);
Running the code results in the following plot:
The preceding plot shows the distribution of possible 1-day ahead portfolio values. We present the value-at-risk with the vertical line.