Value at Risk: Theory & Practice (in progress)

Beniamino Sartini

15/7/2022

Value at Risk for a Portfolio

Define as \(V_t(\Phi)\) the value at Risk at time t of a portfolio composed by \(N\) assets: \[\Phi = (\Phi_1, \Phi_2, ..., \Phi_N)\]

Considering the conditional distribution \(f_{V_{t+h}|I_t}\) of the value of a portfolio h-steps ahead from current time \(t\), then define the Value at risk with a confidence \(\alpha\) the quantile of the conditional distribution such that the real values should be less than the VAR with a probability \(\alpha\).

  • The \(Var_{t+h}^{\alpha}\) is the forecast based on the available informations that are contained in the information set \(I_t\) at time \(t\) of a pessimistic scenario that can be more pessimistic that \(Var_{t+h}^{\alpha}\) for the period \(t+h\) just with probability \(\alpha\).

Generic Formulas for the VAR

The methodology behind the Value at Risk is based on the fact that we would like to compute the following probability:

\[P(r_{t+h} \underline{<} Var_{t+h|t}^{\alpha})\]

where:

  • \(r_t\) are the returns of our portfolio.
  • \(Var_{t+h|t}\) is the value at risk at time \(t+h\) computed based on the informations up to time \(t\).

Then we standardize dividing by the mean and the standard deviations of \(r_t\):

\[P \biggl(\frac{r_{t+h}- \mu}{\sigma} \underline{<}\frac{Var_{t+h|t}^{\alpha}- \mu}{\sigma} \biggl)\]

Assumption of Normality

Assuming the normality of the returns allow us to write the initial probability as:

\[P \biggl(\frac{r_{t+h}- \mu}{\sigma} \underline{<}\frac{Var_{t+h|t}^{\alpha}- \mu}{\sigma} \biggl) = P \biggl(z_{t+h} \underline{<} q^{\alpha} \biggl) = \alpha\] The RHS is just the quantile of the distribution of \(z \sim N(0,1)\) standardized residuals therefore can be explicited as:

\[Var_{t+h|t}^{\alpha} = \mu + q^{\alpha} \sigma\]

The underline assumptions: \(r_t\) are distributed like a \(N(0,1)\). Under this normality assumption we can easily compute the Var but often this assumption could not be valid an need to be tested case by case. The underline of this assumption is that if we have a series of \(N\) independent and identically distributed observations, with mean \(\mu\) and variance \(\sigma^2\):

\[X_i \, \, \, IID \, \, \, \Rightarrow \, \, \, \frac{\sum_{i=1}^{N} X_i - N \mu }{\sigma} \sim N(0,1)\] Considering the returns of a portfolio is reasonable to think that they are not independent but autocorrelated so this assumption could lead to a bad approximation. This assumption is very popular due to the semplicity of computation of the VAR and also doen not need to make any model on the returns.

Extensions: Models for the Mean and the Variance

If we try to specify a model for the returns considering the conditional mean and the conditional variance it will be such that:

\[Var_{t|t}^{\alpha} = E[r_t|I_{t-1}] + q^{\alpha} V[r_t|I_{t-1}]\] Where we can specify models such as the AR, ARCH or GARCH, in order to have an explicit computation of \(E[r_t|I_{t-1}]\) and \(V[r_t|I_{t-1}]\). In this way we are able to recover \(q^{\alpha}\) from the distribution of the standardized residuals.

Empirical Case: Value at Risk on a Porfolio with Bitcoin

In order to make the example more interesting we will consider 3 portfolios of 10000 dollars with the following compositions:

  • A: a portfolio full bitcoin
  • B:a porfolio 50% bitcoin, 50% cash or equivalents with a 1% annual return.
  • C:a portfolio 50% bitcoin 25% ethereum and 25% cash or equivalents with a 1% annual return.

We will analyze the historical var computed starting from the 2018 till today 15 July 2022.

portfolioA = tibble(
  Date = BTC_daily_price$Date,
  retBTC = ComputeReturns(BTC_daily_price$Adj, perc = TRUE)
)

portfolioB = tibble(
   Date = BTC_daily_price$Date,
  retBTC = ComputeReturns(BTC_daily_price$Adj, perc = TRUE)*0.5,
  retUSD = 0.5*(cumprod(rep(0.01/365+1, nrow(BTC_daily_price)))-1),
  ret = retBTC + retUSD
  
)

portfolioC = tibble(
  Date = BTC_daily_price$Date,
  retBTC = ComputeReturns(BTC_daily_price$Adj, perc = TRUE)*0.5,
  retETH = ComputeReturns(ETH_daily_price$Adj, perc = TRUE)*0.25,
  retUSD = 0.25*(cumprod(rep(0.01/365+1, nrow(BTC_daily_price)))-1),
  ret = retBTC + retETH + retUSD
  
)


Value_at_Risk <- function(x = NULL, alpha = 0.05, na.rm = TRUE){
  
  tibble(
    mean = mean(x, na.rm = na.rm),
    sd = sd(x, na.rm = na.rm), 
    q = qnorm(1-alpha, 0, 1),
    VAR = mean + q * sd,
    respected  = mean(x > -VAR, na.rm = TRUE),
    violations = mean(x < -VAR, na.rm = TRUE),
    testBernulli = (violations - alpha)/(sqrt(alpha*(1-alpha))),
    p.value = 1-pnorm(testBernulli, 0, 1),
    Reject = ifelse(p.value < 0.05, "CLT not Valid", "CLT Valid")
  )
}

historical_var = function(ret = NULL, alpha = 0.01, interval = 1, start = 2){
  
  index = unique(c(seq(start+1, length(ret), interval), length(ret)))

  historic_var = Value_at_Risk(ret[1:start],  alpha = alpha )
  
  for(i in 2:(length(index)-1)){
  
    historic_var = bind_rows(historic_var, Value_at_Risk( ret[1:index[i]], alpha = alpha  ))
  }
  
  historic_var$t = 1:nrow(historic_var)
  
  historic_var
}


VAR_A = historical_var(portfolioA$retBTC, start = 2)

VAR_A$rt = portfolioA$retBTC[-c(1,2,3)]
VAR_A$t = portfolioA$Date[-c(1,2,3)]

ggplot(VAR_A)+
  geom_line(aes(t, -VAR), size = 2)+
  geom_line(aes(t, rt), color = "red")+
  ggthemes::theme_solarized()+
  theme(axis.text.x = element_text(angle = 0, face = "bold", size = 7), 
          axis.text.y = element_text(face = "bold"), 
          axis.title  = element_text(face = "bold"),
          plot.title  = element_text(face = "bold"),
          plot.subtitle = element_text(face = "italic"),
          plot.caption = element_text(face = "italic"),
          panel.grid.major.x = element_line(colour="grey60", linetype="dotted"),
          panel.grid.minor.x = element_blank(),
          panel.grid.major.y = element_line(colour="grey60", linetype="dotted"),
          legend.text = element_text(face = "italic", size = 5),
          legend.title = element_text(face = "bold"),
          legend.position = "top" ) +
  ggtitle("Porfolio A: Full BTC") +
  xlab("")+
  ylab("Return")+
  labs(caption = "July 2022")+
  scale_y_continuous(breaks = seq(-20, 40, 2))

VAR_B = historical_var(portfolioB$ret, start = 2)

VAR_B$rt = portfolioB$ret[-c(1,2,3)]
VAR_A$t = portfolioB$Date[-c(1,2,3)]

ggplot(VAR_B)+
  geom_line(aes(t, -VAR), size = 2)+
  geom_line(aes(t, rt), color = "red")+
  ggthemes::theme_solarized()+
  theme(axis.text.x = element_text(angle = 0, face = "bold", size = 7), 
          axis.text.y = element_text(face = "bold"), 
          axis.title  = element_text(face = "bold"),
          plot.title  = element_text(face = "bold"),
          plot.subtitle = element_text(face = "italic"),
          plot.caption = element_text(face = "italic"),
          panel.grid.major.x = element_line(colour="grey60", linetype="dotted"),
          panel.grid.minor.x = element_blank(),
          panel.grid.major.y = element_line(colour="grey60", linetype="dotted"),
          legend.text = element_text(face = "italic", size = 5),
          legend.title = element_text(face = "bold"),
          legend.position = "top" ) +
  ggtitle("Porfolio B: 50% BTC 50% USD") +
  xlab("")+
  ylab("Return")+
  labs(caption = "July 2022")+
  scale_y_continuous(breaks = seq(-20, 40, 2))

# Port
VAR_C = historical_var(portfolioC$ret, start = 2)

VAR_C$rt = portfolioC$ret[-c(1,2,3)]
VAR_A$t = portfolioC$Date[-c(1,2,3)]

ggplot(VAR_C)+
  geom_line(aes(t, -VAR), size = 2)+
  geom_line(aes(t, rt), color = "red")+
  ggthemes::theme_solarized()+
  theme(axis.text.x = element_text(angle = 0, face = "bold", size = 7), 
          axis.text.y = element_text(face = "bold"), 
          axis.title  = element_text(face = "bold"),
          plot.title  = element_text(face = "bold"),
          plot.subtitle = element_text(face = "italic"),
          plot.caption = element_text(face = "italic"),
          panel.grid.major.x = element_line(colour="grey60", linetype="dotted"),
          panel.grid.minor.x = element_blank(),
          panel.grid.major.y = element_line(colour="grey60", linetype="dotted"),
          legend.text = element_text(face = "italic", size = 5),
          legend.title = element_text(face = "bold"),
          legend.position = "top" ) +
  ggtitle("Porfolio B: 50% BTC 25% USD, 25% ETH") +
  xlab("")+
  ylab("Return")+
  labs(caption = "July 2022")+
  scale_y_continuous(breaks = seq(-20, 40, 2))