Ioannis Paraskevopoulos, PhD
VaR is defined as the lowest quantile of the potential losses that can occur within a given portfolio during a specific time period.
The time period $T$ and the confidence level are the two major parameters, which are chosen carefully and are dependent upon the goal of the risk management (regulatory reporting, corporate risk management, etc.).
-Provides just one number that summarizes the total risk of a portfolio.
-Indicates the maximum potencial loss that can generate a given position for a given statistical confidence level and a given time horizon.
Once calculated we can state “ there is a probability $p$% that we will not loose more than $V$ monetary units in the next $T$ days -It tells us “how wrong things can go” -If $T=10$ and $p=99$% we will be calculating the losses over a 10 day period that that will only occur 1 out of 100 times
-The required by regualation capital for market risk operations is 12.5 times the 10 day with 99.9%
$$12.5xVaR_{99.9}$$.
Formally defined, VaR estimates the likelihood that a given portfolio’s losses (L) will exceed a certain amount l.
$$VaR_{\alpha}(L) = Pr(L > l) ≤ 1 − \alpha$$, where $l \in \mathbb{R}$. L is the loss of the portfolio and $\alpha \in [0, 1]$ is the confidence level.
-Imagine that during the last year the daily benefits of a firm are on average 8M euros, but that 5% of the days losses equal or greater than 10M euros were observed. If this is stable the maximum loss that we can observe 5 out of 100 days is 10M euros, thus VaR in absolute terms is 10M euros.
-We can also talk about relative VaR, in terms of relative loss with respect to expected average. In our example relative VaR will be 18M euros.
Assume that our portfolio consists only of one asset. Further we suppose percentiles can be expressed as a function of a dispersion parameters so that the returns of this asset have a bell-shaped normal distribution with annual mean return 10% and standard deviation 30%. If the value of our portfolio is( $V_t$ ) now Eur100m, we would like to answer:
-What’s the value of the portfolio in one year?
import matplotlib.pyplot as plt
%matplotlib inline
from scipy import stats
import numpy as np
# Plot the PDF of our Portfolio V
xmin, xmax = plt.xlim()
x = np.linspace(10, 230, 100)
p = stats.norm.pdf(x, 110, 30)
plt.plot(x, p, 'k', linewidth=2)
title = "Portfolio Value, $V_t$ in a years time"
plt.title(title)
plt.show()
-What is the probability that we suffer a loss?
Since returns are normally distributed around their mean of 10% with volatility 30% we can use the statistical theory and form a normal random variable Z:
$Z=\frac{X-\mu}{\sigma}\Leftrightarrow Z*\sigma+\mu \Rightarrow Pr(X\leq 0)=Pr(Z*\sigma+\mu \leq 0)=Pr(Z\leq -\frac{0.1}{0.3})=Pr(Z \leq -0.333)=N(-0.333)$
import scipy.stats
scipy.stats.norm(0.1, 0.3).pdf(-0.333)
import numpy
import scipy.stats
import datetime
import matplotlib.pyplot as plt
from pandas.io.data import DataReader, DataFrame
%matplotlib inline
We get yahoo data to play with
start = datetime.datetime(2005, 1, 1)
end   = datetime.datetime(2015, 11, 2)
AAPL = DataReader("AAPL", "yahoo", start, end)
SP = DataReader("^GSPC", "yahoo", start, end)
df = DataFrame({ 'AAPL': AAPL["Adj Close"].pct_change(),
                 'SP': SP["Close"].pct_change()})
dfna = df.dropna()
Lets do some plotting on levels
AAPL.plot(y="Adj Close")
plt.title(u"Apple 2015", weight='bold');
We plot the returns
plt.plot(dfna["AAPL"],'b.',alpha=0.5) #chose the color of line: 'b.'=blue, for red is 'r.'
plt.title(u"Apple daily returns period 2005-2015", weight='bold');
# plotting (figure #1)
#  return-series for Apple and S&P index
#
plt.figure(num=2, figsize=(10, 6))
plt.subplot(211)
plt.grid(True)
plt.plot(dfna["AAPL"], '-r', label="Apple")
plt.axis("tight")
plt.ylim([-0.25,0.3])
plt.legend(loc="upper right")
plt.ylabel("Apple daily returns")
plt.subplot(212)
plt.grid(True)
plt.plot(dfna["SP"], '-', label="S&P")
plt.legend(loc="upper right")
plt.axis("tight")
plt.ylim([-0.10,0.15])
plt.ylabel("S&P daily returns")
plt.xlabel("Trading days 13/05/2005-12/11/2015")
plt.show()
we can get immediattely the quantile we want from Apple returns
dfna["AAPL"].quantile(0.05) #see the returns in 0.05 empirical quantile
Lets see the histogram of Apple returns
returns = dfna["AAPL"]
returns.hist(bins=30, normed=True, histtype='stepfilled', alpha=0.5)
support = numpy.linspace(returns.min(), returns.max(), 100)
tdf, tmean, tsigma = scipy.stats.t.fit(returns.as_matrix())
print("Apple t fit: mean={}, scale={}, df={}".format(tmean, tsigma, tdf))
plt.plot(support, scipy.stats.t.pdf(support, loc=tmean, scale=tsigma, df=tdf), "r-")
plt.figtext(0.6, 0.7, u"t$\mu$ = {:.3}".format(tmean))
plt.figtext(0.6, 0.65, u"t$\sigma$ = %3f" % tsigma)
plt.figtext(0.6, 0.6, u"df = %3f" % tdf)
plt.title(u"Histogram of Apple daily returns over 2005–2015", weight='bold');
#Variance Covariance of Dailly VaR
import datetime
import numpy as np
import pandas.io.data as web
from scipy.stats import norm
def var_cov_var(P, c, mu, sigma):
    """
    Variance-Covariance calculation of daily Value-at-Risk
    using confidence level c, with mean of returns mu
    and standard deviation of returns sigma, on a portfolio
    of value P.
    """
    phiInv = norm.ppf(1-c, mu, sigma)
    return P - P*(phiInv + 1)  #daily VaR
if __name__ == "__main__":
    start = datetime.datetime(2010, 1, 1)
    end = datetime.datetime(2015, 11,2 )
    citi = web.DataReader("AAL", 'yahoo', start, end) #get yahoo data
    citi["rets"] = citi["Adj Close"].pct_change() #Create Returns of citi
    P = 1e6   # 1,000,000 USD
    c = 0.99  # 99% confidence interval
    mu = np.mean(citi["rets"]) #mean returns
    sigma = np.std(citi["rets"]) #volatility
    var = var_cov_var(P, c, mu, sigma)
    print "Value-at-Risk: $%0.2f" % var
    
    
    print "Value at Risk for dailly movement in Apple and with 99 percent confidence is: $%0.2f" % var
Value at Risk using the historical bootstrap method Method: we calculate empirical quantiles from a histogram of daily returns.
import numpy as np
#returns = np.random.randn(1000)
#Assuming returns are independently and identically distributed (i.i.d.), then the volatility of T days equals to the product of sqrt(T) times one-day-volatility.
# one-way 5% quantile or 95% confidense, critical value is 1.64
VaR_21 = sigma * np.sqrt(21) * 1.645
VaR_21
#Alternatively, you can do bootstraps. 
#That's randomly select 21 days from historical dataset, 
#calculate the return over this randomly drawed 21 days. Plot the histogram and get the 5% quantile.
def generate_random_index(n=21):
    # could set replace to False as well
    return np.random.choice(np.arange(1000), size=n, replace=False)  
VaR_simulated_21 = []
n_bootstrap = 10000
for _ in range(n_bootstrap):
    VaR = dfna["AAPL"][generate_random_index(21)].sum()
    VaR_simulated_21.append(VaR)
plt.hist(VaR_simulated_21)
np.percentile(VaR_simulated_21, q=5)
we move on to plot a histogram
Value at Risk using the historical bootstrap method Method: we calculate empirical quantiles from a histogram of daily returns.
returns.quantile(0.05) #see the returns in 0.05 empirical quantile
The 0.05 empirical quantile of daily returns is at -0.019. That means that with 95% confidence, our worst daily loss will not exceed 1.9%. If we have a 1Meuros investment, our one-day 5% VaR is 1.9 * 1M€ = 19 k€.
 
returns = dfna["SP"]
returns.hist(bins=30, normed=True, histtype='stepfilled', alpha=0.5)
support = numpy.linspace(returns.min(), returns.max(), 100)
tdf, tmean, tsigma = scipy.stats.t.fit(returns.as_matrix())
print("SP t fit: mean={}, scale={}, df={}".format(tmean, tsigma, tdf))
plt.plot(support, scipy.stats.t.pdf(support, loc=tmean, scale=tsigma, df=tdf), "r-")
plt.figtext(0.6, 0.7, u"t$\mu$ = %3f" % tmean)
plt.figtext(0.6, 0.65, u"t$\sigma$ = %3f" % tsigma)
plt.figtext(0.6, 0.6, u"df = %3f" % tdf)
plt.title(u"Histogram of SP daily returns over 2005–2015", weight='bold');
Let's simulate random joint stock returns from a joint distribution of Apple hat and SP hat according to the distribution parameters estimated above, and plot the results. We need these simulated joint returns to do a Monte Carlo VaR analysis of a stock portfolio composed of Apple and SP stock.
runs = 5000
fittedAPL = numpy.zeros(runs, float)
fittedSP = numpy.zeros(runs, float)
for i in range(runs):
    fittedAPL[i] = scipy.stats.t.rvs(loc=0.00139714130016, scale=0.0153600071028, df=3.68016002902)
    fittedSP[i] = scipy.stats.t.rvs(loc=0.00074328426861, scale=0.00656089369387, df=2.29005123591)
plt.plot(fittedAPL, fittedSP, 'r.', alpha=0.5)
plt.title(u"Apple vs SP returns (simulated, no correlation)", weight='bold');
Method: run many trials with random market conditions, calculating portfolio loss for each trial. Use the aggregated trial data to establish a profile of the porfolio's risk characteristics.
Hypothesis: stock market evolution can be simulated by geometric Brownian motion. Start by defining some parameters of the geometric Brownian motion.
The mathematical formula for the price evololution in future is $\frac{\Delta S}{S}=\mu \Delta t + \sigma*N(0,1)$
days = 300   # time horizon
dt = 1/float(days)
sigma = 0.0152 # volatility
mu = 0.01  # drift (average growth rate)
#BS world...generates a path
def random_walk(startprice):
    price = numpy.zeros(days)
    shock = numpy.zeros(days)
    price[0] = startprice
    for i in range(1, days):
        shock[i] = numpy.random.normal(loc=mu * dt, scale=sigma * numpy.sqrt(dt))
        price[i] = max(0, price[i-1] + shock[i] * price[i-1])
    return price
for run in range(10):
    plt.plot(random_walk(121.18))
    plt.xlabel("Time")
plt.ylabel("Price");
Now let's run a big Monte Carlo simulation of random walks of this type, to obtain the probability distribution of the final price, and obtain quantile measures for the Value at Risk estimation.
runs = 10000
simulations = numpy.zeros(runs)
for run in range(runs):
    simulations[run] = random_walk(121.18)[days-1] #Apple price @ 02/11/2015 is 121.18 is the staring price
q = numpy.percentile(simulations, 1)
plt.hist(simulations, normed=True, bins=30, histtype='stepfilled', alpha=0.5)
plt.figtext(0.6, 0.8, u"Start price: 121.18€")
plt.figtext(0.6, 0.7, u"Mean final price: %.3f€" % simulations.mean())
plt.figtext(0.6, 0.6, u"VaR(0.99): %.3f€" % (121.18 - q,))
plt.figtext(0.15, 0.6, u"q(0.99): %.3f€" % q)
plt.axvline(x=q, linewidth=4, color='r')
plt.title(u"Final price distribution after %s days" % days, weight='bold');