/ / /
第48讲:ARCH、GARCH和GMM模型 (ARCH, GARCH, and GMM)
🔴
入学要求
💯
能力测试
🛣️
课程安排
🕹️
研究资源

第48讲:ARCH、GARCH和GMM模型 (ARCH, GARCH, and GMM)

💡

查看全集:💎Quantopia量化分析56讲

关键概念解析

ARCH模型(自回归条件异方差)

ARCH模型认为波动率具有自回归性,当前方差取决于过去平方残差的移动平均:

σt2=α0+α1εt12+...+αpεtp2σ_t^2 = α_0 + α_1ε_{t-1}^2 + ... + α_pε_{t-p}^2

其中:

GARCH模型(广义自回归条件异方差)

在ARCH基础上加入方差自身滞后项,形成更灵活的波动率模型:

σt2=ω+αεt12+βσt12σ_t^2 = ω + αε_{t-1}^2 + βσ_{t-1}^2

其中:

模型演进对比

特性ARCH(p)GARCH(p,q)
方程结构仅过去残差平方项加入历史方差项
参数效率需要较多参数参数更精简
适用场景短期波动预测中长期波动预测

模拟GARCH(1,1)过程

参数设置与模拟函数

import numpy as np
import math

def simulate_garch(T, a0, a1, b1, initial_vol):
    """模拟GARCH(1,1)过程"""
    X = np.zeros(T)
    sigma = np.zeros(T)
    sigma[0] = initial_vol

    for t in range(1, T):
        X[t-1] = sigma[t-1] * np.random.normal(0, 1)
        sigma[t] = math.sqrt(a0 + b1*sigma[t-1]**2 + a1*X[t-1]**2)

    X[-1] = sigma[-1] * np.random.normal(0, 1)
    return X, sigma

参数配置示例

# 基本参数设置
a0 = 1.0    # 常数项
a1 = 0.1    # ARCH项系数
b1 = 0.8    # GARCH项系数
initial_vol = np.sqrt(a0 / (1 - a1 - b1))  # 初始波动率

# 模拟10000个样本
X, sigma = simulate_garch(10000, a0, a1, b1, initial_vol)
X = X[1000:]  # 去除前10%的燃烧期数据

可视化对比

import matplotlib.pyplot as plt

plt.figure(figsize=(12,6))
plt.plot(X, label='GARCH Process')
plt.plot(sigma[1000:], label='Conditional Volatility', color='r')
plt.axhline(3*np.std(X), color='k', linestyle='--', label='3σ')
plt.legend()
plt.title('GARCH(1,1) Process Simulation');

ARCH效应检验

检验步骤

  1. 对收益率序列进行OLS回归:εt2=γ0+γ1εt12+...+γpεtp2ε_t^2 = γ_0 + γ_1ε_{t-1}^2 + ... + γ_pε_{t-p}^2
  1. 计算检验统计量:TR2χ2(p)TR^2 \sim \chi^2(p)
  1. 判断显著性

其中:

零假设H0H_0:不存在ARCH效应(γ1=γ2=...=γp=0γ_1 = γ_2 = ... = γ_p = 0)

import statsmodels.api as sm
from scipy import stats

def arch_test(returns, p=5):
    """ARCH效应检验"""
    squared_returns = returns**2
    X = np.array([squared_returns[i-p:i] for i in range(p, len(returns))])
    X = sm.add_constant(X)
    model = sm.OLS(squared_returns[p:], X)
    results = model.fit()

    test_stat = len(returns)*results.rsquared
    p_value = 1 - stats.chi2(df=p).cdf(test_stat)
    return test_stat, p_value

# 示例应用
test_stat, p_val = arch_test(X, p=5)
print(f'卡方统计量: {test_stat:.2f}, p值: {p_val:.4f}')

小练习

尝试不同滞后阶数p(如3,5,10),观察检验结果的变化,思考如何选择最优滞后阶数?

参数估计方法

最大似然估计(MLE)

通过最大化对数似然函数进行参数估计:

L(θ)=12t=1T(ln(σt2)+εt2σt2)L(θ) = -\frac{1}{2}\sum_{t=1}^T \left( \ln(σ_t^2) + \frac{ε_t^2}{σ_t^2} \right)

其中:

from scipy.optimize import minimize

def garch_loglikelihood(params, returns):
    """GARCH(1,1)对数似然函数"""
    a0, a1, b1 = params
    T = len(returns)
    sigma2 = np.zeros(T)

    # 初始化
    sigma2[0] = np.var(returns)
    for t in range(1,T):
        sigma2[t] = a0 + a1*returns[t-1]**2 + b1*sigma2[t-1]

    return -np.sum( -0.5*(np.log(sigma2) + returns**2/sigma2) )

# 参数估计示例
cons = ({'type': 'ineq', 'fun': lambda x: 1 - (x[1]+x[2])},
        {'type': 'ineq', 'fun': lambda x: x[1]},
        {'type': 'ineq', 'fun': lambda x: x[2]})

result = minimize(garch_loglikelihood, [0.1,0.1,0.8],
                  args=(X,), method='SLSQP', constraints=cons)
print('MLE估计参数:', result.x)

GMM估计

def gmm_objective(params, returns, W):
    """GMM目标函数"""
    a0, a1, b1 = params
    sigma2 = compute_sigma2(returns, a0, a1, b1)
    residuals = returns / np.sqrt(sigma2)

    # 构建矩条件
    m1 = np.mean(residuals)
    m2 = np.mean(residuals**2 - 1)
    m3 = np.mean(residuals**3)
    m4 = np.mean(residuals**4 - 3)

    G = np.array([m1, m2, m3, m4])
    return G.T @ W @ G

# 迭代估计过程需要多次优化

实战:预测波动率

使用历史数据进行预测

def forecast_volatility(params, last_vol, last_return, days=5):
    """向前预测波动率"""
    a0, a1, b1 = params
    forecasts = []
    current_vol = last_vol

    for _ in range(days):
        next_vol = np.sqrt(a0 + a1*last_return**2 + b1*current_vol**2)
        forecasts.append(next_vol)
        current_vol = next_vol
        last_return = 0  # 假设未来收益率为0

    return forecasts

# 使用估计参数进行预测
params = [0.1, 0.1, 0.8]
last_vol = sigma[-1]
last_return = X[-1]
forecast = forecast_volatility(params, last_vol, last_return, days=10)

蒙特卡洛模拟

def monte_carlo_forecast(params, n_sims=1000, days=5):
    """蒙特卡洛波动率预测"""
    all_sims = []
    for _ in range(n_sims):
        sim_returns, sim_vol = simulate_garch(days+1, *params, sigma[-1])
        all_sims.append(sim_vol[1:])
    return np.array(all_sims)

# 生成预测区间
forecasts = monte_carlo_forecast([0.1,0.1,0.8])
lower = np.percentile(forecasts, 5, axis=0)
upper = np.percentile(forecasts, 95, axis=0)

练习题

  1. 尝试修改ARCH项的系数a1,观察模拟序列的尖峰厚尾现象变化
  1. 使用yfinance获取真实股票数据,应用ARCH检验并比较结果
    import yfinance as yf
    data = yf.download('AAPL', start='2020-01-01', end='2023-01-01')
    returns = data['Close'].pct_change().dropna()
    
  1. 比较不同初始值对MLE估计结果的影响,思考稳健性改进方法

通过本教程,您已掌握ARCH/GARCH模型的核心原理和实现方法。下一步可以探索: