时间序列算法(3): GARCH (广义自回归条件异方差)
GARCH (广义自回归条件异方差) 模型
GARCH (Generalized Autoregressive Conditional Heteroskedasticity) 模型是 Bollerslev(1986)在 ARCH 模型的基础上提出的扩展版本,是金融时间序列波动率建模中最常用的模型之一。
GARCH 模型的基本原理
GARCH 模型不仅考虑了过去残差项的影响(即 ARCH 部分),还包括了过去条件方差的影响,使得模型能够以更少的参数更有效地捕捉波动率的持续性。
GARCH(p,q) 模型的数学表达式
GARCH(p,q) 模型可以表达为:
- 均值方程:\(r_t = \mu_t + \varepsilon_t\)
- 条件方差方程:
\(\sigma_t^2 = \omega + \sum_{i=1}^q \alpha_i \varepsilon_{t-i}^2 + \sum_{j=1}^p \beta_j \sigma_{t-j}^2\) - 误差项:\(\varepsilon_t = \sigma_t z_t\),其中 \(z_t\) 是独立同分布的随机变量,通常假设服从标准正态分布
参数限制条件:
- \(\omega > 0\)
- \(\alpha_i \geq 0\) 对所有 \(i = 1, 2, ..., q\)
- \(\beta_j \geq 0\) 对所有 \(j = 1, 2, ..., p\)
- \(\sum_{i=1}^q \alpha_i + \sum_{j=1}^p \beta_j < 1\) (保证方差平稳)
其中最常用的是 GARCH(1,1) 模型,形式为:
\(\sigma_t^2 = \omega + \alpha_1 \varepsilon_{t-1}^2 + \beta_1 \sigma_{t-1}^2\)
小数据示例
假设我们有一个简单的 GARCH(1,1) 模型:
\(r_t = 0.01 + \varepsilon_t\)
\(\sigma_t^2 = 0.02 + 0.1\varepsilon_{t-1}^2 + 0.85\sigma_{t-1}^2\)
\(\varepsilon_t = \sigma_t z_t\),其中 \(z_t \sim N(0,1)\)
我们可以手动计算几个时间点的值:
-
假设初始条件:\(\varepsilon_0 = 0\),\(\sigma_0^2 = 0.04\)(长期方差)
-
在 \(t=1\) 时:
- \(\sigma_1^2 = 0.02 + 0.1 \times 0^2 + 0.85 \times 0.04 = 0.054\)
- 假设 \(z_1 = 1.1\),则 \(\varepsilon_1 = \sqrt{0.054} \times 1.1 \approx 0.255\)
- \(r_1 = 0.01 + 0.255 = 0.265\)
-
在 \(t=2\) 时:
- \(\sigma_2^2 = 0.02 + 0.1 \times 0.255^2 + 0.85 \times 0.054 \approx 0.0665\)
- 假设 \(z_2 = -0.9\),则 \(\varepsilon_2 = \sqrt{0.0665} \times (-0.9) \approx -0.232\)
- \(r_2 = 0.01 + (-0.232) = -0.222\)
GARCH 与 ARCH 的关系
GARCH(1,1) 等价于一个无穷阶的 ARCH 模型:
\(\sigma_t^2 = \frac{\omega}{1-\beta} + \alpha \sum_{i=1}^{\infty} \beta^{i-1} \varepsilon_{t-i}^2\)
这表明 GARCH 模型能以更精简的参数表达高阶 ARCH 效应,使模型更加高效。
Python 实现
下面使用 arch
库来模拟和估计 GARCH 模型:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from arch import arch_model
import yfinance as yf
from datetime import datetime, timedelta
# 1. 模拟 GARCH(1,1) 过程
np.random.seed(123)
n = 1000
# 模型参数
omega = 0.02
alpha = 0.1
beta = 0.85
# 初始化
epsilon = np.zeros(n)
sigma2 = np.zeros(n)
returns = np.zeros(n)
sigma2[0] = omega / (1 - alpha - beta) # 初始化为长期方差
# 模拟 GARCH(1,1) 过程
for t in range(1, n):
sigma2[t] = omega + alpha * epsilon[t-1]**2 + beta * sigma2[t-1]
epsilon[t] = np.sqrt(sigma2[t]) * np.random.normal(0, 1)
returns[t] = 0.01 + epsilon[t]
# 2. 可视化模拟数据
plt.figure(figsize=(12, 6))
plt.subplot(211)
plt.plot(returns)
plt.title('模拟的GARCH(1,1)收益率')
plt.ylabel('收益率')
plt.subplot(212)
plt.plot(np.sqrt(sigma2))
plt.title('模拟的条件标准差')
plt.ylabel('条件标准差')
plt.tight_layout()
plt.show()
# 3. 使用arch库估计GARCH模型
model = arch_model(returns, vol='GARCH', p=1, q=1, mean='Constant')
results = model.fit(disp='off')
print(results.summary())
# 4. 使用真实数据演示 - 获取上证指数数据
end_date = datetime.now()
start_date = end_date - timedelta(days=365*5) # 5年数据
# 尝试使用yfinance获取上证指数数据
df = yf.download('^SSEC', start=start_date, end=end_date)
returns = 100 * df['Adj Close'].pct_change().dropna()
# 估计GARCH模型
model = arch_model(returns, vol='GARCH', p=1, q=1, mean='Constant')
results = model.fit(disp='off')
print(results.summary())
# 可视化拟合结果
fig = plt.figure(figsize=(12, 9))
ax1 = fig.add_subplot(311)
ax1.plot(returns)
ax1.set_title('上证指数日收益率')
ax2 = fig.add_subplot(312)
ax2.plot(results.conditional_volatility)
ax2.set_title('GARCH(1,1)估计的条件波动率')
ax3 = fig.add_subplot(313)
ax3.plot(results.conditional_volatility**2)
ax3.set_title('GARCH(1,1)估计的条件方差')
plt.tight_layout()
plt.show()
# 5. 波动率预测
forecasts = results.forecast(horizon=10)
plt.figure(figsize=(12, 6))
plt.plot(forecasts.variance[-30:].values)
plt.title('未来10天的方差预测')
plt.xlabel('时间')
plt.ylabel('预测方差')
plt.show()
GARCH 模型的优点
- 参数精简: GARCH(1,1) 通常可以有效地捕捉金融资产收益率序列的条件异方差特性,而无需使用高阶 ARCH 模型
- 波动率持续性: 能够有效捕捉金融市场中波动率的持久性和聚集现象
- 预测能力: 在波动率预测方面表现良好,尤其是短期预测
- 灵活性: 可以扩展为各种形式,如 EGARCH、GJR-GARCH 等,应对不同市场特征
GARCH 模型的扩展
- EGARCH (指数GARCH): 考虑了杠杆效应,允许正负冲击对波动率有不对称影响
- GJR-GARCH (Glosten-Jagannathan-Runkle GARCH): 另一种捕捉杠杆效应的GARCH变体
- IGARCH (综合GARCH): 当波动率高度持久时使用
- FIGARCH (分数综合GARCH): 用于长记忆波动率过程
- 多变量GARCH: 允许对多个时间序列的波动率和它们之间的相关性进行建模
在实践中,GARCH(1,1) 是最常用的波动率模型之一,在金融风险管理、资产定价和投资组合优化等领域有广泛应用。