# Residuals from GARCH(1,2) model look almost identical with the starting dataset (financial market returns) -- is this normal?

Caveat emptor: I'm relatively new to (G)ARCH models - here using financial markets as dataset just for convenience. If my question is known topic / logical fallacy please point me in the right direction. Kind TIA.

My problem: In analyzing GARCH models, the residuals after a model fit look very similar to the original dataset -- at least for financial market returns (here below for SP500 market returns between 2000 and 2022). Is there any particular explanation for why this is the case ?

Code example:

import pandas as pd
import datetime as dt

# SP500 data: from 2000-01-01 -- 2022-06-01
start = dt.datetime(2000, 1, 1)
end = dt.datetime(2022, 6, 1)
sp500 = web.DataReader('^GSPC', 'yahoo', start=start, end=end)

#### The dataset is SP500 market returns, scaled to 100
retSP500 = 100 * sp500['Adj Close'].pct_change().dropna()

#### Build a GARCH(1,2) model for this data
from arch import arch_model

model_garch_1_2 = arch_model(retSP500, mean = "Constant",  vol = "GARCH", p=2, q=1)
res_garch_1_2 = model_garch_1_2.fit()


As a result, the model residuals -- res_garch_1_2.resid -- are almost identical with the input dataset -- retSP500:

# GARCH(1,2) model fit residuals
>>> res_garch_1_2.resid.describe()

count    5639.000000
mean       -0.037597
std         1.242744
min       -12.047766
25%        -0.543124
50%        -0.002837
75%         0.521157
max        11.516327
Name: resid, dtype: float64

# The original dataset
>>> retSP500.describe()

count    5639.000000
mean        0.026113
std         1.242744
min       -11.984055
25%        -0.479414
50%         0.060874
75%         0.584868
max        11.580037

### Quick 1-1 comparison between the starting dataset and residuals

Date
2000-01-04   -3.898177
2000-01-05    0.128508
2000-01-06    0.031857
2000-01-07    2.645330
2000-01-10    1.055287
2000-01-11   -1.369962
2000-01-12   -0.502348
2000-01-13    1.153260
2000-01-14    1.003420
2000-01-18   -0.746918
2000-01-19   -0.011481
2000-01-20   -0.773242
2000-01-21   -0.354942
2000-01-24   -2.827070
2000-01-25    0.542770
2000-01-26   -0.484983
2000-01-27   -0.457553
2000-01-28   -2.809393
2000-01-31    2.458046
2000-02-01    0.999072

Date
2000-01-04   -3.834467
2000-01-05    0.192218
2000-01-06    0.095568
2000-01-07    2.709040
2000-01-10    1.118997
2000-01-11   -1.306251
2000-01-12   -0.438637
2000-01-13    1.216970
2000-01-14    1.067130
2000-01-18   -0.683207
2000-01-19    0.052229
2000-01-20   -0.709532
2000-01-21   -0.291232
2000-01-24   -2.763359
2000-01-25    0.606480
2000-01-26   -0.421272
2000-01-27   -0.393843
2000-01-28   -2.745683
2000-01-31    2.521757
2000-02-01    1.062782



I haven't made any more "in-depth" analysis of the two series, but they look almost identical.

So my question is: Is this similarity just an artefact due to the datasets/model/methodology I used? Or is this a "feature" of GARCH models that I am not aware of ?

(Side note: The original purpose of building the model in the first place is learning -- particularly, on what consists of a "good metric" for volatility / conditional variance for time-series data, and I use the SP500 financial market returns dataset just for convenience. While I assume that's tangential to my question, I mention it here just in case it's relevant nonetheless).

A GARCH(r,s) model looks something like this: \begin{aligned} x_t &= \mu_t + u_t, \\ \mu_t &= \dots, \\ u_t &= \sigma_t \varepsilon_t, \\ \sigma_t^2 &= \omega + \alpha_1 u_{t-1}^2 + \dots + \alpha_s u_{t-s}^2 + \beta_1 \sigma_{t-1}^2 + \dots + \beta_r \sigma_{t-r}^2, \\ \varepsilon_t &\sim i.i.D(0,1) \end{aligned} where $$\mu_t$$ is the conditional mean of $$x_t$$, $$\sigma_t^2$$ is the conditional variance of $$x_t$$ and $$D$$ is some probability distribution with zero mean and unit variance.
There are two types of residuals in a GARCH model: raw ones $$u_t$$ and standardized ones $$\varepsilon_t$$. If we set the conditional mean to be zero, we obtain $$u_t=x_t$$. That is, raw residuals are the same as the original data $$x_t$$. If we set it to be a constant $$c$$, we obtain $$u_t=x_t-c$$, i.e. raw residuals differ from the original data by a constant. I am not familiar with coding in Python, but it looks like the conditional mean model in your specification happens to be a constant; the two time series you have presented differ by $$0.06371$$ at all time points.
The interesting type of residuals in a GARCH model is however not the raw $$u_t$$ but the standardized $$\varepsilon_t$$. It is the latter that is used in GARCH model diagnostics. For a well-fitting GARCH model, they should be approximately homoskedastic with a mean of zero and a variance of $$1$$.