GARCH External Regressors and Nonnegativity Constraints in rugarch
Summary
The document investigates why a GARCH(1,1) fit differs from a variance model that replaces its lagged squared-return term with an external regressor. The example uses daily equity returns and compares fitted coefficients from the two specifications. The reported estimates do not match, despite the intended equivalence between the models.
The accepted explanation is that rugarch applies nonnegativity bounds to coefficients by default. That restriction also affects the external-regressor coefficient, even though reproducing the usual GARCH specification may require allowing it to take negative values during optimization. The author reports that setting explicit bounds on the regressor coefficient resolves the discrepancy. This is a software-specific estimation detail, and the explanation offered for why optimization needs negative interim estimates is tentative. The example provides no broader comparison across data sets or package versions.
Key ideas
- The example compares a GARCH(1,1) model with a GARCH model using lagged squared returns as an external regressor.
- The fitted coefficients differ under the default settings.
- The accepted answer attributes the discrepancy to nonnegativity bounds on the external-regressor coefficient.
- Explicit coefficient bounds that allow negative values are reported to restore the expected fit.
- The proposed reason for negative intermediate estimates during optimization is not established.
Tags
Full text
# rugarch: GARCH external regressors
# rugarch: GARCH external regressors
I'm currently playing around with the great rugarch package in R. However, I tried to test the external regressor functionality. I implemented a GARCH(1,1) process and compared it with a GARCH(0,1) process where I added the lagged squared returns as external regressor. The results should be the same but aren't. Does anyone of you know where my mistake is? Thank you very much in advance for your help.
```
library(rugarch)
library(quantmod)
getSymbols('C', from = '2000-01-01')
C = adjustOHLC(C, use.Adjusted = TRUE)
R_d = ROC(Cl(C), na.pad = FALSE)
extReg = R_d[1:length(R_d)-1]^2
spec = ugarchspec(mean.model = list(armaOrder = c(0, 0),include.mean = FALSE), variance.model = list(model = 'sGARCH', garchOrder = c(1, 1)), distribution = 'norm')
spec2 = ugarchspec(mean.model = list(armaOrder = c(0, 0),include.mean = FALSE), variance.model = list(model = 'sGARCH', garchOrder = c(0, 1),external.regressors=extReg), distribution = 'norm')
fit = ugarchfit(data = R_d[2:length(R_d),1], spec = spec)
fit2 = ugarchfit(data = R_d[2:length(R_d),1], spec = spec2)
```
The coefficients of the fit model are:
```
omega: 2.1038530309075e-06
alpha1: 0.0863073049030114
beta1: 0.912692551076183
```
The coefficients of the fit2 model are:
```
omega: 8.17097079205033e-07
beta1: 0.999316873189476
vxreg1: 1.01005006640392e-08
```
## Answer by Filippo Scopel (score 2, accepted)
https://quant.stackexchange.com/a/27816
I have found the mistake. The ugarchfit function sets automatically non negativity constraints for all coefficients- This makes sense since the alpha in our case shouldn't be negative. However, when releasing the constraint to negative values you get the right results. The only explanation I can think of is that in the course of optimisation, temporarily negative coefficients estimates are occurring.
```
setbounds(spec2)<-list(vxreg1=c(-1,1))
```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.