ff— title: “ARCH and GARCH Models Explained (for Dummies)” output: html_document —

Why this matters

The core idea

ARCH and GARCH models are about one specific thing: predicting how much a value will wiggle, not predicting the value itself.

Imagine you’re tracking the daily return of a stock. Some weeks it barely moves. Other weeks it swings wildly — and importantly, wild weeks tend to cluster together. A big move today makes a big move tomorrow more likely. Calm periods stay calm for a while too.

This is called volatility clustering, and regular models (which assume constant variance) completely miss it.

ARCH (Autoregressive Conditional Heteroskedasticity)

Breaking down the name:

The simple idea: today’s variance depends on yesterday’s squared shock (error).

\[\sigma_t^2 = \omega + \alpha \cdot \epsilon_{t-1}^2\]

In plain English: “If yesterday had a big surprise (positive or negative), expect today to be more volatile too.”

Toy example. Say \(\omega = 0.1\) and \(\alpha = 0.6\).

One big shock spikes the predicted volatility.

GARCH (Generalized ARCH)

ARCH only looks one step back and forgets fast. GARCH adds memory of recent volatility itself, not just shocks:

\[\sigma_t^2 = \omega + \alpha \cdot \epsilon_{t-1}^2 + \beta \cdot \sigma_{t-1}^2\]

The extra \(\beta \sigma_{t-1}^2\) term means: “Also factor in how volatile things already were yesterday, not just yesterday’s surprise.” This makes GARCH smoother and better at modeling realistic, slowly-decaying volatility — a shock causes a spike, then volatility gradually settles back down over days or weeks, not instantly.

Analogy. ARCH is like reacting only to the last earthquake’s magnitude. GARCH is like reacting to the last earthquake and remembering we’re still in an aftershock period.

Model Remembers Use when
ARCH Just the last shock Simple, short-memory volatility
GARCH Last shock + last volatility level Most real-world data (smoother, more realistic decay)

“GARCH(1,1)” simply means it looks back 1 period for the shock term and 1 period for the volatility term — the most common, often “good enough” specification.

Simulating a GARCH(1,1) process in R

The code below simulates a simple GARCH(1,1) process from scratch (no external packages needed) so you can see volatility clustering appear.

Notice how the volatility panel spikes right after large moves in the returns panel, then decays gradually — that gradual decay is the “G” (generalized) memory effect in GARCH.

Fitting a GARCH model to real data

In practice you’d fit a GARCH model rather than simulate one.

## [1] "AAPL"
## 
## Title:
##  GARCH Modelling 
## 
## Call:
##  garchFit(formula = ~garch(1, 1), data = returns, trace = FALSE) 
## 
## Mean and Variance Equation:
##  data ~ garch(1, 1)
## <environment: 0x00000252ac060c78>
##  [data = returns]
## 
## Conditional Distribution:
##  norm 
## 
## Coefficient(s):
##         mu       omega      alpha1       beta1  
## 1.2591e-03  1.3907e-05  9.3908e-02  8.6910e-01  
## 
## Std. Errors:
##  based on Hessian 
## 
## Error Analysis:
##         Estimate  Std. Error  t value Pr(>|t|)    
## mu     1.259e-03   4.044e-04    3.114  0.00185 ** 
## omega  1.391e-05   3.727e-06    3.732  0.00019 ***
## alpha1 9.391e-02   1.487e-02    6.315 2.71e-10 ***
## beta1  8.691e-01   2.080e-02   41.776  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Log Likelihood:
##  4269.184    normalized:  2.615922 
## 
## Description:
##  Sun Jul  5 19:56:37 2026 by user: Cristian 
## 
## 
## 
## Standardised Residuals Tests:
##                                   Statistic      p-Value
##  Jarque-Bera Test   R    Chi^2  449.8869986 0.000000e+00
##  Shapiro-Wilk Test  R    W        0.9750282 3.063117e-16
##  Ljung-Box Test     R    Q(10)    4.6598327 9.127134e-01
##  Ljung-Box Test     R    Q(15)    5.8171947 9.826575e-01
##  Ljung-Box Test     R    Q(20)   11.5545967 9.305541e-01
##  Ljung-Box Test     R^2  Q(10)    7.8209783 6.463185e-01
##  Ljung-Box Test     R^2  Q(15)    8.1406376 9.180206e-01
##  Ljung-Box Test     R^2  Q(20)   12.7398961 8.882629e-01
##  LM Arch Test       R    TR^2     7.9586566 7.883528e-01
## 
## Information Criterion Statistics:
##       AIC       BIC       SIC      HQIC 
## -5.226941 -5.213712 -5.226953 -5.222034

Plotting the returns series with dates

Interpreting the fitted coefficients

Once you run summary(fit) above, you’ll get a coefficient table roughly like this:

Coefficient Meaning
mu The mean of the returns series. Usually close to 0 for daily stock returns and often not statistically significant — that’s normal, since GARCH is about variance, not the mean.
omega (\(\omega\)) The baseline variance level. Combined with alpha1 and beta1, it gives the long-run (unconditional) variance: \(\omega / (1 - \alpha_1 - \beta_1)\).
alpha1 (\(\alpha\)) How much yesterday’s shock (squared residual) feeds into today’s variance. Higher = more reactive, jumpy volatility.
beta1 (\(\beta\)) How much of yesterday’s variance itself carries over. Higher = more persistent volatility that decays slowly.

Three things worth checking in your results:

  1. \(\alpha + \beta\) should be less than 1. This is the stationarity condition — it guarantees that shocks eventually die out rather than compounding forever. Real daily financial data often lands close to 1 (e.g. 0.97-0.99), meaning volatility is highly persistent but still mean-reverting. If \(\alpha + \beta \geq 1\), the model is misspecified for that series.
  2. Statistical significance. Each coefficient comes with a standard error and p-value. You generally want alpha1 and beta1 to be significant. If beta1 isn’t significant, a plain ARCH model (no volatility memory term) might already be enough.
  3. Relative size of \(\alpha\) vs \(\beta\). In most real financial series, \(\beta\) is noticeably larger than \(\alpha\) (e.g. \(\alpha \approx\) 0.05-0.15, \(\beta \approx\) 0.80-0.90). This matches the earthquake analogy from earlier: volatility today is driven more by “how volatile things already were” (\(\beta\)) than by any single shock (\(\alpha\)).