Introduction to Risk Management

Introduction to Risk Management

“Only those who risk going too far can possibly find out how far they can go.” - T.S. Eliot

The entirety of risk analysis is a very extensive space. This introduction to risk management is going to focus solely on applied business risk modeling and analysis. Some examples of this would include market risk (the risk of having unknown future prices in a market), operational risk (the risk of having unknown effects impact a company’s operation like employee turnover), credit risk (the risk of having people default on loans - for more information on modeling credit risk directly check out the code notes: Credit Modeling), and liquidity risk (the risk of not being able to liquefy assets when capital is needed).

Risk is typically tied with uncertainty. Risk and uncertainty are related, however, they are different than each other. Risk is something that someone bears. Risk is a possible outcome of uncertainty. Once you have an uncertain event and you can put some distribution to it, you can measure possible risks associated with that event. Just because there is uncertainty doesn’t mean there is risk. Take the flip of a coin. The outcome of this flip of a coin is uncertain. It could be heads or tails. However, there is no risk involved in this uncertainty. Now imagine that the outcome of the flip of that coin is you getting $5 for heads and losing $5 for tails. Now there is risk to the uncertainty of the coin flip because you stand to lose something based on one of the possible outcomes.

There are three levels of uncertainty that we typically think of:

  1. Known - a guaranteed event or no uncertainty. For example, I enter in a contract where I will buy 10 bushels of corn 1 year from now.

  2. Unknown - events that carry risk that will be reduced / eliminated over time as the event gets closer. For example, I do not know the price of corn 1 year from now so our contract could be bad for me in terms of price, but as I get closer to 1 year from now I know more about my risk.

  3. Unknowable - events that carry risk that may not change over time as the event gets closer. For example, a natural disaster could prevent us from exercising the contract. The risk didn’t change up to the event because the disaster might not have been known to happen. Insurance can protect us against this kind of risk!

Let’s load up all of the needed libraries in R that we will be using in these course notes. This isn’t needed for the SAS sections of the code.

install.packages("quantmod")
install.packages("ks")
install.packages("TTR")
install.packages("scales")
install.packages("fExtremes")
install.packages("triangle")

library(graphics)
library(quantmod)
library(TTR)
library(ks)
library(scales)
library(fExtremes)
library(triangle)

Primer on Risk

Let’s go through a basic example of evaluating risk. Here we have three potential projects to invest in - A, B, or C. The cost of these projects, the expected net return of these projects (profit after subtracting initial costs), and the risk of these projects is defined in the table below:

Risk Adjusted Return on Capital Example

If we evaluate the project based solely on the expected net return we might choose project B. However, project B carries more risk. To combine the information on return and risk we have the Risk Adjusted Return on Capital (RAROC) calculation which is simply the ratio of return to risk. Here we can see that project C is the most return for the risk that we are taking. In fact, investors are not getting paid based on RAROC instead of just return in the investment world. This is because of the incentive problem. Investors were willing to take high risks with other people’s money to make high incomes. They were relying on the government to bail them out if they made a mistake. Now, they are getting paid based on smart investments in terms of both return as well as risk.

However, when evaluating possible scenarios of outcomes, this method of RAROC still falls short. It helps make sound decisions when only considering point estimates of return and risk, but what if that expected return is variable? For example, I want to get in the market of selling widgets. I think I can sell 1500 widgets (quantity, Q) at $10.00 per widget (price, P). It will cost me $7.00 to make each widget (variable cost, VC) and $2,500 to buy the widget making machine (initial / fixed costs, FC). From a basic revenue calculation we can see the net revenue (NR) this enterprise has:

\[ NR = Q \times (P - VC) - FC \]

\[ NR = 1500 \times (10-7) - 2500 \]

\[ NR = \$2,000 \] Again, this assumes that these inputs are all fixed and known ahead of time. Let’s see what happens when they vary.

Scenario Analysis

In the previous example, we looked at our widget making business and calculated an expected net return of $2,000. If all of the inputs are guaranteed, then we should always invest in this opportunity as it guarantees us a net return that is positive.

Scenario analysis introduces the idea of risk into these calculations. People started accounting for possible extreme values in their estimation of some inputs into calculations. Let’s change the above example slightly. Instead of 1500 widgets being guaranteed to be sold, we have three possibilities. I am most likely to sell 1500 widgets. The best case scenario though is that I can sell 2000 widgets. However, the worst case scenario is that I can only sell 500 widgets. Going through the same net revenue calculation for all three of these possibilities shows some variability to our final result. Now we have an expected net revenue still of $2,000, but with the possibility of making as much as $3,500 and losing as much as $1,000. With those possibilities, the investment is no longer a guarantee. This process can be repeated across all of the variables to see which one has the most impact on the net revenue.

This basic scenario analysis is OK, but still has highly variable outcomes. Is losing money rare or is it more likely that I make some money with a small chance of losing money? We don’t know as only three possibilities are shown. What about interdependence between variables? I imagine that the quantity I sell is highly related to the price that I charge.

Simulation

Simulation analysis allows us to account for all of the possible changes in all these variables and the possible correlation between them. The final output from a simulation analysis is the probability distribution of all possible outcomes. Let’s imagine triangle distributions for the inputs to the above example with the following bounds:

Widget Example
Variable Worst Case Expected Best Case
Quantity 500 1,500 2,000
Price $9.00 $10.00 $11.00
Variable Cost $8.00 $7.00 $6.50
Fixed Cost $3,000 $2,500 $1,500


By randomly drawing possible values from the respective triangle distributions 10,000 times and plotting the possible net revenues from each of these simulations we can get a fuller view of the possible outcomes from our widget investment. To do this we use the rtriangle function to draw values for each input to our equation. From there we just calculate the net revenue for each row in our input vectors to get 10,000 different possible net revenues. From there we just plot the corresponding distribution.

simulation.size <- 10000

Units <- rtriangle(simulation.size, a=500, b=2000, c=1500)
Var.Cost <- rtriangle(simulation.size, a=6.5, b=8, c=7)
Fixed.Cost <- rtriangle(simulation.size, a=1500, b=3000, c=2500)
Price <- rtriangle(simulation.size, a=8, b=11, c=10)

Net.Revenue <- (Price - Var.Cost)*Units - Fixed.Cost

hist(Net.Revenue, breaks=50, main='Sampling Distribution of Net Revenue', xlab='Net Revenue')

From this we see a much fuller picture of the possible outcomes from our investment. Although the average net revenue is a little over $1,000, in 23.34% of outcomes we lose money. This helps us better evaluate risk. For more information on how to develop simulations like this one, please see the code notes: Introduction to Simulation.

Key Risk Measures

Risk is an uncertainty that affects a system in an unknown fashion and brings great fluctuation in values and outcomes. Remember, that risk is a possible outcome of uncertainty. These outcomes can be measured in a probabilistic sense. Risk has a time horizon and has to be set against a benchmark. Risk analysis uses some of the “typical” statistical measures of spread.

There are some common measures that are used in risk analysis:

  1. Probability of occurrence - measures the probability of risky outcomes like a project losing money, defaulting on a loan, downgrading of a company, etc.
  2. Standard deviation / variance - measures spread in a two-sided manner that works best in normality or symmetric distributions.
  3. Semi-standard deviation - measures of dispersion for the values falling on the risk side of a distribution. For example, if you were measuring risk for profit the semi-standard deviation is calculated as:

\[ \sigma_{semi} = \sqrt{\frac{1}{T} \sum_{t=1}^T \min(X_t - \bar{X}, 0)^2} \]

  1. Volatility - measures the standard deviation of an asset’s logarithmic returns as follows:

\[ \sigma_{volatility} = \sqrt{\frac{1}{T} \sum_{t=1}^T \log(\frac{X_t}{X_{t-1}})^2} \]

  1. Value at Risk (VaR) - measures the amount of money at risk given a particular time period at a particular probability of loss. For example, a 1 year 1% VaR being $10,000 means there is a 1% chance you will lose more than $10,000 in 1 year.
  2. Expected Shortfall (ES) - measures the average money in the worst % of cases given a particular period of time. For example, in the worst 1% of scenarios, the average amount of money you will lose in one year is $15,000.

Value at risk and expected shortfall are some of the most popular measures of risk so we will discuss them in much further detail throughout these notes.

Value at Risk

Value at risk (VaR) was developed in the early 1990’s by JP Morgan. They were made famous in JP Morgan’s “4:15pm” report which was a daily report given to the Chief Risk Officer at JP Morgan detailing the risk of all current investments / portfolios. In 1994, JP Morgan launched RiskMetrics®. VaR has been widely used since that time and people are researching other similar measures.

The VaR calculation is aimed at making a statement of the following form: We are 1% certain that we will lose more than $10,000 in the next 3 days. VaR is the maximum amount at risk to be lost over a period of time and at a particular level of confidence. Essentially, VaR is associated with a percentile (quantile) of a distribution as shown in the chart below:

Value at Risk for Portfolio Value

For the plot above, the one year 1% VaR is $500,000. In other words, there is a 1% chance you will lose at least $500,000 by holding that portfolio for a year. Although most of the portfolio value over the next year is positive with the average being one million in value, there is some risk. VaR calculates the value that is most at risk in terms of a quantile. For costs, the VaR would be on the high end since risk is high cost, not low cost.

The main steps to estimating VaR are the following:

  1. Identify the variable of interest (asset value, portfolio value, credit losses, insurance claims, etc.)
  2. Identify the key risk factors that impact the variable of interest (asset prices, interest rates, duration, volatility, default probabilities, etc.)
  3. Perform deviations in the risk factors to calculate the impact in the variable of interest

The main question is how to estimate the distribution that we will calculate the quantile of. There are three main approaches to estimating the distribution in VaR:

  1. Delta-Normal (Variance-Covariance) Approach
  2. Historical Simulation Approach(s)
  3. Simulation Approach

These will be discussed in later sections of these notes.

Expected Shortfall

There are some downsides to value at risk as a calculation. One of them is that VaR ignores the distribution of a portfolio’s return beyond its VaR value. For example, if two portfolios each have a one year 1% VaR of $100,000, does that mean you are indifferent between the two? What if you then knew the maximum loss for one of the portfolios is $250,000, while the other has a maximum loss of $950,000. VaR ignores the magnitude of the worst outcomes. Another downside of VaR is that under non-normality, VaR may not capture diversification. Mathematically, it fails to satisfy the subadditivity property:

\[ Risk(A + B) \le Risk(A) + Risk(B) \]

The VaR of a portfolio with two securities may be larger than the sum of the VaR’s of the securities in the portfolio.

The expected shortfall (ES) (also called the conditional value at risk (CVaR)) is a measure that doesn’t have the two drawbacks described above. Given a confidence level and a time horizon, a portfolio’s ES is the expected loss one suffers given that a “bad” event occurs. The ES is a conditional expectation that tries to answer what you should expect to lose if your loss exceeds the VaR. It is the expected (average) value of the portfolio in the circled region below:

Expected SHortfall for Portfolio Value

The main question is how to estimate the distribution that we will calculate the average of the worst case outcomes. There are three main approaches to estimating the distribution in ES and they are the same as VaR:

  1. Delta-Normal (Variance-Covariance) Approach
  2. Historical Simulation Approach(s)
  3. Simulation Approach

These will be discussed in later sections of these notes.

Returns

Before getting into detail on calculating the distributions behind VaR and ES, let’s briefly talk about returns. A lot of the calculations in the remaining pieces of this document will revolve around calculating returns on assets. There are two main methods for calculating returns:

  1. Arithmetic returns
  2. Geometric returns

As we detail the differences between these approaches, here is the notation we will use:

  • Arithmetic Returns (\(r_t\)) - return at a period \(t\) (value of holding an asset from period \(t-1\) to period \(t\))
  • Price (\(P_t\)) - price at a given time period \(t\)
  • Lag Price (\(P_{t-1}\)) - price at a given time period \(t-1\)
  • Dividend (\(D_t\)) = sum of money regularly paid from company to shareholders at time period \(t\). For small time periods we typically ignore dividends (set them equal to 0). Equivalently, we can think about the price of an asset where dividends are fully reinvested and reflected in the price itself.

Arithmetic returns are calculated as follows:

\[ r_t = \frac{P_t + D_t - P_{t-1}}{P_{t-1}} = \frac{P_t - P_{t-1}}{P_{t-1}} \; when \; D_t = 0 \]

If \(r_1 = 5\%\) and \(r_2 = -5\%\), what is the total return of the two days? It is not 0%! This is how we would get the return, \(r_{0,2}\), over the two days:

\[ r_{0,2} = \frac{P_2 - P_0}{P_0} = \cdots = \frac{P_1}{P_0}r_2 + r_1 \ne r_2 + r_1 \]

For example, if we had $100 that we got 5% return on after 1 year, but lost 5% in year two with arithmetic returns we would have:

\[ P_0 = 100, \; P_1 = 100 \times (1 + 0.05) = 105, \; P_2 = 105 \times (1 - 0.05) = 99.75 \]

\[ r_{0,2} = \frac{99.75 - 100}{100} = -0.25\% \]

Geometric returns (denoted \(R_t\) instead) on the other hand are calculated as follows:

\[ R_t = \log(\frac{P_t + D_t}{P_{t-1}}) = \log(\frac{P_t}{P_{t-1}}) = \log(P_t) - \log(P_{t-1}) \; when \; D_t = 0 \]

If \(R_1 = 5\%\) and \(R_2 = -5\%\), what is the total return of the two days? It is 0%! This is how we would get the return, \(R_{0,2}\), over the two days:

\[ R_{0,2} = \log(\frac{P_2}{P_0}) = \log(\frac{P_2}{P_1} \times \frac{P_1}{P_0}) = \log(\frac{P_2}{P_1}) + \log(\frac{P_1}{P_0}) = R_1 + R_2 \]

Let’s use the previous example’s prices to see what the geometric returns would be:

\[ P_0 = 100, \; P_1 = 105, \; P_2 = 99.75 \]

\[ R_1 = 4.88%, \; R_2 = -5.13% \]

\[ R_{0,2} = \frac{99.75}{100} = 4.88% - 5.13% = -0.25\% \]

The difference between arithmetic and geometric means is very small when returns are close to zero. We can see this by expanding the natural log:

\[ R_t = \log(\frac{P_t}{P_{t-1}}) = \log(\frac{P_t - P_{t-1}}{P_{t-1}} + 1) = \log(1 + r_t) = r_t - \frac{r_t^2}{2} + \frac{r_t^3}{3} - \cdots \]

This is approximately \(r_t\) when \(r_t\) is small. The following are the arithmetic returns and geometric returns for Google.

Returns for Google

As you can see above, the two different types of returns are approximately equal.

Estimation of VaR and ES

The main steps to estimating VaR and ES are the following:

  1. Identify the variable of interest (asset value, portfolio value, credit losses, insurance claims, etc.)
  2. Identify the key risk factors that impact the variable of interest (asset prices, interest rates, duration, volatility, default probabilities, etc.)
  3. Perform deviations in the risk factors to calculate the impact in the variable of interest

The main question is how to estimate the distribution that we will calculate the quantile of. There are three main approaches to estimating the distribution in VaR:

  1. Delta-Normal (Variance-Covariance) Approach
  2. Historical Simulation Approach(s)
  3. Simulation Approach

First we will discuss how to do this for value at risk followed by expected shortfall.

Delta Normal

The Delta Normal approach has two key characteristics that define it. First, we will discuss the Normal part of the name. Suppose that the value, \(V\), of an asset is a function of a normally distributed risk factor, \(RF\). Assume that the relationship between this risk factor and the value of the asset is linear:

\[ V = \beta_0 + \beta_1 RF \]

In this situation it is easy to calculate the VaR. If \(RF\) is normally distributed in the baove equation, then \(V\) would also be normally distributed as well. The 2.5% VaR on any normal distribution is the quantile shown below:

Quantiles on Normal Distribution

The VaR at 2.5% is just \(\mu - 1.96\sigma\). With an estimate of \(\mu\) and \(\sigma\) we can estimate this number easily. In fact, any VaR for a normal distribution can be calculated by adjusting the \(1.96\) to match the quantile of interest. For example, the 1% VaR is \(\mu - 2.33\sigma\).

The above approach works great if the relationship is linear between \(RF\) and \(V\). What if the relationship between the two is nonlinear:

\[ V = \beta_0 + \beta_1 RF^2 \]

Finding the extreme of a normally distributed value and squaring that value does not equal the extreme value for a squared risk factor. However, we can still use the normality assumption to help calculate the VaR.

This is where the delta piece of the name comes into play. The derivative of the relationship will help us approximate what we need. Remember, the derivative at a specific point (say \(RF_0\)) is the tangent line at that point. If we zoom in closer to the area around \(RF_0\) the relationship is approximately linear as seen below:

Tangent Line on Non-Linear Relationship

Small changes of the risk factor result in small changes of the value of the asset. We can approximate these small changes with the slope. We can see this more mathematically by looking at the Taylor-series expansion of a function’s derivatives:

\[ dV = \frac{\partial V}{\partial RF}\cdot dRF + \frac{1}{2}\cdot \frac{\partial^2 V}{\partial RF^2}\cdot dRF^2 + \cdots \]

The Delta-Normal approach assumes that only the first derivative is actually important. We can evaluate this first derivative at a specific point \(RF_0\) which is typically some initial value:

\[ dV = \frac{\partial V}{\partial RF} \Biggr \vert_{RF_0} \cdot dRF \; \rightarrow \; \Delta V = \delta_0 \cdot \Delta RF \]

The change in the value of the asset / portfolio is a constant (\(\delta_0\)) multiplied by the change in the risk factor. This is a linear relationship between the changes. All we need to know is the distribution of \(\Delta RF\). Luckily, we already assumed normality for \(RF\). Since \(\Delta RF = RF_t - RF_{t-1}\) and each of \(RF_t\) and \(RF_{t-1}\) are normal, then \(\Delta RF\) is normally distributed since the difference in normal distributions is still normal. Therefore, the change in the value of the asset / portfolio, \(\Delta V\) is also normally distributed by the same logic. Since \(\Delta V\) is normally distributed we can easily calculate any VaR values for the change in the portfolio as we did above.

Let’s work through an example! Suppose that the variable of interest is a portfolio consisting of \(N\) units in a certain stock, \(S\). The price of the stock at time \(t\) is denoted as \(P_t\). Therefore, the value of the portfolio is \(N \times P_t\). Let’s assume that the price of the stock follows a random walk:

\[ P_t = P_{t-1} + \varepsilon_t \] with \(\varepsilon_t\) following a normal distribution with mean 0 and standard deviation \(\sigma\). Therefore, the change in the value of the portfolio is \(N \times \Delta P_t\) with \(\Delta P_t = P_t - P_{t-1} = \varepsilon_t\) which is a normal distribution. We can then look up the VaR for a portfolio under this structure by just looking up the corresponding point on the normal distribution. If we wanted the 1% VaR for the change in the value of the portfolio, it would just be \(0 - 2.33 \sigma\). This is why the Delta-Normal approach is sometimes referred to as the variance-covariance approach. If you know the variances of your data and are willing to assume normality, then the calculation of the VaR is rather straight forward.

Let’s put some numbers to the previous example. Suppose you invested $100,000 in Apple today (bought Apply stock). Historically, the daily standard deviation of Apple returns are 2.36%. Let’s also assume daily returns for Apple have a mean return of 0%. Let’s assume that the returns for Apple follow a normal distribution. Then the 1 day, 1% VaR is calculated as \(\$100,000 \times (-2.33) \times 0.0236 = -\$5,498.80\). In other words, you think there is a 1% chance of losing more than $4,075.50 by holding that portfolio of Apple stock for a single day.

What if we had two assets in our portfolio? Luckily, these calculations are still easily worked out under the assumption of normality. If we had two random variables X and Y that were both normally distributed, then the variance of a linear combination of X and Y, \(aX + bY\) would be the following:

\[ \sigma^2 = a^2 \sigma_X^2 + b^2 \sigma_Y^2 + 2ab \times Cov(X,Y) \]

Suppose you invested $200,000 in Microsoft and $100,000 in Apple. Assume the historical daily average return is 0% for both. Also assume that the historical standard deviation of daily returns for Microsoft and Apple are 2.15% and 2.36% respectively. Lastly, assume that the historical correlation between the two returns is 0.791. Under the assumption that both returns follow normal distributions then the variance of that portfolio is the following:

\[ \sigma^2_P = (\frac{2}{3})^2 \sigma_M^2 + (\frac{1}{3})^2 \sigma_A^2 + 2(\frac{2}{3})(\frac{1}{3}) \times Cov(M,A) \]

\[ \sigma^2_P = (\frac{2}{3})^2 0.0215^2 + (\frac{1}{3})^2 0.0236^2 + 2(\frac{2}{3})(\frac{1}{3}) \times (0.791 * 0.0215 * 0.0236) = 0.00045 \]

Then the one day, 1% VaR for this portfolio is \(\$300,000 \times (-2.32635) \times \sqrt(0.00045) = -\$14,728.28\).

Let’s see how we can do this in each of our softwares!

R

It is easy to replicate the calculations we did above by hand using R. First, we need to collect our stock data. We can do this using the getSymbols function. The input to the getSymbols function is the stock tickers from the New York Stock Exchange accessed through Yahoo Finance ®. It will pull all daily opening, closing, high, and low prices for the given stock tickers and save them in dataframes under the same names. The last function will extract only the last number of observations from the data sets. Here we are looking at the last 500 days. Every day you run this code, the last 500 days will change so the calculations could be different. Specifically we are looking only at the closing prices for each stock. The ROC function will give us the daily returns for each of these stocks now saved as the variables msft_r and appl_r.

tickers = c("AAPL", "MSFT")

getSymbols(tickers)
[1] "AAPL" "MSFT"
stocks <- cbind(last(AAPL[,4], '500 days'), last(MSFT[,4], '500 days'))

stocks$msft_r <- ROC(stocks$MSFT.Close)
stocks$aapl_r <- ROC(stocks$AAPL.Close)

head(stocks)
           AAPL.Close MSFT.Close       msft_r       aapl_r
2019-02-26    43.5825     112.36           NA           NA
2019-02-27    43.7175     112.17 -0.001692451  0.003092763
2019-02-28    43.2875     112.03 -0.001248876 -0.009884593
2019-03-01    43.7425     112.53  0.004453160  0.010456306
2019-03-04    43.9625     112.26 -0.002402217  0.005016874
2019-03-05    43.8825     111.70 -0.005000948 -0.001821436

Next, we just calculate the historical numbers we need for our calculations, namely the correlation between and the variance of the stocks. Instead of the correlation, we could also use the covariance directly. The cov, var, and cor functions give us the covariance, variances, and correlations respectively. From there we just recreate the equation written above in code. Lastly, we use the qnorm function to get the quantile from the normal distribution for our VaR calculation.

var.msft <- var(stocks$msft_r, na.rm=TRUE)
var.aapl <- var(stocks$aapl_r, na.rm=TRUE)
cov.m.a <- cov(stocks$msft_r, stocks$aapl_r, use="pairwise.complete.obs")
cor.m.a <- cor(stocks$msft_r, stocks$aapl_r, use="pairwise.complete.obs")

VaR.percentile = 0.01
AAPL.inv <- 100000
MSFT.inv <- 200000

var.port <- (MSFT.inv/(MSFT.inv+AAPL.inv))^2*var.msft + (AAPL.inv/(MSFT.inv+AAPL.inv))^2*var.aapl + 2*(AAPL.inv/(MSFT.inv+AAPL.inv))*(MSFT.inv/(MSFT.inv+AAPL.inv))*cov.m.a

VaR.DN.port <- (AAPL.inv+MSFT.inv)*qnorm(VaR.percentile)*sqrt(var.port)
dollar(VaR.DN.port)
[1] "-$14,729.81"

If the number above is different than the number we calculated by hand, then it is simply a result of a different time period and different data underlying it. The code is written to always use the most up to date data for each stock.

Another great aspect of the VaR under the normality assumption is the ease of calculating any \(n\)-day VaR from the 1-day VaR. This is defined simply as \(VaR_n = \sqrt(n) \times VaR_1\). Another great reason why the normality assumption in the Delta-Normal approach makes the calculation of VaR numbers rather easy.

SAS

We will use the functions in the R section of the code to get the necessary data in a dataset called stocks. First, we will use PROC CORR to get us the necessary information on the variances, covariances, and correlations. You could easily just write these numbers down, but we are going to use the out = option to store the needed information into a dataset called covar_results. We then use the DATA step to create MACRO variables that store the values of the covariance between and variances of the stocks.

proc corr data=SimRisk.stocks cov out=covar_results plots;
    var msft_r aapl_r;
run;

data _null_;
    set covar_results(where = (_type_ eq 'COV'));
    if upcase(_name_) eq 'MSFT_R' then do;
        call symput("var_msft",msft_r);
        call symput("covar",aapl_r);
    end;
    if upcase(_name_) eq 'AAPL_R' then do;
        call symput("var_aapl",aapl_r);
    end;
run;

data _null_;
    set covar_results(where = (_type_ eq 'CORR'));
    if upcase(_name_) eq 'MSFT_R' then do;
        call symput("corr",aapl_r);
    end;
run;
2 Variables: msft_r aapl_r

Covariance Matrix, DF = 498
msft_r aapl_r
msft_r 0.0004619768 0.0004010742
aapl_r 0.0004010742 0.0005560452

Simple Statistics
Variable N Mean Std Dev Sum Minimum Maximum
msft_r 499 0.00158 0.02149 0.78668 -0.15945 0.13293
aapl_r 499 0.00225 0.02358 1.12495 -0.13771 0.11316

Pearson Correlation Coefficients, N = 499
Prob > |r| under H0: Rho=0
msft_r aapl_r
msft_r
1.00000
0.79133
<.0001
aapl_r
0.79133
<.0001
1.00000

Next, we need to use PROC IML to do the calculations by hand. PROC IML is the interactive matrix language of SAS. It is similar in design to R. We start by defining some MACRO variables for the amount we invested in each stock as well as the desired VaR percentile. From there we invoke PROC IML and put in calculations as we would in R. We print out the results of these equations that we defined above.

%let msft_position = 200000;
%let aapl_position = 100000;
%let var_percentile = 0.01;

proc iml;
title 'VaR Results';

msft_p_weight = &msft_position/(&msft_position + &aapl_position);
aapl_p_weight = &aapl_position/(&msft_position + &aapl_position);

P_variance =  &var_msft*(msft_p_weight)**2 + &var_aapl*(aapl_p_weight)**2 
                   + 2*aapl_p_weight*msft_p_weight*&covar;
P_StdDev=sqrt(P_variance);

VaR_normal = (&msft_position + &aapl_position)*PROBIT(&var_percentile)*SQRT(P_variance);

print "Daily VaR (Percentile level: &var_percentile); Delta-Normal" VaR_normal[format=dollar15.2];

quit;
VaR Results

VaR_normal
Daily VaR (Percentile level: 0.01); Delta-Normal $-14,728.28

If the number above is different than the number we calculated by hand, then it is simply a result of a different time period and different data underlying it. The code is written to always use the most up to date data for each stock.

Another great aspect of the VaR under the normality assumption is the ease of calculating any \(n\)-day VaR from the 1-day VaR. This is defined simply as \(VaR_n = \sqrt(n) \times VaR_1\). Another great reason why the normality assumption in the Delta-Normal approach makes the calculation of VaR numbers rather easy.

Historical Simulation Approach

The historical simulation approach is a non-parametric (distribution free) approach to estimating the VaR and ES values. This approach, as the name states, depends solely on historical data. For example, if history suggests that only 1% of the time Apple’s daily returns were below -4%, then the 1% VaR for daily returns is just -4%. Essentially, we just find the quantiles of our historical data! Let’s work through some examples.

Single Position Example

Suppose you invested $100,000 in Apple today. You have 500 historical observations on Apple’s daily returns. You want to compute the daily, 1% VaR of your portfolio. All we have to do is find the 1% quantile of our 500 observations. To do this we simply calculate the portfolio’s value as if the 500 historical observations we had were possible future values of the Apple’s daily returns. We sort these 500 portfolio values from worst to best. The 1% of 500 days is 5 days, so we need to find a loss that is only exceeded 5 times. In other words, the 1% VaR would be the 6th observation in our sorted possible portfolio values as shown below:

6 Worst Observations in Time Window of 2/22/2019 - 2/16/2021

Here we can see that our portfolio dropping 6.76% in value is the 6th worst occurrence.

Let’s see how to do this in each of our softwares!

R

It is rather easy to sort data in R. We simply use the order function inside of the [] to resort the rows of the variable of interest. We then just use the head function to define which elements we want to look at. Here we want the 6th element.

VaR.H.AAPL <- AAPL.inv*stocks$aapl_r[head(order(stocks$aapl_r), 6)[6]]
print(VaR.H.AAPL)
              aapl_r
2020-02-27 -6760.263

SAS

We will use PROC IML again to easily calculate this quantile in SAS. Again, we will read in our data that we obtained from R. We then calculate the portfolio values as we did before. Lastly, we just use the SORT function from the CALL statement to sort these returns. From there we just use the 6th observation.

proc iml;

use SimRisk.stocks var {aapl_r}; 
read all var _all_ into returns;

portfolio_return = &aapl_position*returns[,1];

call sort(portfolio_return,{1});
number_of_observations = nrow(portfolio_return);

VaR_historical = portfolio_return[6,1];

print "Daily VaR (Percentile level: &var_percentile); Historical" VaR_historical[format=dollar15.2];

title;
quit;
VaR_historical
Daily VaR (Percentile level: 0.01); Historical $-6,760.26

Two Position Example

We can easily extend this to a two position portfolio example by taking the same approaches. Suppose you invested $200,000 in Microsoft and $100,000 in Apple today. You have 500 historical observations on both returns. Simply calculate the portfolio’s value as if each of the previous 500 days is a possible scenario for your one day return on this portfolio. We then sort these 500 possible scenarios and the 1% VaR will be the 6th observation as shown below:

6 Worst Observations in Time Window of 2/22/2019 - 2/16/2021

Let’s see how to do this in each of our softwares!

R

Just like with the one position portoflio, it is rather easy to sort data in R. We simply use the order function inside of the [] to resort the rows of the variable of interest. We then just use the head function to define which elements we want to look at. Here we want the 6th element.

stocks$port_v <- MSFT.inv*stocks$msft_r + AAPL.inv*stocks$aapl_r

VaR.H.port <- stocks$port_v[order(stocks$port_v)[6]]
dollar(as.numeric(VaR.H.port))
[1] "-$18,089.40"

SAS

Just like with the one position portfolio, we will use PROC IML again to easily calculate this quantile in SAS. Again, we will read in our data that we obtained from R. We then calculate the portfolio values as we did before. Lastly, we just use the SORT function from the CALL statement to sort these returns. From there we just use the 6th observation.

proc iml;

use SimRisk.stocks var {msft_r aapl_r}; 
read all var _all_ into returns;

portfolio_return = &msft_position*returns[,1] + &aapl_position*returns[,2];

call sort(portfolio_return,{1});
number_of_observations = nrow(portfolio_return);

VaR_historical = portfolio_return[6,1];

print "Daily VaR (Percentile level: &var_percentile); Historical" VaR_historical[format=dollar15.2];

title;
quit;
VaR_historical
Daily VaR (Percentile level: 0.01); Historical $-18,089.40

Stressed VaR and ES

There are some key assumptions we are making with the historical simulation approach:

  1. The past will repeat itself.
  2. The historical period covered is long enough to get a good representation of “tail” events.

These have lead to alternative version of the historical simulation approach.

One of these approaches is the stressed VaR (and ES) approach. Instead of basing the calculations on the movements in market variables over the last \(n\) days, we can base calculations on movements during a period in the past that would have been particularly bad for the current portfolio. Essentially, we look for the worst collection of \(n\) days in a row in our data. That is where we will get our stressed VaR instead of the last \(n\) days.

Let’s see how to do this in each of our softwares!

R

The only difference between the stressed approach and the historical simulation approach is the data that we use. In the code below we will get a different collection of data then just the previous 500 days. First, we aggregate all of our data back to 2007 in a new dataframe called stocks_stressed. Again, we calculate the daily returns and daily portfolio values of holding $200,000 in Microsoft and $100,000 in Apple. We then use the SMA function to calculate the moving average of the portfolio value across 500 days for every observation in the data. Essentially, we are trying the “worst” 500 days in terms of our portfolio values. These will be what we build the VaR calculation off of.

stocks_stressed <- cbind(AAPL[, 4], MSFT[, 4])
stocks_stressed$msft_r <- ROC(stocks_stressed$MSFT.Close)
stocks_stressed$aapl_r <- ROC(stocks_stressed$AAPL.Close)
stocks_stressed$port_v <- MSFT.inv*stocks_stressed$msft_r + AAPL.inv*stocks_stressed$aapl_r

stocks_stressed$ma <- SMA(stocks_stressed$port_v, 500)
stocks_stressed <- stocks_stressed[seq(order(stocks_stressed$ma)[1]-499,order(stocks_stressed$ma)[1],1)]

From there we use the same approach to calculating the VaR.

stressed.VaR.H.port <- stocks_stressed$port_v[order(stocks_stressed$port_v)[6]]
dollar(as.numeric(stressed.VaR.H.port))
[1] "-$18,639.23"

We can see that this number is slightly larger than the traditional historical simulation approach.

SAS

The only difference between the stressed approach and the historical simulation approach is the data that we use. As with the previous example we will use R to get the data and then analyze it in SAS. From there we use the same approach to calculating the VaR.

proc iml;

use SimRisk.stocks_s var {msft_r aapl_r}; 
read all var _all_ into returns;

portfolio_return = &msft_position*returns[,1] + &aapl_position*returns[,2];

call sort(portfolio_return,{1});
number_of_observations = nrow(portfolio_return);

VaR_historical = portfolio_return[6,1];

print "Daily VaR (Percentile level: &var_percentile); Historical" VaR_historical[format=dollar15.2];

title;
quit;
VaR_historical
Daily VaR (Percentile level: 0.01); Historical $-18,639.23

We can see that this number is slightly larger than the traditional historical simulation approach.

Multiple Day VaR

With the Delta-Normal approach is was easily mathematically to extend the 1 day VaR calculations to the \(n\)-day VaR. When extending to multiple days using the historical simulation approach you could do one of the following approaches:

  1. Calculate \(n\) day returns first, then run the historical simulation approach(es) as desired.
  2. Use any of the historical simulation approaches, but consider the daily returns as starting points. Record the return of the next consecutive \(n\) days to get a real example of \(n\) day returns for simulation.

Simulation

The last approach to estimating the VaR and ES would be through simulation. We simulate the value of the portfolio using some statistical / financial model that explains the behavior of the random variables of interest. If we have “enough” simulations then we have simulated the distribution of the portfolio’s value. From there we can find the VaR or ES at any point we desire. Simulation approaches allow us to control for non-normal distributions, non-linear relationships, multidimensional problems, and history changing.

Using simulation assumes a couple of key aspects:

  1. The choice of distribution is an accurate representation of the reality.
  2. The number of draws is enough to capture the tail behavior.

Let’s walk through the approach for our two position portfolio. If we have $200,000 invested in Microsoft and $100,000 invested in Apple, we just need to pick a distribution for their returns to simulate. Assume a normal distribution for each of these stocks returns with their historical mean and standard deviation. We can draw 10,000 observations from each of these distributions.

We can add in the correlation structure to these returns through Cholesky decomposition. For more details on Cholesky decomposition and adding correlation to simulations, please see the code notes for Introducion to Simulation.

From there, we just need to calculate the quantile for this distribution. With 10,000 simulations, the 1% VaR would be the \(101^{st}\) observation.

Due to the normality assumption in this example we could have easily used the Delta-Normal approach instead, but it would at least illustrates the simulation approach.

Let’s see how to do this in each of our softwares!

R

Running this simulation is rather easy to do in R. First, we define our correlation structure (here R) and calculate the Cholesky decomposition of this matrix to multiply into our data. Next, we simulate 10,000 draws from the respective normal distributions for our Microsoft and Apple returns using the rnorm function. We multiply in the correlation structure and then simply calculate the return on the portfolio of these two sets of returns. From there it is a simple call of the quantile function to find the quantile of the distribution to get the VaR. A histogram of the distribution of changes in the portfolio is also provided.

n.simulations <- 10000
R <- matrix(data=cbind(1,cor.m.a, cor.m.a, 1), nrow=2)
U <- t(chol(R))

msft.r <- rnorm(n=n.simulations, mean=0, sd=sqrt(var.msft))
aapl.r <- rnorm(n=n.simulations, mean=0, sd=sqrt(var.aapl))
Both.r <- cbind(msft.r, aapl.r)
port.r <- U %*% t(Both.r)
port.r <- t(port.r)

value.change <- MSFT.inv*port.r[,1] + AAPL.inv*port.r[,2]
value <- (MSFT.inv + AAPL.inv) + value.change

VaR <- quantile(value.change, VaR.percentile, na.rm=TRUE)
VaR.label <- dollar(VaR)

hist(value.change/1000, breaks=50, main='1 Day Value Change Distribution', xlab='Value Change', col="lightblue")
breaks = c(-40, -30, -20, -10, 0, 10, 20, 30, 40, 50, 60)
axis(1, at = breaks, labels = paste("$", breaks, "K", sep = ""))
abline(v = VaR/1000, col="red", lwd=2)
mtext(paste("Value at Risk",VaR.label, sep=" = "), at=VaR/1000, col="red")

As you can see from above, the one day, 1% VaR for this portfolio (assuming normality of returns for each asset) is $14,476.19.

SAS

Running this simulation is a little complicated in SAS due to correlation structure we are imposing on the returns. For more detail on the code below and the approach to adding in correlation structures in simulations in SAS please see the code notes for Introducion to Simulation. First, we define our correlation structure using the DATA step. This will repeat the desired correlation matrix the number of times we are simulating. Next, we again use the DATA step to define starting points for each of the variables in the simulation - namely the returns for Microsoft and Apple. From there PROC MODEL simulates and correlates the necessary returns.

data Corr_Matrix;
    do i=1 to 10000;
        _type_ = "corr";
        _name_ = "msft_r";

        msft_r = 1.0; 
        aapl_r = &corr;

        output;
        _name_ = "aapl_r";

        msft_r = &corr; 
        aapl_r = 1.0;

        output;
    end;
run;

data Naive;
    do i=1 to 10000;
        msft_r=0;
        aapl_r=0;
        output;
    end;
run;

proc model noprint;

    msft_r = 0;
    errormodel msft_r ~Normal(&var_msft);

    aapl_r = 0;
    errormodel aapl_r ~Normal(&var_aapl);

    solve msft_r aapl_r/ random=1 sdata=Corr_Matrix
    data=Naive out=mc_stocks(keep=msft_r aapl_r i);
        by i;

run;
quit;

data mc_stocks;
    set mc_stocks;
    by i;
    if first.i then delete;
    rename i=simulation;
    value_change = &msft_position*msft_r + &aapl_position*aapl_r;
    value = &msft_position + &aapl_position + value_change;
    format value_change dollar15.2;
run;

%let var_clevel=%sysevalf(100*&var_percentile);
    
proc univariate data=mc_stocks;
    var value_change;
    format value_change dollar15.2;
    output out=percentiles pctlpts = &var_clevel pctlpre=P;
    histogram value_change / kernel normal;
  ods select Quantiles;
run;
Variable: value_change

Quantiles (Definition 5)
Level Quantile
100% Max 26189.6834
99% 14542.6342
95% 10210.8088
90% 8113.6385
75% Q3 4169.7244
50% Median -53.3739
25% Q1 -4251.9856
10% -8178.0204
5% -10484.2905
1% -14628.3288
0% Min -25310.7449

As you can see from above, the one day, 1% VaR for this portfolio (assuming normality of returns for each asset) is $14,615.71.

Comparison of Three Approaches

The following is a summary comparison for the three approaches - Delta-Normal, historical simulation, and simulation.

Advantages and Disadvantages of 3 Approaches

Confidence Intervals for VaR

Value at risk calculations in any of the above approaches are just estimates. All estimates have a notion of variability. Therefore, we can calculate confidence intervals for each of the above approaches.

When you have a normal distribution (the Delta-Normal approach) there is a known mathematical equation for the confidence interval around a quantile. It is derived as a confidence interval around the standard deviation \(\sigma\) followed by multiplying this \(\sigma\) by the corresponding quantiles of interest on the normal distribution. The confidence interval for \(\sigma\) is as follows:

\[ CI(\hat{\sigma}) = (\sqrt{\frac{(n-1)\hat{\sigma}^2}{\chi^2_{\alpha / 2, n-1}}}, \; \sqrt{\frac{(n-1)\hat{\sigma}^2}{\chi^2_{1 - \alpha / 2, n-1}}}) \]

For non-normal distributions or historical / simulation approaches, the bootstrap method of confidence intervals is probably best. The bootstrap approach to confidence intervals is as follows:

  1. Resample from the simulated data using their empirical distribtion; or rerun the simulation severeal times.
  2. In each new sample (from step 1) calculate the VaR.
  3. Repeat steps 1 and 2 many times to get several VaR estimates. Use these estimates to get the expected VaR and its confidence interval.

Let’s see both of these approaches in our softwares!

R

Let’s first start with the direct normal distribution calculation approach. Under the Delta-Normal approach you can easily calculate the confidence interval for the value at risk based on the equation defined above. The code below just recreates that function using the qchisq and qnorm functions were necessary to get values from the \(\chi^2\) and normal distributions.

sigma.low <- sqrt(var.port*(length(stocks$AAPL.Close)-1)/qchisq((1-(VaR.percentile/2)),length(stocks$AAPL.Close)-1) )
sigma.up <- sqrt(var.port*(length(stocks$AAPL.Close)-1)/qchisq((VaR.percentile/2),length(stocks$AAPL.Close)-1) )

VaR.DN.port <- (AAPL.inv+MSFT.inv)*qnorm(VaR.percentile)*sqrt(var.port)
VaR.L <-  (AAPL.inv+MSFT.inv)*qnorm(VaR.percentile)*(sigma.low)
VaR.U <- (AAPL.inv+MSFT.inv)*qnorm(VaR.percentile)*(sigma.up)

print(paste("The VaR is ", dollar(VaR.DN.port), " with confidence interval (", dollar(VaR.L), " , ", dollar(VaR.U), ")", sep = "" ))
[1] "The VaR is -$14,729.81 with confidence interval (-$13,614.27 , -$16,029.05)"

To perform the bootstrap approach in R, we first need to define the number of bootstrap samples as well as the size of each of these samples. From there we loop through the simulation values we already obtained earlier called value.change using a for loop. Using the sample function we can sample values from our original simulation and calculate the VaR of this new sub-sample using the quantile function at our percentile. We repeat this process over and over until we form many different values for our VaR from which to build our confidence interval. From there we simply look at the values that define the middle 95% of all of our VaR values, again using the quantile function to define the upper and lower bounds of our confidence interval. Lastly, we plot the VaR as well as its confidence interval bounds on a histogram of the value.change distribution.

n.bootstraps <- 1000
sample.size <- 1000

VaR.boot <- rep(0,n.bootstraps)
for(i in 1:n.bootstraps){
  bootstrap.sample <- sample(value.change, size=sample.size)
  VaR.boot[i] <- quantile(bootstrap.sample, VaR.percentile, na.rm=TRUE)
}

VaR.boot.U <- quantile(VaR.boot, 0.975, na.rm=TRUE)
VaR.boot.L <- quantile(VaR.boot, 0.025, na.rm=TRUE)

print(paste("The VaR is ", dollar(mean(VaR.boot)), " with confidence interval (", dollar(VaR.boot.L), " , ", dollar(VaR.boot.U), ")", sep = "" ))
[1] "The VaR is -$14,033.25 with confidence interval (-$15,606.72 , -$12,821.69)"
hist(value.change/1000, breaks=50, main='1 Day Value Change Distribution', xlab='Value Change', col="lightblue")
breaks = c(-20, -10, 0, 10, 20)
axis(1, at = breaks, labels = paste("$", breaks, "K", sep = ""))
abline(v = VaR/1000, col="red", lwd=2)
mtext(paste("Value at Risk",VaR.label, sep=" = "), at = VaR/1000, col="red")
abline(v = VaR.boot.L/1000, col="blue", lwd=2, lty="dashed")
abline(v = VaR.boot.U/1000, col="blue", lwd=2, lty="dashed")

SAS

It is actually rather easy to calculate the confidence intervals for a percentile in SAS under the normality assumption. PROC UNIVARIATE and the cipctlnormal option calculates confidence intervals for percentiles of any variable. Here we define the value_change variable from our dataset to make this calculation.

proc univariate data=mc_stocks cipctlnormal;
    var value_change;
  ods select Quantiles;
run;
Variable: value_change

Quantiles (Definition 5)
Level Quantile 95% Confidence Limits
Assuming Normality
100% Max 22706.234
99% 15013.916 14641.3 15121.9
95% 10615.659 10349.6 10732.6
90% 8153.985 8058.8 8395.7
75% Q3 4252.741 4222.5 4499.1
50% Median 82.039 -60.0 189.6
25% Q1 -4188.497 -4369.5 -4092.9
10% -8041.911 -8266.1 -7929.2
5% -10312.626 -10603.0 -10220.0
1% -15076.400 -14992.3 -14511.7
0% Min -23546.838

To perform the bootstrap approach in SAS, we first need to define the number of bootstrap samples as well as the size of each of these samples. From there we use PROC SURVEYSELECT to sample from our dataset many times. The method = srs option specifies that we want to use simple random sampling. We want sample sizes that are 10% of the size of the simulation which is defined in the samprate = option. Lastly, we repeat this sampling over and over again using the rep = option. Make sure to put noprint so you don’t see results from each of these 1000 samples!

Next, we just calculate percentiles using PROC UNIVARIATE for each of the samples (called replicates) using the by statement. We will output the percentiles from each of these calculations using the output statement with the out = option. Specifically, we want the 1% quantile (our VaR values) which we can define using the pctlpts option. We will label this quantile as P1. We define this name using the pctlpre option to define the prefix on the number of the quantile (here 1). Another PROC UNIVARIATE call will give us the percentiles of all of these VaR calculations from the previous PROC UNIVARIATE. Lastly, we print these results.

%let n_bootstraps=1000;
%let bootstrap_prop=0.1;
%let var_percentile = 0.01;
%let var_clevel=%sysevalf(100*&var_percentile);

proc surveyselect data=mc_stocks out=outboot seed=12345 method=srs 
                  samprate=&bootstrap_prop rep=&n_bootstraps noprint;
run; 

proc univariate data=outboot noprint;
    var value_change;
    output out=boot_var pctlpts = &var_clevel pctlpre=P;
    by replicate;
run;

proc univariate data=boot_var;
    var P1;
    output out=var_ci pctlpts = 2.5 97.5 pctlpre=P;
  ods select Quantiles;
run;

proc print data=var_ci;
run;
Variable: P1 (the 1.0000 percentile, value_change)

Quantiles (Definition 5)
Level Quantile
100% Max -12630.0
99% -13221.3
95% -13684.1
90% -13897.2
75% Q3 -14221.1
50% Median -14638.3
25% Q1 -15138.9
10% -15633.6
5% -15940.0
1% -16596.7
0% Min -17438.4



Obs P2_5 P97_5
1 -16235.26 -13472.77

Expected Shortfall

The ES is a conditional expectation that tries to answer what you should expect to lose if your loss exceeds the VaR. It is the expected (average) value of the portfolio in the circled region below:

Expected SHortfall for Portfolio Value

The main question is how to estimate the distribution that we will calculate the average of the worst case outcomes. There are three main approaches to estimating the distribution in ES and they are the same as VaR:

  1. Delta-Normal (Variance-Covariance) Approach
  2. Historical Simulation Approach(s)
  3. Simulation Approach

The best part is that extending these approaches to include expected shortfall from what we already covered for value at risk is rather straight forward. Let’s take a look at each of these.

Delta-Normal

Just like the VaR calculation for the Delta-Normal approach, the ES has a known equation. For a normal distribution, the average (or expected value) in a tail of the distribution is defined as follows:

\[ ES = CVaR = \mu - \sigma \times \frac{e^{\frac{-q^2_\alpha}{2}}}{\alpha \sqrt(2\pi)} \] with \(\sigma\) being the standard deviation of the data, \(\alpha\) being the percentile of interest (1% for example), and \(q_\alpha\) as the tail percentile from the standard normal distribution (-2.33 for example).

Let’s see how to code this into our softwares!

R

Just as with the VaR, the ES is easy to hard code into R directly. The function below repeats the same function as defined above.

ES.DN.port <- (0 - sqrt(var.port)*exp(-(qnorm(VaR.percentile)^2)/2)/(VaR.percentile*sqrt(2*pi)))*(AAPL.inv+MSFT.inv)
dollar(ES.DN.port)
[1] "-$16,875.42"

Again, this value is saying that if the worst 1% of cases happens, we expect to lose $16,874.49 on average.

SAS

Just as with the VaR, the ES can be coded into SAS directly using PROC IML. The function below repeats the same function as defined above.

%let msft_position = 200000;
%let aapl_position = 100000;
%let var_percentile = 0.01;

proc iml;
title 'VaR Results';

msft_p_weight = &msft_position/(&msft_position + &aapl_position);
aapl_p_weight = &aapl_position/(&msft_position + &aapl_position);

P_variance =  &var_msft*(msft_p_weight)**2 + &var_aapl*(aapl_p_weight)**2 
                   + 2*aapl_p_weight*msft_p_weight*&covar;
P_StdDev=sqrt(P_variance);

VaR_normal = (&msft_position + &aapl_position)*PROBIT(&var_percentile)*SQRT(P_variance);

pi=3.14159265;
ES_normal = -(&msft_position + &aapl_position)*SQRT(P_variance)*exp(-0.5*(PROBIT(&var_percentile))**2)/(&var_percentile.*sqrt(2*pi));

print "Daily CVaR/ES (Percentile level: &var_percentile); Delta-Normal" ES_normal[format=dollar15.2];

quit;
VaR Results

ES_normal
Daily CVaR/ES (Percentile level: 0.01); Delta-Normal $-16,873.67

Again, this value is saying that if the worst 1% of cases happens, we expect to lose $16,873.67 on average.

Historical

We can easily extend the historical simulation approach for VaR to ES. Let’s look at our two position portfolio example. Suppose you invested $200,000 in Microsoft and $100,000 in Apple today. You have 500 historical observations on both returns. Simply calculate the portfolio’s value as if each of the previous 500 days is a possible scenario for your one day return on this portfolio. We then sort these 500 possible scenarios and the 1% ES will be the average of these 5 observations that make up the 1%:

6 Worst Observations in Time Window of 2/22/2019 - 2/16/2021

The average of these 5 observations is -$28,154.09. Again, this value is saying that if the worst 1% of cases happens, we expect to lose $28,154.09 on average. Let’s see how to do this in each of our softwares!

R

Just as with the historical simulation approach before for VaR, we can easily isolate the worst five observations using the head and order functions followed by using the mean to take the average.

ES.H.port <- mean(stocks$port_v[head(order(stocks$port_v), 5)])
dollar(as.numeric(ES.H.port))
[1] "-$28,154.09"

Again, this value is saying that if the worst 1% of cases happens, we expect to lose $28,154.09 on average.

SAS

Just as with the historical simulation approach before for VaR, we can easily isolate the worst five observations using PROC IML. Inside of this PROC we can calculate the mean of the worst five observations.

proc iml;

use SimRisk.stocks_s var {msft_r aapl_r}; 
read all var _all_ into returns;

portfolio_return = &msft_position*returns[,1] + &aapl_position*returns[,2];

call sort(portfolio_return,{1});
number_of_observations = nrow(portfolio_return);

VaR_historical = portfolio_return[6,1];

ES = sum(portfolio_return[1:6,1])/(6-1);
print "Daily CVaR/ES (Percentile level: &var_percentile level); Historical" ES[format=dollar15.2];


title;
quit;
ES
Daily CVaR/ES (Percentile level: 0.01 level); Historical $-28,212.32

Again, this value is saying that if the worst 1% of cases happens, we expect to lose $28,212.32 on average.

Simulation

Simulation is just an extension of what we did earlier to calculate the VaR. First, follow the steps described earlier to create the 10,000 simulated, sorted, portfolio values for the VaR calculation. Then simply just take the average of all the values that are worst than the VaR. For 10,000 simulations, the ES would be the average of the worst 100 observations.

Let’s see how to do this in each of our softwares!

R

Just as with simulation in R, we can easily get the final distribution for our portfolio changes, called value.change, and just isolate the worst observations through boolean logic. We just take the mean function of all the observations for value.change that are lower than the VaR value.

ES <- mean(value.change[value.change < VaR], na.rm=TRUE)
dollar(ES)
[1] "-$16,320.06"
h <- hist(value.change/1000, breaks=50, plot=FALSE)
cuts <- cut(h$breaks, c(-Inf, VaR/1000, Inf))
plot(h, col = cuts, main='1 Day Value Change Distribution', xlab='Value Change')
breaks = c(-20, -10, 0, 10, 20, 30)
axis(1, at = breaks, labels = paste("$", breaks, "K", sep = ""))
abline(v = VaR/1000, col="red", lwd=2)
mtext(paste("Value at Risk",VaR.label, sep=" = "), at=VaR/1000, col="red")

Again, this value is saying that if the worst 1% of cases happens, we expect to lose $16,041.57 on average. This would be the average in the dark shaded tail region in the histogram above.

SAS

Just as with simulation in SAS, we can easily get the final distribution for our portfolio changes, called value_change in our mc_stocks dataset, and just isolate the worst observations through the WHERE statement in PROC MEANS. This will apply the mean of all the observations for value_change that are lower than the VaR value.

proc print data=percentiles;
run;

data _null_;
    set percentiles;
    call symput("var_p",P1);
run;

proc means data=mc_stocks mean;
    var value_change;
    where value_change < &var_p;
run;
Obs P1
1 -14594.31



Analysis Variable
: value_change
Mean
-16807.32

Again, this value is saying that if the worst 1% of cases happens, we expect to lose $16,921.19 on average.

Recent Developments

The field of risk management is ever changing and growing quickly. The following couple of sections outline some of the latest additions to the field of risk management - extreme value theory (EVT) and newer VaR calculations.

Extreme Value Theory

There are some complications to the expected shortfall calculation. First, ES estimates tend to be less stable than the VaR for the same confidence level due to sample size limitations. ES requires a large number of observations to generate a reliable estimate. Due to this, ES is also more sensitive to estimation errors than VaR because is substantially depends on the accuracy of the tail model used in the distribution.

We try so hard to estimate the full distribution. However, our only care is the tail of the distribution so we will turn our attention on just estimating the tail. This is the value of extreme value theory (EVT). EVT provides the theoretical foundation for building statistical models describing extreme events. This is used in many fields such as finance, structual engineering, traffic prediction, weather prediction, and geological prediction.

EVT provides the distribution for the following two things:

  • Block Maxima (Minima) - the maximum (or minimum) the variable takes in successive periods.

  • Exceedances - the values that exceed a certain threshold.

For VaR and ES calculations we will focus on the exceedances piece of EVT. The approach of exceedances tries to understand the distribution of values that exceed a certain threshold. Instead of isolating the tail of an overall distribution (limiting the values) we are trying to build a distribution for the tail events themselves.

One of the popular distributions for this is the generalized Pareto. This distribution is named after Italian engineer and economist Vilfredo Pareto. It came into popularity with the “Pareto Principle” which is more commonly known as the “80-20” Rule. Pareto noted in 1896 that 80% of the land of Italy was owned by 20% of the population. Richard Koch authored the book The 80/20 Principle to illustrate some common applications. The plot below shows some example Pareto distributions:

Pareto Distribution Examples

This can be applied to value at risk and expected shortfall to provide more accurate estimates of VaR and ES, but the math is very complicated. We need to use maximum likelihood estimation to find which generalized Pareto distribution fits our data the best - which parameters \(\xi\) and \(\beta\) are optimal to maximize:

\[ f(v) = \sum_{i=1}^{n_u} \log(\frac{1}{\beta} (1 + \frac{\xi(v_i - u)}{\beta})^{\frac{-1}{\xi-1}} ) \]

The calculation for VaR from the Pareto distribution is:

\[ VaR = u + \frac{\beta}{\xi}([\frac{n}{n_u} (1-q)]^{-\xi}) \]

The calculation of ES from the Pareto distribution is:

\[ ES = \frac{VaR + \beta - \xi u}{1-\xi} \]

Let’s walk through the approach for our two position portfolio. If we have $200,000 invested in Microsoft and $100,000 invested in Apple, we can use the 500 observations for each stocks’ returns to estimate the generalized Pareto distribution parameters. Assume a normal distribution for each of these stocks returns with their historical mean and standard deviation. From there we can just estimate the VaR and ES from the above equations.

Let’s see how to this in each of our softwares!

R

To get the estimated parameters from the Pareto distribution we can use the gpdFit function. The first input is the data itself (careful, the function requires positive values) and the second input input is the type = c("mle") option to specify using maximum likelihood estimation to estimate the parameters. From there we use the tailRisk function to estimate the VaR and ES from the output of the gpdFit function.

pareto.fit <-gpdFit(as.numeric(stocks$port_v[-1])*-1, type = c("mle"))
tailRisk(pareto.fit, prob = 0.99)
    Prob      VaR       ES
95% 0.99 19419.31 27720.33
dollar(tailRisk(pareto.fit, prob = 0.99)[,2]*-1)
[1] "-$19,419.31"
dollar(tailRisk(pareto.fit, prob = 0.99)[,3]*-1)
[1] "-$27,720.33"

We can see the values from the Pareto estimation above. To compare this to the normal distribution, the following plot shows the estimated distribution (in the histogram) of the Pareto distribution compared to the theoretical normal distribution (the density line) for the same data.

hist(-1*rgpd(n = 10000, mu = pareto.fit@parameter$u, beta = pareto.fit@fit$par.ests[2], xi = pareto.fit@fit$par.ests[1]), breaks = 50, main = "Comparison of Simulated tail to Normal", xlab = "Portfolio Value", freq = FALSE, yaxt = "n", ylab = "", col = "lightblue")
curve(dnorm(x, mean(stocks$port_v, na.rm = TRUE), sd(stocks$port_v, na.rm = TRUE)), add = TRUE, col = 'red', lwd = 2)

As we can see above, the data estimates a distribution with a much thicker tail than the normal distribution would otherwise account for. This aligns with the historical simulation approach that had a much riskier value for VaR and ES compared to the Delta-Normal approach. All of the approaches are compared in the table below:

Comparison of VaR and ES Across Approaches

SAS

In SAS, we first need to isolate the tail fo the data to fit the Pareto distribution with. SAS requires that the data values are all positive so we convert our negative values to positive using the DATA step and multiplying our values by -1. Next, we use PROC UNIVARIATE to calculate the percentiles of our data. We want to isolate the 5% tail to build our Pareto distribution off of. We specify the variable of interest, neg_port_v, in our VAR statement. We then use the OUTPUT statement to save the percentiles into a new dataset called percentiles by using the pctlpts = 95 and pctlpre = P options we have defined before. Next, we use another DATA step to create a MACRO variable for the value of the 5% quantile of interest (remember we are working with the 95% instead of 5% because we flipped all of our values when taking the negative). We then use a last DATA step to delete all the data values not in the tail of interest.

%let var_percentile=0.01;

data neg_stocks;
    set SimRisk.stocks;
    neg_port_v = -1*port_v;
run;

proc univariate data=neg_stocks;
    var neg_port_v;
    output out=percentiles pctlpts = 95 pctlpre=P;
  ods select Quantiles;
run;

proc print data=percentiles;
run;

data _null_;
    set percentiles;
    call symput("tail",P95);
run;

data stocks_tail;
    set neg_stocks;
    if neg_port_v <= &tail then delete;
run;
Variable: neg_port_v

Quantiles (Definition 5)
Level Quantile
100% Max 45661.487
99% 21134.514
95% 9002.725
90% 6101.344
75% Q3 1908.307
50% Median -821.581
25% Q1 -3565.546
10% -5890.933
5% -8902.751
1% -20184.071
0% Min -37901.543



Obs P95
1 9002.73

Now we can use PROC UNIVARIATE to fit our data to the Pareto distribution. To do this we use the HISTOGRAM statement on our variable neg_port_v with the pareto(theta=&tail percent=80) option. This will fit the parameters of the Pareto distribution to our dataset. We can output these parameters using the ODS OUTPUT statements. The output from PROC UNIVARIATE provides the parameter estimates for the Pareto distribution as well as the estimate of our quantile of interest, the VaR. We save this VaR as a MACRO variable and print it out using PROC IML.

proc univariate data=stocks_tail;
    histogram neg_port_v / pareto(theta=&tail percent=80);
    ods output ParameterEstimates=PE FitQuantiles=FQ;
    ods select histogram ParameterEstimates FitQuantiles;
run;

data _null_;
    set PE;
    if upcase(Symbol) eq 'THETA' then do;
        call symput("threshold",Estimate);
    end;
    if upcase(Symbol) eq 'SIGMA' then do;
        call symput("beta",Estimate);
    end;
    if upcase(Symbol) eq 'ALPHA' then do;
        call symput("xi",Estimate);
    end;
run;

data _null_;
    set FQ;
    call symput("VaR",EstQuantile);
run;

proc iml;
title 'EVT Results';

VaR_EVT = &VaR*-1;

print "Daily VaR (Percentile level: &var_percentile); EVT" VaR_EVT[format=dollar15.2];

quit;

Histogram for neg_port_v




Fitted Pareto Distribution for neg_port_v

Parameters for Pareto Distribution
Parameter Symbol Estimate
Threshold Theta 9002.725
Scale Sigma 5984.027
Shape Alpha -0.12531
Mean 15844.01
Std Dev 7902.856

Quantiles for Pareto Distribution
Percent Quantile
Observed Estimated
80.0 21134.5 19673.5



EVT Results

VaR_EVT
Daily VaR (Percentile level: 0.01); EVT $-19,673.50

Lastly, we use one final PROC IML call to calculate the ES using the equation defined above.

proc iml;
title 'EVT Results';

VaR_EVT = &VaR*-1;
ES_EVT = ((&VaR + &beta - &xi*&threshold)/(1-&xi))*-1;

print "Daily CVaR/ES (Percentile level: &var_percentile); EVT" ES_EVT[format=dollar15.2];

quit;
EVT Results

ES_EVT
Daily CVaR/ES (Percentile level: 0.01); EVT $-23,802.97

These values align with the historical simulation approach that had a much riskier value for VaR and ES compared to the Delta-Normal approach. All of the approaches are compared in the table below:

Comparison of VaR and ES Across Approaches

VaR Extensions

The last section just briefly touches on some of the latest variations and adaptions of the value at risk metric. There are many additions to VaR calculations:

  • Delta-Gamma VaR
  • Delta-Gamma Monte Carlo Simulation
  • Marginal VaR
  • Incremental VaR
  • Component VaR

Let’s discuss each briefly in concept.

Delta-Gamma VaR

The Delta-Gamma approximation approach tries to improve on the Delta-Normal approach by taking into account higher derivatives than the first derivative only. In the expansion of the derivatives we can look at the first two:

\[ dV = \frac{\partial V}{\partial RF}\cdot dRF + \frac{1}{2}\cdot \frac{\partial^2 V}{\partial RF^2}\cdot dRF^2 + \cdots \]

\[ dV = \Delta \cdot dRF + \frac{1}{2} \cdot \Gamma \cdot dRF^2 \]

Essentially, this approach takes the variance component into account in building the Gamma portion of the equation. Delta-Normal typically underestimates VaR when assumptions do not hold. The Delta-Gamma approach tries to correct for this, but it is computationally more intensive.

Delta-Gamma Monte Carlo

The assumption of normality still might not be reliable even with the Delta-Gamma adjustment to Delta-Normal. The Delta-Gamma MC simulation approach simulates the risk factor before using Taylor-series expansion to create simulated movements in the portfolio’s value. Just like with regular simulation, the VaR is calculated using the simulated distribution of the portfolio.

For a comparison, if you have a large number of things to evaluate in a portfolio with few options, the Delta-Normal approach is fast and efficient enough. However, if you have only a few sources of risk and substantial complexity, the Delta-Gamma approach is better. If you have both a large number of risk factors and substantial complexity, simulation is probably the best approach.

Marginal VaR

The marginal VaR tries to answer the question of how much the VaR will change if we invest one more dollar in a position of the portfolio. In other words, the first derivative of VaR with respect to the weight of a certain position in the portfolio. Assuming normality, this calculation is quite easy:

\[ \Delta VaR = \alpha \times \frac{Cov(R_i, R_p)}{\sigma_p} \]

Incremental VaR

The incremental VaR tries to measure the change in VaR due to the addition of a new position in the portfolio. This is used whenever an institution wants to evaluate the effect of a proposed trade or change in the portfolio of interest. This is slightly different from the marginal VaR that only takes into account an additional dollar of one position instead of adding or subtracting an entire (or multiple) positions.

This is trickier to calculate as you now need to calculate the VaR under both portfolios and take their difference. There are Taylor series approximations to his, but they are not as accurate as calculating the full VaR for both portfolios and looking at the difference.

Component VaR

The component VaR decomposes the VaR into its basic components ina way that takes into account the diversification of the portfolio. It is a “partition” of the portfolio VaR that indicates the change of VaR if a given component was deleted. The component VaR is defined in terms of the marginal VaR:

\[ VaR_{Comp} = \Delta VaR \times (\$ \; value \; of \; component) \]

The sum of all component VaR’s is the total portfolio VaR.