Out-of-Sample Two-Day VaR Forecasting with GARCH(1,1)
Summary
The document explains how to forecast a lower-tail, two-day Value at Risk (VaR) from a Gaussian GARCH(1,1) model and how to evaluate the forecasts. Rather than using the fitted, in-sample quantiles as the main backtest, the accepted answer recommends repeatedly estimating the model on a rolling or expanding history, then producing a two-step-ahead volatility forecast. The mean and forecast volatility are combined with the chosen innovation quantile to obtain VaR.
The answer derives the recursive two-step conditional variance from the GARCH parameters and the latest residual and volatility. It also presents a simpler alternative: fit the model to returns sampled every second day and use a one-step forecast on that series. A separate answer stresses that out-of-sample forecasts better represent real use when a model is imperfect, and cautions that overlapping two-day returns reduce the effective number of independent observations. Details such as the return definition, forecast alignment, and backtest method still need careful implementation; the example code alone does not establish forecast accuracy.
Key ideas
- VaR evaluation should use forecasts formed only from data available at each forecast origin.
- A two-step Gaussian GARCH VaR combines the forecast mean, conditional volatility, and the innovation quantile.
- The two-step conditional variance can be calculated recursively from GARCH parameters and the latest state.
- Sampling returns every second day offers an alternative one-step forecasting approach for two-day horizons.
- Overlapping multi-day returns reduce the effective sample size used in backtesting.
Tags
Full text
# 2-day ahead prediction of value at risk with GARCH(1,1) in R
# 2-day ahead prediction of value at risk with GARCH(1,1) in R
Let's say I have a 10 year dataset of Tesla (example) and I am taking the percentage change of lag 2:
```
tsla <- quantmod::getSymbols("TSLA", from = base::as.Date("2011-01-01"), to = base::as.Date("2022-01-31"), auto.assign = F)
tsla = as_tibble(tsla)
head(tsla)
d = tsla%>%
dplyr::select(TSLA.Adjusted)%>%
dplyr::mutate(Close = TSLA.Adjusted)%>%
dplyr::mutate(y = as.numeric((Close - dplyr::lag(Close, 2)) / Close))%>%
dplyr::select(Close,y)%>%
tidyr::drop_na();d
```
That look like this:
```
# A tibble: 2,786 × 2
Close y
<dbl> <dbl>
1 5.37 0.00783
2 5.58 0.0434
3 5.65 0.0499
4 5.69 0.0200
5 5.39 -0.0475
6 5.39 -0.0553
7 5.24 -0.0282
8 5.15 -0.0470
9 5.13 -0.0226
10 4.81 -0.0716
# … with 2,776 more rows
```
Now I want to fit the GARCH(1,1) model with normal innovations.
```
garnor1 = function(x){
require(fGarch)
t = length(x)
fit = garchFit(~garch(1,1),data=x,trace=F,cond.dist="norm")
m = fit@fitted
cv = fit@sigma.t
var = m+cv*qnorm(0.01) # low tail
return(var[t])
}
```
What I have succeeded is that I can estimate the the lower value at risk for 2-day returns up to time $t$. This will give a number that is the VaR up until now (say today). Am I right until now?
If yes, I know that the VaR is being calculated from the predictive function for the $t+2$ quantile value. Doing so I have to predict the above function:
```
g11pre = function(x){
require(fGarch)
fit = garchFit(~garch(1,1),data=x,trace=F,cond.dist="norm")
df=coef(fit)["shape"]
p = predict(fit,2)
m=p$meanForecast
cv=p$standardDeviation
var=m+cv*qnorm(0.01)
return(var[2])
}
```
And this last predictive function I have to backtest or the previous one?
Edit
For the backtesting in the predictive function I tried something by my own.(in order to fully understand it):
```
db= d%>%
dplyr::mutate(back_lower = zoo::rollapplyr(y,252,FUN = g11pre,by = 21,fill=NA))%>%
tidyr::fill(back_lower)%>%
tidyr::drop_na()
```
I know it looks strange.Let me explain.I am using the full 10 year dataset.The period of estimation are the first 252 days and then roll by one month (21) days.I am not interested on by 2 day assess-roll the model. Plotting the backtesting result:
```
p = ggplot() +
geom_line(data = db, aes(x =1:length(y) , y = y), color = "black") +
geom_line(data = db, aes(x = 1:length(back_lower), y = back_lower), color = "red") +
xlab('') +
ylab('risk low')
```
That looks like a step graph (this what It must look like)
## Answer by Pleb (score 1, accepted)
https://quant.stackexchange.com/a/70187
In general, forecasting Value at Risk (VaR) following a parametric GARCH framework follows standard practices of univariate (point) forecasting. Moreover, we are always interested in the accuracy of a VaR model based on the out-of-sample forecast performance.
## Forecasting 2-day ahead Out-of-sample Value at Risk:
Assume that we are standing at time $t$ with information $\mathcal{F}_t$, then for a constant mean model $\mu$, we can define a univariate GARCH(1,1) framework for a return process $r_{t+1}$ as:
\begin{align*} r_{t+1} \vert \mathcal{F}_{t} &= \mu + \varepsilon_{t+1}\\ \varepsilon_{t+1} &= \sigma_{t+1} \cdot z_{t+1}\\ \sigma^2_{t+1} &= \omega + \alpha_1 \varepsilon_{t}^2 + \beta_1 \sigma_{t}^2, \end{align*} where $z_t \overset{iid}{\sim} D(0,1)$ (which in your case is the Gaussian distribution). It is the standardized distribution of the innovations, $z_t$, that determines the quantile in the forthcoming parametric VaR equation. Then the VaR at time $t+1$ given the filtration $\mathcal{F}_t$ can be defined as (equivalent to the 1-step ahead VaR):
$$ VaR_{t+1\vert t}^\alpha = \mu + \sigma_{t+1\vert t}\cdot\Phi^{-1}_\alpha\left(0,1\right) $$ Note that in some cases we negate the above calculation, in order to get positive VaR estimates. This makes sense when taking about losses in notional amount. Nevertheless the 2-step ahead VaR forecast can be obtained via a recursive forecasting scheme:
$$ VaR_{t:t+2\vert t}^\alpha = \mu + \sigma_{t:t+2\vert t}\cdot\Phi^{-1}_\alpha\left(0,1\right), \tag{1} $$ where we observe that the only forecastable object in the Gaussian VaR framework is the conditional volatility process. Note that the 2-step ahead conditional volatility forecast, $\sigma_{t:t+2\vert t}$, is recovered by utilizing the prediction at time $t+1$. Using the fact that the multistep recursive forecast for the GARCH(1,1) is given by (see this link p. 449):
$$ \mathbb{E}\left[\sigma_{t+h}^2 \vert \mathcal{F}_t\right] = \sum_{i=0}^{h-1} (\alpha_1 + \beta_1)^i \cdot \omega + (\alpha_1+\beta_1)^{h-1}(\alpha_1 \varepsilon_t^2+\beta_1 \sigma^2_t) $$
we get for $t+2$:
\begin{align*} \sigma^2_{t:t+2\vert t}&:=\mathbb{E}\left[\sigma_{t+2}^2 \vert \mathcal{F}_t\right] \\ &= \omega + (\alpha_1 + \beta_1) \mathbb{E}\left[\sigma_{t+1}^2\vert \mathcal{F}_t\right]\\ &= \omega + (\alpha_1+\beta_1)\omega + (\alpha_1+\beta_1) \alpha_1 \varepsilon_t^2 + (\alpha_1+\beta_1) \beta_1 \sigma_t^2. \end{align*} Inserting this in $(1)$ yield the 2-step ahead VaR forecast/prediction in the GARCH(1,1) framework. Now you can do the following recursive procedure to acquire your forecasts:
- Fit the GARCH(1,1) model via a rolling or expanding window,
- get estimates $(\hat{\omega},\hat{\alpha}_1, \hat{\beta}_1, \hat{\mu})$ at each time point $t$,
- calculate the 2-step ahead VaR forecast, $VaR_{t:t+2\vert t}^\alpha $.
### Alternative approach:
Instead of the above methodology, you could fit the GARCH(1,1) model on sparse sampled returns which are sampled every second day, ie. $\{r_t,r_{t+2},r_{t+4},\ldots\}$.
This will yield conditional volatilities every second day. Then the 1-step ahead VaR forecast,$VaR_{t+1\vert t}^\alpha$, defined in $(1)$ gives you a VaR estimate for the next 2 days.
This methodology is easy to implement as you can follow most literature on how they define the 1-step ahead forecast without the need of additional derivations. For this matter, you can get some inspiration from the `R` code provided here (however, they only estimate VaR in-sample, not out-of-sample).
If you want to specify a time-varying mean model $\mu_t$, then you also need the 2-step ahead conditional forecast of $\mu_{t+2\vert t}$ in order to recover your VaR forecasts. These can very often get recovered using a similar recursive scheme. I hope this provide some insight.
## Answer by Richard Hardy (score 0)
https://quant.stackexchange.com/a/70186
Your question seems to be whether to evaluate/backtest in-sample VaRs or out-of-sample VaRs. I presume you want to get a sense of your model's anticipated performance on unseen future data. If your model was exactly correct, both ways would be fine. However, in reality models are not exactly correct. Then out-of-sample VaRs are the relevant ones, as they (unlike the in-sample VaRs) mimic how you will be using your model.
Just note that if your 2-day periods overlap, your effective sample size is half of what the nominal sample size is. (I cannot tell from your code whether you only look at every second day or at every day. It is in the latter case that the neighboring 2-day returns will overlap.)Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.