# Value-at-Risk for Stocks: Historical Simulation

### Lecture Notes by Jakov Ivan S. Dumbrique (jdumbrique@ateneo.edu)

MATH 100.2: Topics in Financial Mathematics II \
First Semester, S.Y. 2021-2022 \
Ateneo de Manila University


```python
import numpy as np # Numerical Computing
import pandas as pd # Data wrangling
```

## Introduction to Historical Simulation

1. The primary basis of the Delta-Normal approach in the computation of the VaR is the assumption that asset price returns (or portfolio returns) are normally distributed.
2. Historical data can also be used to estimate VaR for stock portfolios without assuming a particular parametric distribution for the asset return series. This particular procedure is known as **historical simulation**.

Consider a financial institution with a position of $N$ shares on a stock $E$ with price $S_{0}$ today. Let $S_1$ be the price per share of $E_1$ tomorrow.

Let $R_1 = \ln(S_1/S_0)$ be the continuously compounded return on the asset observed tomorrow.
For sufficiently small $R_1$, we assume that $$\Delta P = P_1-P_0 = N(S_1-S_0) \approx N S_0 R_1.$$

In historical simulation, it is also assumed that $R_1$ is a random variable whose values consist of the one-day asset returns observed historically. However, unlike in Delta-Normal Approach, we don't assume $R_1$ to be normally distributed.

###  Step 1: Generate historical one-day returns $\{R_{1,j}\}$
Consider the time series $\{S_{-t}\}$, $t=0,1,2,\dots,M$, where $S_{-t}$ indicates the stock price $t$ trading days ago and $M+1$ is the length of the time series.

Define
\begin{equation}
R_{1,j} = \ln\left(\frac{S_{-j}}{S_{-(j+1)}}\right), j=0,1,\dots,M-1
\end{equation}
and so the series $\{R_{1,j}\}$ contains all possible values of the random variable $R_1$, with $R_{1,j}$ representing the $j$th scenario for $R_1$.

<h3 style='color:green'> Example on Single-Asset Portfolio</h3> 
Today is February 23, 2018. You are a portfolio risk manager who is assigned to analyze the market risk of a portfolio of 700 PLDT (TEL) shares. Determine the portfolio's one-day 99% VaR using historical simulation approach.
 



```python
TEL_df = pd.read_csv("https://raw.githubusercontent.com/ateneomathdept/math100.2_2021Sem1/main/data/lectures/TEL_2018.csv")
TEL_df
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>dt</th>
      <th>close</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>2/23/18</td>
      <td>1488.74</td>
    </tr>
    <tr>
      <th>1</th>
      <td>2/22/18</td>
      <td>1510.86</td>
    </tr>
    <tr>
      <th>2</th>
      <td>2/21/18</td>
      <td>1513.72</td>
    </tr>
    <tr>
      <th>3</th>
      <td>2/20/18</td>
      <td>1536.65</td>
    </tr>
    <tr>
      <th>4</th>
      <td>2/16/18</td>
      <td>1476.37</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>243</th>
      <td>3/2/17</td>
      <td>1430.29</td>
    </tr>
    <tr>
      <th>244</th>
      <td>3/1/17</td>
      <td>1408.94</td>
    </tr>
    <tr>
      <th>245</th>
      <td>2/28/17</td>
      <td>1394.35</td>
    </tr>
    <tr>
      <th>246</th>
      <td>2/27/17</td>
      <td>1374.93</td>
    </tr>
    <tr>
      <th>247</th>
      <td>2/24/17</td>
      <td>1367.68</td>
    </tr>
  </tbody>
</table>
<p>248 rows × 2 columns</p>
</div>




```python
def get_return(df, d):
    """
    df is the original df
    
    appends returns series to df
    """
    df["previous"] = df["close"].shift(-d)
    df["return"] = np.log(df["close"]/df["previous"])
    return df 
```


```python
TEL_df = get_return(TEL_df, d=1)
TEL_df
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>dt</th>
      <th>close</th>
      <th>previous</th>
      <th>return</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>2/23/18</td>
      <td>1488.74</td>
      <td>1510.86</td>
      <td>-0.014749</td>
    </tr>
    <tr>
      <th>1</th>
      <td>2/22/18</td>
      <td>1510.86</td>
      <td>1513.72</td>
      <td>-0.001891</td>
    </tr>
    <tr>
      <th>2</th>
      <td>2/21/18</td>
      <td>1513.72</td>
      <td>1536.65</td>
      <td>-0.015035</td>
    </tr>
    <tr>
      <th>3</th>
      <td>2/20/18</td>
      <td>1536.65</td>
      <td>1476.37</td>
      <td>0.040018</td>
    </tr>
    <tr>
      <th>4</th>
      <td>2/16/18</td>
      <td>1476.37</td>
      <td>1475.71</td>
      <td>0.000447</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>243</th>
      <td>3/2/17</td>
      <td>1430.29</td>
      <td>1408.94</td>
      <td>0.015040</td>
    </tr>
    <tr>
      <th>244</th>
      <td>3/1/17</td>
      <td>1408.94</td>
      <td>1394.35</td>
      <td>0.010409</td>
    </tr>
    <tr>
      <th>245</th>
      <td>2/28/17</td>
      <td>1394.35</td>
      <td>1374.93</td>
      <td>0.014026</td>
    </tr>
    <tr>
      <th>246</th>
      <td>2/27/17</td>
      <td>1374.93</td>
      <td>1367.68</td>
      <td>0.005287</td>
    </tr>
    <tr>
      <th>247</th>
      <td>2/24/17</td>
      <td>1367.68</td>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
  </tbody>
</table>
<p>248 rows × 4 columns</p>
</div>



### Step 2: Get historical changes in portfolio values $\{\Delta P_j\}$
In scenario $j$, the stock price tomorrow is approximated as
\begin{equation}
S_{1,j} = S_0 e^{R_{1,j}}.
\end{equation}

Consequently, the change in portfolio value under scenario $j$ is given by the approximation
\begin{equation}
\Delta P_j = N (S_{1,j}-S_0) \approx NS_0 R_{1,j}.
\end{equation}

Like the random variable $R_1$, $\Delta P$ can be represented as a random variable with $M$ possible scenarios denoted by $\{\Delta P_j\}$.



```python
def get_change_in_value_df(df, N):
    """
    df is the output of get_returns_df 
    
    appends change in portfolio value series to df
    """
    S0 = df.loc[0, "close"]
    df["change_in_value"] = N * S0 * df["return"]
    return df
```


```python
TEL_df = get_change_in_value_df(TEL_df, N=700)
TEL_df
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>dt</th>
      <th>close</th>
      <th>previous</th>
      <th>return</th>
      <th>change_in_value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>2/23/18</td>
      <td>1488.74</td>
      <td>1510.86</td>
      <td>-0.014749</td>
      <td>-15370.094698</td>
    </tr>
    <tr>
      <th>1</th>
      <td>2/22/18</td>
      <td>1510.86</td>
      <td>1513.72</td>
      <td>-0.001891</td>
      <td>-1970.824622</td>
    </tr>
    <tr>
      <th>2</th>
      <td>2/21/18</td>
      <td>1513.72</td>
      <td>1536.65</td>
      <td>-0.015035</td>
      <td>-15667.749059</td>
    </tr>
    <tr>
      <th>3</th>
      <td>2/20/18</td>
      <td>1536.65</td>
      <td>1476.37</td>
      <td>0.040018</td>
      <td>41703.842890</td>
    </tr>
    <tr>
      <th>4</th>
      <td>2/16/18</td>
      <td>1476.37</td>
      <td>1475.71</td>
      <td>0.000447</td>
      <td>465.975103</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>243</th>
      <td>3/2/17</td>
      <td>1430.29</td>
      <td>1408.94</td>
      <td>0.015040</td>
      <td>15673.009003</td>
    </tr>
    <tr>
      <th>244</th>
      <td>3/1/17</td>
      <td>1408.94</td>
      <td>1394.35</td>
      <td>0.010409</td>
      <td>10847.710303</td>
    </tr>
    <tr>
      <th>245</th>
      <td>2/28/17</td>
      <td>1394.35</td>
      <td>1374.93</td>
      <td>0.014026</td>
      <td>14616.263663</td>
    </tr>
    <tr>
      <th>246</th>
      <td>2/27/17</td>
      <td>1374.93</td>
      <td>1367.68</td>
      <td>0.005287</td>
      <td>5509.622658</td>
    </tr>
    <tr>
      <th>247</th>
      <td>2/24/17</td>
      <td>1367.68</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
  </tbody>
</table>
<p>248 rows × 5 columns</p>
</div>



### Step 3: Get the (1-alpha)th percentile of the ordered array of historical changes in portfolio values
 
The one-day 99\% VaR of the portfolio thus corresponds to the scenario $j^*$, given by $\Delta P_{j^*}$, in the 1st percentile of the scenario space $\{\Delta P_j\}$. 

$\Delta P_{j^*}$ represents the worst possible movement in portfolio value with probability 99\%. 

If the $\Delta P_j$s are arranged in ascending order, the one-day 99\% VaR for the portfolio is the $\lfloor 0.01M \rfloor$th smallest value in the array.



```python
M = len(TEL_df)-1
M
```




    247




```python
0.01*M
```




    2.47




```python
k = int(np.floor(0.01*M))
k
```




    2




```python
TEL_df["change_in_value"]
```




    0     -15370.094698
    1      -1970.824622
    2     -15667.749059
    3      41703.842890
    4        465.975103
               ...     
    243    15673.009003
    244    10847.710303
    245    14616.263663
    246     5509.622658
    247             NaN
    Name: change_in_value, Length: 248, dtype: float64




```python
var = abs(TEL_df["change_in_value"].sort_values(ignore_index=True)[k-1])
var
```




    60730.66451735293




```python
def get_kth_percentile_discrete(df, d, alpha):
    """
    this returns the (1-alpha)th percentile of the ordered array of historical changes in portfolio values
    """
    M = len(df)-d
    k = int(np.floor((1-alpha)*M))
    var = abs(df["change_in_value"].sort_values(ignore_index=True)[k-1])
    
    return var
```


```python
get_kth_percentile_discrete(TEL_df, d=1, alpha=0.99)
```




    60730.66451735293




```python
def d_day_alpha_percent_VaR_single_stock_historical(
    df, N, d, alpha
):
    """Returns the d-day 100(alpha)% VaR of a single stock using Historical Simulation Approach.
    
    Parameters
    ----------
    df : pandas.DataFrame
        has two columns: (1) dt [str] and (2) closing price [float]
        assumes the dates are arranged from newest to oldest, and the date today is the date on the first row  
    N : int
        number of shares for the sole stock
    d : int
        the value to be used in calculating the d-day VaR (e.g. 1-day, 5-day)
    alpha : float
        the value to be used in calculting the 100(alpha)% VaR (e.g. 0.99, 0.95)
    
    Returns
    -------
    float (2 decimal places)
        d-day 100(alpha)% VaR of a single stock using Historical Simulation Approach
    """
    
    # step 1: generate your historical returns
    df = get_return(df, d)
    # Step 2: get your historical changes in portfolio values
    df = get_change_in_value_df(df, N)
    # Step 3: get the (1-p/100)th percentile of the ordered array of historical changes in portfolio values
    var = get_kth_percentile_discrete(df, d, alpha)
    
    return round(var, 2)
```


```python
TEL_df = pd.read_csv("https://raw.githubusercontent.com/ateneomathdept/math100.2_2021Sem1/main/data/lectures/TEL_2018.csv")
TEL_df
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>dt</th>
      <th>close</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>2/23/18</td>
      <td>1488.74</td>
    </tr>
    <tr>
      <th>1</th>
      <td>2/22/18</td>
      <td>1510.86</td>
    </tr>
    <tr>
      <th>2</th>
      <td>2/21/18</td>
      <td>1513.72</td>
    </tr>
    <tr>
      <th>3</th>
      <td>2/20/18</td>
      <td>1536.65</td>
    </tr>
    <tr>
      <th>4</th>
      <td>2/16/18</td>
      <td>1476.37</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>243</th>
      <td>3/2/17</td>
      <td>1430.29</td>
    </tr>
    <tr>
      <th>244</th>
      <td>3/1/17</td>
      <td>1408.94</td>
    </tr>
    <tr>
      <th>245</th>
      <td>2/28/17</td>
      <td>1394.35</td>
    </tr>
    <tr>
      <th>246</th>
      <td>2/27/17</td>
      <td>1374.93</td>
    </tr>
    <tr>
      <th>247</th>
      <td>2/24/17</td>
      <td>1367.68</td>
    </tr>
  </tbody>
</table>
<p>248 rows × 2 columns</p>
</div>




```python
d_day_alpha_percent_VaR_single_stock_historical(df=TEL_df, N=700, d=1, alpha=0.99)
```




    60730.66



<h3 style='color:green'> Exercise on N-Asset Portfolio</h3> 
Today is February 23, 2018. You are a portfolio risk manager who is assigned to analyze the market risk of a portfolio of 700 PLDT (TEL) shares, 300 Ayala Corporation (AC) shares, and 500 URC shares. What is the portfolio's one-day 99% VaR using historical approach?


```python

```

088da36aab621239889fca7bea2a1cfc0ce877d3
ipynb
Jupyter Notebook
lectures/1Stocks/20210923_VaRforStocks_HistoricalSimulation.ipynb
ateneomathdept/math100.2_2021Sem1
ac51a30e25d57a50ef8aa25fcfc0db64da0641b9
MIT
2021-12-12T04:44:09.000Z
2021-12-12T04:44:09.000Z
lectures/1Stocks/20210923_VaRforStocks_HistoricalSimulation.ipynb
ateneomathdept/math100.2_2021Sem1
ac51a30e25d57a50ef8aa25fcfc0db64da0641b9
MIT
lectures/1Stocks/20210923_VaRforStocks_HistoricalSimulation.ipynb
ateneomathdept/math100.2_2021Sem1
ac51a30e25d57a50ef8aa25fcfc0db64da0641b9
MIT
2021-10-04T04:16:18.000Z
2021-10-04T04:16:18.000Z
Qwen/Qwen-72B
1. YES
2. YES