
简介这份PPT课件面向金融学、计量经济学方向的学生与研究人员系统讲解GARCH类模型在金融时间序列波动性分析中的原理与应用。内容从Engle提出的ARCH过程切入梳理条件异方差性的来源与ARCH(q)的建模思路进而展开GARCH(1,1)及高阶GARCH(p,q)的形式、参数含义、最大似然估计与ARCH-LM检验方法并延伸到EGARCH、TGARCH、GARCH-M等变体结合上证指数GARCH(1,1)实证案例演示波动率预测与杠杆效应的刻画。资源包共1个PPT文件约749KB结构按ARCH过程、模型检验与估计、模型扩展三节递进配套学习目标与实证图表便于课堂讲授或自学时对照梳理知识框架。目前已有266人学习适合需要理解金融波动聚集性、尖峰厚尾特征与风险管理建模方法的读者作为入门与复习参考。1. 从波动丛聚到条件异方差第六章GARCH模型分析与应用想解决的问题第六章GARCH模型分析与应用这份课件里有个案例值得先看把上证指数1990年12月19日到2006年8月31日的3855个日收益率丢进一个AR(1)模型残差用Ljung-Box检验p值很大干净得像白噪声可把残差平方再做一次自相关滞后1到10阶几乎全部显著。同一份数据一次说“没有自相关”一次说“强相关”差别只在于对残差做了什么变换。这就是课件要处理的核心矛盾——收益率本身几乎不可预测收益率的方差却高度可预测。课件的骨架是四段ARCH过程的提出背景与金融异方差特征、GARCH(1,1)的均值方程与条件方差方程、ARCH-LM检验与残差平方相关图这套检验估计流程、以及EGARCH、TGARCH、GARCH-M三类扩展加一个上证指数实证。做量化想给仓位加波动率约束的、做风控要给VaR找一个会动的分母的、以及被教材里一堆符号绕晕的都能从这份材料里拿到能直接上手的东西。2. ARCH过程与GARCH(1,1)均值方程和条件方差方程怎么摆2.1 金融时间序列的三个典型事实传统线性模型默认扰动项同方差这个假设在金融数据上基本站不住。课件第一节花了不少笔墨描述的现象落到建模层面可以归纳成三条它们决定了后面为什么必须拆出第二个方程。特征数据表现对建模的直接含义尖峰厚尾收益率分布峰度远大于3尾部概率高于正态正态似然会低估极端风险需考虑t分布或GED波动丛聚大幅波动后面跟着大幅波动小幅波动扎堆条件方差本身要有自回归结构杠杆效应同幅度的负冲击比正冲击带来更大波动对称的GARCH(1,1)结构上就刻画不了波动丛聚是最容易验证的一条把残差平方序列画出来或者直接看它的自相关图就能看到明显的衰减拖尾。恩格尔1982年在分析通胀数据时注意到的正是这件事预测误差的方差取决于后续扰动项的大小误差的方差里含有可提取的相关性。2.2 ARCH(q)的构造把残差平方当成可回归的对象ARCH模型的全称是自回归条件异方差模型它的思路不是去预测收益率而是去预测收益率的方差。把序列写成均值方程加扰动项的形式y_t a0 a1 * y_{t-1} e_t e_t sqrt(h_t) * v_t, v_t ~ iid N(0, 1)关键在于第二步的乘法结构e_t 被拆成“一个标准化的白噪声”乘上“当期标准差”方差 h_t 因此可以随时间变化。ARCH(q) 把 h_t 写成过去 q 期残差平方的线性函数h_t a0 a1 * e_{t-1}^2 a2 * e_{t-2}^2 ... aq * e_{t-q}^2参数含义上a0 是方差的地板ai 度量第 i 期冲击对当前波动的影响强度所有 ai 非负以保证方差不会为负。用一段模拟代码可以直观看到这种“大波动扎堆”是长什么样import numpy as np np.random.seed(2024) n 2000 a0, a1 0.4, 0.6 e np.zeros(n) h np.zeros(n) h[0] a0 / (1 - a1) for t in range(1, n): # 当期方差由上一期残差平方决定 h[t] a0 a1 * e[t - 1] ** 2 e[t] np.sqrt(h[t]) * np.random.randn() # 观察残差平方的自相关前几阶通常显著非零 sq e ** 2 acf1 np.corrcoef(sq[1:], sq[:-1])[0, 1] print(残差平方一阶自相关:, round(acf1, 4))这段代码只做了一件事人为制造一个异方差过程再回头验证它确实留下了可检测的自相关痕迹。把 a1 调大波动丛聚会更夸张调成0残差平方的自相关就掉到统计上不显著的水平。后面做真实数据时判断标准是同一套逻辑只是残差由均值方程估计得到。2.3 GARCH(1,1)用两个参数吃掉无穷阶ARCHARCH(q) 的麻烦在于阶数。金融高频数据的波动记忆很长要拟合充分往往得取到 q10 甚至更高参数一多就难估、容易违反非负约束。Bollerslev 1986年的做法是给条件方差方程再套一层自回归结构让无穷阶的ARCH被两个参数近似掉h_t w a1 * e_{t-1}^2 b1 * h_{t-1}这就是 GARCH(1,1) 的条件方差方程配合均值方程 y_t X_t * b e_t 构成完整模型。三个参数的分工可以用一张表说清参数名称作用取值范围w常数项长期方差的地板等于 (1-a1-b1) 乘无条件方差w 0a1ARCH项系数度量上一期“新息”冲击的即时反应a1 ≥ 0b1GARCH项系数度量波动记忆的延续长度b1 ≥ 0a1b1持久性越接近1波动冲击衰减越慢必须小于1a1b1 是建模时第一个要盯的数字。它小于1模型才是协方差平稳的无条件方差才等于 w/(1-a1-b1)等于1就是IGARCH冲击永不衰减大于1在多数软件里会直接跑到不收敛或者给出无意义的估计。想估算冲击衰减多快可以用半衰期 ln(0.5)/ln(a1b1) 换算比如 a1b10.98 时半衰期大约是34期。从ARCH到GARCH这一步本质上是用一个更节约的参数化形式替代长滞后代价是对冲击衰减形状施加了指数衰减的约束。如果实际数据的波动记忆不是指数衰减就得考虑后面几章的长记忆或非对称扩展。3. GARCH类模型的检验与估计ARCH-LM、残差平方相关图与最大似然3.1 建模顺序先均值方程再残差最后条件方差一份能复现的GARCH建模流程顺序不能乱。常见做法是下面五步对收益率序列做平稳性检验确认均值方程里该放几阶滞后估计均值方程AR、ARMA或带外生变量的回归拿到残差 e_t对 e_t 做ARCH效应检验确认还有没有东西可建模加入条件方差方程用极大似然联合估计均值方程和方差方程的参数检验标准化残差 z_t e_t / sqrt(h_t) 是否已经是白噪声并做分布诊断。第2步和第3步最容易被跳过。如果均值方程没估干净残差里混着没提取的自相关ARCH-LM 会把均值设定错误误判成异方差最后拟合出一个拟合优度很高但没有任何预测意义的方差方程。3.2 ARCH-LM检验辅助回归和两个统计量的读法ARCH-LM 检验的原假设是残差序列直到 q 阶都不存在ARCH效应即 a1 a2 … aq 0。检验方式是把残差平方对自身滞后做辅助回归e_t^2 c0 c1 * e_{t-1}^2 ... cq * e_{t-q}^2 u_t课件里提到会得到两个统计量实务中理解它们的区别很重要。F统计量是对所有滞后残差平方项的联合显著性检验适合小样本另一个是观测数乘以辅助回归的 R²渐近服从自由度为 q 的卡方分布。EViews输出的 Obs*R-squared 用的是有效观测数 (T-q) 乘 R²所以会和课件上写的 T×R² 差一个 lag 的量级样本量大时无关紧要样本只有几百个时别混用。import numpy as np from statsmodels.stats.diagnostic import het_arch # resid 来自上一步均值方程的残差 resid np.asarray(resid) lm_stat, lm_p, f_stat, f_p het_arch(resid, nlags10) print(fLM统计量{lm_stat:.3f}, p{lm_p:.4f}) print(fF统计量{f_stat:.3f}, p{f_p:.4f})nlags是辅助回归的滞后阶数通常先试10。p值小于0.05就拒绝原假设说明残差平方里还有可提取的结构可以继续做GARCHp值很大则说明ARCH效应不明显硬上GARCH只会估出一堆不显著的参数。het_arch默认不做自由度修正和EViews的数字对不上属于正常范围。3.3 残差平方相关图与Ljung-Box QARCH-LM 给的是联合检验的结论残差平方相关图给的是结构信息。它显示残差平方序列在指定滞后阶数上的自相关和偏自相关系数并给出对应阶数的 Ljung-Box Q 统计量。判读规则可以整理成这样图上现象Q统计量结论AC在1~3阶显著之后快速衰减低阶p值小高阶p值大短记忆ARCH/GARCH取q1~2AC缓慢拖尾10阶仍显著所有滞后p值都小波动记忆长考虑高阶或长记忆模型AC/PAC全在置信带内各阶p值都大无ARCH效应不必建方差方程偏自相关在低阶截尾时可以据此给ARCH项定阶但GARCH(1,1)的ACF是缓慢衰减的看图形定阶的意义有限实践中更常用的是从 GARCH(1,1) 起步再看更高阶项是否显著、AIC是否下降。3.4 最大似然估计与分布假设的选择GARCH类模型基本都走极大似然。给定样本对数似然函数是各期条件密度之和以正态假设为例每一项是 -0.5 * (ln(2π) ln(h_t) e_t²/h_t)。因为 h_t 递推依赖前面的参数目标函数没有解析解靠数值优化参数初值和分布假设就变得很敏感。分布假设适用场景代价正态教学演示、波动幅度小的低频数据严重低估尾部参数可能被极端值带偏Student-t尖峰厚尾明显的股票收益率多一个自由度参数样本少时估计不稳GED尾部厚度介于正态与t之间需要额外选择形状参数偏t收益率分布本身不对称参数最多优化容易卡在局部极值判断分布选得对不对最直接的办法是把标准化残差 z_t 拿出来看峰度、做Jarque-Bera检验再用 QQ 图看尾部。z_t 理论上应该是同方差的白噪声如果它还有明显的厚尾说明分布假设太薄换t分布重估通常会让参数的对数似然明显改善。4. 用Python复现上证指数GARCH(1,1)从对数收益率到条件方差4.1 数据准备与收益率缩放把课件里的上证指数案例搬到代码里第一步是收益率的口径。价格序列是非平稳的必须转成对数收益率更关键的是缩放——原始对数收益率的数量级在1e-3到1e-2之间直接丢进优化器会触发数值警告甚至不收敛。实务里统一乘以100把单位换算成百分比。import pandas as pd import numpy as np from arch import arch_model df pd.read_csv(sh_index.csv, parse_dates[date]).sort_values(date) df[ret] 100 * np.log(df[close]).diff() # 对数收益率百分比口径 df df.dropna(subset[ret]).reset_index(dropTrue) print(df[ret].describe()) print(峰度:, df[ret].kurt()) # 远大于3说明厚尾np.log(close).diff()得到连续复利收益率乘100只是为了数值条件更好不影响参数显著性事后解释波动率时记得除回去。峰度这一步是在为后面的分布假设做铺垫如果算出来是6以上基本可以放弃正态假设。4.2 均值方程设定与模型拟合均值方程不要一上来就堆滞后。先用AR(1)起步把残差取出来做 ARCH-LM确认有效应之后再上GARCH。arch包可以直接把均值项和方差项写在一个调用里meanAR配合lags1表示AR(1)均值方程。# 第一步只估均值方程取残差做ARCH效应检验 from statsmodels.tsa.arima.model import ARIMA ar1 ARIMA(df[ret], order(1, 0, 0)).fit() resid ar1.resid # 第二步联合估计AR(1)-GARCH(1,1)残差服从t分布 am arch_model(df[ret], meanAR, lags1, volGARCH, p1, q1, distt) res am.fit(dispoff) print(res.summary())distt让新息服从Student-tdispoff关掉每轮迭代的输出。res.summary()里要重点看四块均值方程系数的显著性、omega/alpha[1]/beta[1]、t分布的自由度参数nu、以及对数似然值。alpha[1] 显著说明冲击的即时反应真实存在beta[1] 显著说明波动记忆长两个相加接近1说明波动冲击衰减得很慢。4.3 参数解读与标准化残差诊断拟合完不能直接拿去用必须回头验证标准化残差。z_t e_t / sqrt(h_t) 如果还有结构说明模型没吃干净。# 标准化残差 z res.resid / res.conditional_volatility from statsmodels.stats.diagnostic import het_arch, acorr_ljungbox print(标准化残差ARCH-LM p值:, het_arch(z.dropna(), nlags10)[1]) print(标准化残差平方Ljung-Box p值:, acorr_ljungbox(z.dropna() ** 2, lags[10])[lb_pvalue].values) print(标准化残差峰度:, z.kurt())两个p值都应该大于0.05峰度应该比原始收益率明显下降、接近t分布的理论水平。如果ARCH-LM仍然显著说明阶数不够把 p 或 q 加到2再试如果峰度还是很高说明t分布的自由度估计被极端值拉住了可以考虑GED或者把样本里的极端点单独检查。4.4 条件波动率提取与常见报错条件波动率直接用res.conditional_volatility取注意这是标准差不是方差量纲是百分比换算成年化要乘 sqrt(252)。这一步做错是新手最常见的量纲错误用它去和日收益率画在同一张图上动辄差两个数量级。几个高频报错和处理方式报错/警告原因处理DataScaleWarning收益率量纲太小乘100后重估ConvergenceWarning初值差或模型设定过复杂降阶、换分布、多给几组初值omega为负样本内极端值主导检查缺失值和停牌日考虑稳健设定alphabeta1波动记忆过强或样本太短检查数据频率必要时用IGARCH停牌、涨跌停和复权处理不干净是上证指数这类数据最容易出问题的地方。收益率序列里出现一根异常大的跳空omega 和 alpha 都会跟着走样动手前先把数据清洗日志留一份。5. EGARCH、TGARCH与GARCH-M杠杆效应与风险溢价的建模5.1 对称结构在什么地方失效GARCH(1,1) 的条件方差只依赖 e_{t-1} 的平方正负冲击对波动的影响完全一样。但股票市场里同等幅度的下跌带来的波动上升通常比上涨更猛这就是课件里提到的杠杆效应。用 EGARCH 或 TGARCH 的核心动机就是把“方向”这个信息塞进方差方程。5.2 EGARCH对数方差加符号项EGARCH 把方差方程写到对数尺度上天然保证方差为正不需要再对参数施加非负约束ln(h_t) w b * ln(h_{t-1}) g * (e_{t-1}/sqrt(h_{t-1})) a * (|e_{t-1}|/sqrt(h_{t-1}) - E|z|)g 是符号项系数。g 显著为负说明负冲击推高波动更多杠杆效应成立g 不显著则说明数据里没这个特征用GARCH(1,1)就够了。对数形式还带来一个额外好处外部冲击对波动的影响是可加的不会因为当前波动水平高低而被放大或压缩。5.3 TGARCH的阈值项与GARCH-M的均值方程TGARCH 走的是另一条路直接在方差方程里加一个哑变量交乘项h_t w a * e_{t-1}^2 g * e_{t-1}^2 * d_{t-1} b * h_{t-1} d_{t-1} 1 若 e_{t-1} 0否则为 0当 e_{t-1} 为负时冲击项的系数是 ag为正时是 a。g0 就对应杠杆效应。相比EGARCHTGARCH的参数更容易解释但也更难保证方差恒为正。GARCH-M 则换了个方向把条件方差搬回均值方程y_t mu delta * h_t e_tdelta 是风险溢价系数delta0 表示波动越大、要求收益越高常用来描述风险与收益的跨期关系。三种扩展的适用场景可以对照下面这张表模型加入的结构主要检验目标Python设置GARCH(1,1)仅残差平方与滞后方差波动丛聚是否显著volGARCH, p1, q1EGARCH对数方差 符号项杠杆效应方向volEGARCH, o1TGARCH负冲击阈值交乘杠杆效应幅度volGARCH, o1, power1GARCH-M条件方差进均值方程风险溢价是否存在meanAR, 并在均值中指定vol5.4 用信息准则做模型选择同一样本上估多个模型别只看参数显著性AIC和BIC更靠谱因为它们惩罚了参数个数。实操里通常固定均值方程不变只换方差方程设定比较对数似然和AIC。cands { GARCH: arch_model(df[ret], meanAR, lags1, volGARCH, p1, q1, distt), EGARCH: arch_model(df[ret], meanAR, lags1, volEGARCH, p1, o1, q1, distt), TGARCH: arch_model(df[ret], meanAR, lags1, volGARCH, p1, o1, q1, power1.0, distt), } for name, m in cands.items(): r m.fit(dispoff) print(f{name}: LLF{r.loglikelihood:.2f}, AIC{r.aic:.2f}, BIC{r.bic:.2f})o1控制非对称项阶数power1.0让GARCH族按标准差而非方差建模这是TGARCH在 arch 包里的常见写法。三个模型的AIC差在2以内时优先选参数少、解释更直接的那个差出10以上说明杠杆效应确实存在别硬用对称模型。6. 波动率预测落地预测步长、滚动回测与几个容易踩的坑模型估完真正拉开差距的是预测环节。调用res.forecast(horizon5, methodanalytic)拿到的res.forecast.variance是按期排列的条件方差注意列名是 h.1 到 h.5对应未来第1到第5期。多步预测有个容易被忽略的性质GARCH(1,1) 的预测值会按 (a1b1)^k 的速度收敛到长期方差 w/(1-a1-b1)。这意味着设 horizon1 和 horizon20早期几期还有差别越往后越是同一条水平线。所以拿GARCH做中期波动率预测意义有限它的价值集中在一到五个交易日这个窗口。评估预测质量别只看均方误差。用滚动窗口做样本外回测更接近真实使用场景每次用固定长度的历史窗口估参预测下一期方差再滚动前移。window 1000 preds, actuals [], [] for i in range(window, len(df) - 1): train df[ret].iloc[i - window:i] m arch_model(train, meanAR, lags1, volGARCH, p1, q1, distt).fit(dispoff) # 取未来一期方差预测 preds.append(np.sqrt(m.forecast(horizon1).variance.values[-1, 0])) actuals.append(df[ret].iloc[i]) # 用当期收益平方作为代理 preds, actuals np.array(preds), np.array(actuals) qlike np.mean(np.log(preds ** 2) (actuals ** 2) / preds ** 2) print(QLIKE损失:, round(qlike, 4))这段代码里有三个坑。第一每次都重新拟合计算量大可以改成每20期重估一次、中间只做预测速度能快一个数量级。第二用当期收益率平方作为事后波动的代理噪声极大样本少于500期时结论不稳更稳的做法是用日内高频数据算已实现波动率。第三QLIKE损失对低估波动率惩罚更重评估结果要和MSE、Mincer-Zarnowitz回归的R²一起看。最后是量纲和年化。conditional_volatility是百分比口径的标准差年化乘 sqrt(252)若要拿去算VaR记得先转回小数再乘头寸。风控场景里还有一个常见误用把 GARCH 预测方差直接代入正态VaR公式而新息分布选的是t两边口径不一致会导致尾部风险被系统性低估正确做法是用估计出的自由度参数查t分布分位数。本文还有配套的精品资源点击获取