ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

GARCH-MIDAS模型实战解析:混合频率波动率建模与MATLAB实现

GARCH-MIDAS模型实战解析:混合频率波动率建模与MATLAB实现 简介面向金融时间序列分析中的波动率建模与混频数据融合需求这份MATLAB代码包完整实现了GARCH-MIDAS、DCC-MIDAS、adl-MIDAS及DCC-GARCH等主流模型适用于金融计量课程、科研课题及量化投资实证研究。压缩包共含39个文件包括30个m格式源码脚本、4个xls和2个xlsx示例数据文件、2个txt说明文档以及1个PDF用户指南整体仅1.11MB结构清晰、便于快速定位。通过这些代码研究者可以处理日度、周度与月度等不同频率数据的混合抽样问题估计资产间的动态条件相关性加入外生变量进行扩展并结合DCC-GARCH刻画多资产波动联动效应内置的示例数据集和模块化函数也让用户能直接替换自有数据运行降低从理论到实践的门槛。同时随包的PDF用户指南对模型原理与函数调用做了说明便于初学者对照学习。目前已有389人学习下载是一份小巧而完整的参考代码包值得金融与计量经济学方向的读者收藏使用。1. 混合频率波动率建模为什么 GARCH-MIDAS 值得拆开源码金融时间序列分析里最尴尬的问题不是模型不够复杂而是数据频率对不上。纳斯达克综合指数的日度收益率与工业产值指数的月度波动之间天然存在一层频率错配。传统 GARCH 族模型只能用单一频率把月度数据降频到日度会损失信息把日度收益聚合到月度又会抹平短期波动。GARCH-MIDAS 的思路是把这个矛盾拆成两层短期波动率由 GARCH 过程刻画长期趋势由低频宏观变量通过 MIDAS 滤波驱动。DCC-MIDAS 进一步把动态条件相关嵌入这一框架。v2.4 代码包将这两类模型完整封装成 MATLAB 脚本并附带了可以直接复现的金融数据集对量化研究者和资产配置从业者来说是少见的能直接跑通的完整实现。2. 数据工程第一步MixFreqData 与金融宏观数据对齐GARCH-MIDAS 模型跑得动的前提是数据对齐。v2.4 代码包内附带的 INDPRO.xls、NASDAQCOM.xls、DEXJPUS.xls、DGS10.xls 分别对应工业产值指数、纳斯达克综合指数、日元/美元汇率和十年期国债收益率涵盖月度与日度两种采样频率。真正动手时第一步不是写模型而是把这些 Excel 读进 MATLAB按时间戳统一成模型要求的格式。2.1 数据文件与频率说明先看这几个.xls文件在建模过程中扮演的角色文件变量频率在模型中的角色INDPRO.xls工业产值指数月度MIDAS 低频解释变量刻画宏观基本面NASDAQCOM.xls纳斯达克综合指数日度高频收益率序列计算短期波动率DEXJPUS.xls日元/美元汇率日度可选高频资产DCC 相关性分析用DGS10.xls十年期国债收益率日度长期利率作为低频宏观变量的候选mydata.xlsx用户自定义数据混合替换默认数据集的入口这里有一个容易被忽略的关键点MIDAS 里的低频和高频是相对概念。GARCH-MIDAS 把日收益率作为高频观测把月度宏观变量作为低频驱动但 MIDAS 权重函数要求在低频时间点上把过去若干期的高频数据压缩成一个长期分量所以数据对齐的核心是建立低频时点到高频观测区间的映射表。2.2 MixFreqData.m 的数据混合逻辑MixFreqData.m 是整个代码包的数据入口核心职责是读取原始 Excel生成两个数组高频收益率序列 Y 和对齐后的低频解释变量序列 X_low。标准的混合步骤可以抽象为下面这段 MATLAB 代码% MixFreqData.m 核心逻辑简化版 % 读取日度价格数据生成日收益率 adjClose xlsread(NASDAQCOM.xls); % 读纳斯达克数据 retDaily diff(log(adjClose)); % 对数差分得到日收益率 % 读取月度宏观数据 macroData xlsread(INDPRO.xls); % 工业产值指数 macroRet diff(log(macroData)); % 宏观变量的对数增长率 % 构造低频对齐矩阵每个低频时点对应的高频观测索引 % nLow 是低频样本数nHighPerLow 是每个低频周期内的高频观测数 for t 1:nLow idxStart (t - 1) * nHighPerLow 1; idxEnd t * nHighPerLow; X_low(t, :) macroRet(t); % 低频变量在每个周期内取同一值 Y_high(idxStart:idxEnd, 1) retDaily(idxStart:idxEnd); end这段代码里有两个参数需要根据实际数据调整。nHighPerLow是每个低频周期内的高频样本数数据源是日度与月度混合时通常取 21 或 22——每月平均交易日数——但如果你的宏观数据是季度就得改成 63 左右。xlsread在读取 Excel 时默认把第一列识别为日期序列如果你的原始文件第一列不是日期需要显式指定 sheet 和 range 参数否则数据会整体错位后续所有索引全部失效。2.3 数据对齐的常见坑第一个坑是交易日历不一致。纳斯达克和外汇市场的休市日不同DEXJPUS.xls 里某一天可能没有数据而 NASDAQCOM.xls 是完整的直接diff(log(...))不会报错但收益率计算会跨过一个非交易日产生虚假的日收益。我一般会在读取后先用isnan检查缺失值对缺失价格用前值填充对缺失收益率直接用 0 填充。第二个坑是低频变量的时序起点。MIDAS 模型要求低频变量至少覆盖高频序列的整个样本期但 INDPRO 这类经济指标发布有滞后实际可用的观察值通常比收益率序列短。建议先用intersect把两个序列的时间戳公共部分切出来再进入模型估计避免索引越界。第三个坑是量纲。工业产值月度增长率的数值在 0.001 这个量级而日收益率的量级在 0.01 附近两者不在一个尺度上。GarchMidas.m 内部会对低频变量做标准化处理但如果你替换成自己的数据最好直接在预处理阶段就对新变量做一次zscore避免量纲影响 MIDAS 权重的估计结果。3. GarchMidas.m 深度拆解短期波动与长期趋势的分量估计GARCH-MIDAS 模型的核心假设是资产收益率的条件方差可以分解为两个分量短期分量遵循 GARCH(1,1) 过程长期分量则由低频宏观变量通过 MIDAS 加权方程驱动。这一分解的实际价值在于宏观变量的加入不是简单地把月度数据塞进日度模型而是通过 Beta 权重函数决定低频变量对长期波动的影响时效与方向。3.1 模型设定与目标函数模型的标准形式可以写成下面这段 MATLAB 目标函数。注意这里的params向量包含了所有待估参数估计过程利用 MATLAB 自带的fmincon做带约束的极大似然优化% GarchMidas.m 核心目标函数示意 function [llf, variance] garchMidAsObjective(params, retDaily, X_low, K) % 参数顺序mu, omega, alpha, beta, theta, w1, w2 mu params(1); omega params(2); % 长期波动分量的截距 alpha params(3); % 短期 ARCH 项系数 beta params(4); % 短期 GARCH 项系数 theta params(5); % 低频变量对长期分量的影响系数 w1 params(6); w2 params(7); % Beta 权重函数形状参数 % 计算长期分量 tau_t低频变量经 MIDAS 加权后形成 nObs length(retDaily); tau zeros(nObs, 1); for t K1:nObs xWeighted 0; for j 1:K % 权重按 Beta 分布密度函数计算 wj (j / K)^(w1-1) * (1 - j / K)^(w2-1); xWeighted xWeighted wj * X_low(t - j); end tau(t) exp(omega theta * xWeighted); end % 短期波动率 g_t 服从 GARCH(1,1) g2 ones(nObs, 1); eps2 retDaily.^2; for t 3:nObs g2(t) (1 - alpha - beta) ... alpha * eps2(t-1) / tau(t-1) ... beta * g2(t-1); end variance tau .* g2; % 对数似然 llf -0.5 * sum(log(variance) retDaily.^2 ./ variance); end从这段代码可以拆出三个关键设计。其一长期分量tau(t)不是直接取低频变量的当期值而是用过去 K 期的低频变量加权求和窗口宽度 K 由用户设定Beta 权重函数的形状参数w1和w2是待估参数。这意味着宏观因子对波动率的影响不是一次性的脉冲而是一段持续衰减的作用过程。其二短期分量g2(t)的动态方程里标准化残差用的是eps2(t-1)/tau(t-1)长期分量被剥离后才进入 GARCH 更新这保证了低频与高频分量的识别互不污染。其三exp对数链接函数保证了长期分量恒为正无需在优化时额外施加正值约束。3.2 参数初值与优化器选择GarchMidas.m 的估计调用fmincon做带约束优化时初值的设定比想象中更重要。alpha 和 beta 的标准初值可以取 0.05 和 0.90这也是传统 GARCH(1,1) 的常见估计结果theta 初值设为 0 即可因为它的符号和大小取决于低频变量与波动率的实际关系w1 和 w2 初值分别取 1 和 4对应 Beta(1,4) 权重即滞后越远影响越小的单调递减形态。优化时我习惯把约束写成参数上下界矩阵而不是用约束函数。alpha 和 beta 需要满足alpha beta 1这个线性约束在fmincon里用不等式约束矩阵可以严格给出但 theta 和 w 参数只需保证在正的可行域内。如果你发现估计结果出现alpha beta恰好等于 0.999 的边界情况别急着接受——这多半是数据中有极端值把 GARCH 项推向了单位根边界需要检查样本期是否包含 2008 年或 2020 年这类极端行情。3.3 结果解读与残差检验跑完估计后一个值得关注的指标是长期分量在总方差中的占比% 计算长期分量贡献率 longContrib var(tau) / var(variance); fprintf(长期分量方差占比: %.2f%%\n, longContrib * 100);如果这个占比低于 5%说明低频宏观变量对波动率的解释力很弱需要更换宏观指标或者调整窗口 K。反过来如果占比超过 80%说明短期波动全被宏观变量解释了GARCH 项几乎没有发挥作用这时要复查低频变量是否被错误地重复计算进了每个高频周期。残差部分标准化残差retDaily ./ sqrt(variance)应当近似白噪声用autocorr函数检查前 20 阶是否落在置信带内即可。4. DCC-MIDAS 与 ADL-MIDAS动态相关性及外生变量扩展单资产的 GARCH-MIDAS 解决的是波动率预测问题但资产配置场景下分析师更关心多资产之间的相关性是否随时间变化。DCC-MIDAS 模型在 GARCH-MIDAS 的框架上引入动态条件相关估计而 ADL-MIDAS 则允许外生变量直接影响收益率条件均值。两者在 v2.4 代码包中分别对应 DccMidas.m 与 MIDAS_ADL.m 及配套的 app 脚本。4.1 DccMidas.m 的两阶段估计流程DCC 类模型的标准做法是两步估计第一步用单变量 GARCH-MIDAS 模型为每个资产估计边际波动率第二步用标准化残差估计动态相关系数矩阵。DccMidas.m 的实现思路与之一致% DccMidas.m 两阶段估计流程简化 % 阶段 1单资产 GARCH-MIDAS 边际模型 for i 1:nAssets ret_i retDaily(:, i); [params_i, llf_i] estimateGarchMidas(ret_i, X_low, K); epsStd(:, i) (ret_i - mu_i) ./ sqrt(tau_i .* g2_i); end % 阶段 2DCC 动态相关估计 Qbar cov(epsStd); % 无条件相关矩阵 Qt zeros(T, nAssets, nAssets); a_dcc 0.05; b_dcc 0.90; % DCC 参数初值 for t 2:T Qt(:, :, t) Qbar * (1 - a_dcc - b_dcc) ... a_dcc * (epsStd(t-1, :) * epsStd(t-1, :)) ... b_dcc * Qt(:, :, t-1); end Rt corrcov(Qt(:, :, t)); % 归一化为相关系数矩阵这里有个容易踩坑的细节Qt 矩阵不直接是相关系数矩阵需要做对角线归一化。corrcov函数在 MATLAB 统计工具箱里可以完成这个转换但如果你看到某一步 Rt 对角线不是 1说明代码实际用的是 Qt 而不是归一化后的 Rt相关性的数值就会被系统性低估。DccMidas.m 与普通 DCC-GARCH 的最大区别在阶段一——边际模型被替换成了 GARCH-MIDAS每个资产的边际波动率都受到了宏观变量的影响。使用 appDCCMIDAS1.m 跑多资产时注意它默认所有资产共享同一个 K 值但实际中不同资产对宏观变量的响应速度不同。建议把 K 从 24 改成逐资产分别估计代价是计算时间翻倍但相关性的估计会更稳健。4.2 ADL-MIDAS把外生变量写进条件均值ADL-MIDAS 解决的是另一类问题收益率条件均值不是常数而是受外生变量影响。MIDAS_ADL.m 的核心方程是在标准 MIDAS 基础上把自回归滞后项与外生高频变量的 MIDAS 滞后同时放进均值方程。ssr_r25_adl_new.m 和 mfrvobj_adl.m 里面的目标函数围绕的是这个逻辑的优化实现% MIDAS_ADL.m 目标函数核心逻辑 % 均值方程: y_t mu sum_i rho_i * y_{t-i} gamma * sum_j w_j * X_{t-j} eps_t for t p1:T yLag 0; for i 1:p yLag yLag rho(i) * y(t - i); end xMid 0; for j 1:K xMid xMid wBeta(j, K, w1, w2) * X_low(t - j); end yHat(t) mu yLag gamma * xMid; resid(t) y(t) - yHat(t); endssr_r25_adl_new.m文件名里的 r25 是代码作者的经验窗口设定表示低频滞后阶数取 25配上月度宏观变量相当于覆盖两年的历史信息。ssr_r25_NN_adl_new.m是同一个模型的神经网络近似版本适合数据量大到普通极大似然跑不动的场景但对训练集长度有要求——样本少于 500 个交易日时建议用原始版本神经网络近似在小样本下反而容易过拟合。4.3 模型选择DCC-MIDAS 还是 DCC-GARCH把两组模型的样本外预测误差直接对比是最可靠的判断方法。ForecastCombine.m 提供了一种滚动预测组合机制可以在每个时间点动态调整 DCC-MIDAS 和 DCC-GARCH 的预测权重。实际经验是当宏观变量处于剧烈波动期比如工业产值月度变化率超过历史两倍标准差时DCC-MIDAS 的相关性预测显著优于 DCC-GARCH反之在平稳市况下两者的差距不超过 2 个百分点。如果你只需要每月更新一次预测DCC-GARCH 够用如果需要日度相关性预测且手头有可靠的月度宏观指标DCC-MIDAS 值得多花一些计算成本。5. 从复现到改造在你自己的数据上跑通这套代码把代码包解压后最快跑通的方式是按顺序执行 app 开头的脚本。appGARCHMIDAS1.m 对应单资产 GARCH-MIDASappDCCMIDAS1.m 对应双资产 DCC-MIDASappADLMIDAS1.m 到 appADLMIDAS4.m 对应不同外生变量组合的 ADL-MIDASappMidasQuantile1.m 则对应分位数回归的 MIDAS 版本。每个脚本都通过addpath引入 private 目录中的辅助函数所以工作目录必须设在解压后的根目录。5.1 替换数据文件的关键改动假设你要用自己的股票指数和货币供应数据替换默认的 NASDAQCOM.xls 和 INDPRO.xls需要改动的点集中在 app 脚本开头的数据加载部分% 替换数据加载原脚本中相应行 adjClose readmatrix(你的股票指数文件.xlsx, Sheet, Sheet1, Range, A2:B2000); retDaily diff(log(adjClose)); % 低频变量 macroRaw readmatrix(你的宏观指标.xlsx, Sheet, Sheet1, Range, B2:B300); macroRet diff(log(macroRaw)); % 检查样本区间是否匹配高频样本数应约为低频样本数的 21 倍 assert(height(retDaily) height(macroRet) * 21, 高频样本长度不足);这里推荐用readmatrix而不是原代码里的xlsread因为 MATLAB 2023 及以后版本中xlsread已被标记为不推荐使用虽然还能跑但每次执行都会输出 deprecation 警告。第三个参数Range要尽量精确用A2:B2000而不是A:B原因在于 Excel 读取整列时会把尾部空值读成 NaN而 MIDAS 建模过程中 NaN 会通过索引传导导致整个估计失败。5.2 波动率分解的可视化诊断跑完模型后长期分量与总波动率的对比图是最直观的诊断方式% 波动率分解可视化 plot(dates, sqrt(variance), b-, LineWidth, 1); hold on; plot(dates, sqrt(tau), r--, LineWidth, 2); legend({总波动率, 长期分量}, Location, northwest); xlabel(时间); ylabel(年化波动率);画图时注意长期分量的曲线应当比总波动率平滑得多。如果长期分量和总波动率几乎重合说明短期 GARCH 项接近于零模型退化为纯 MIDAS 结构这通常是因为 alpha 初值设置过小在fmincon里把初值改成 0.1 重新估计即可。如果长期分量曲线出现明显的阶梯状跳跃通常是低频变量在某个时间点发生了统计口径调整需要在预处理阶段对该断点做水平修正否则 MIDAS 权重会被这一个异常跳变主导。5.3 private 目录和版本兼容的注意事项最后提醒两个文档里不写的细节。第一private 目录里的文件不要乱动mfrvobj_adl.m和mfrvobj.m为目标函数文件被多个 app 脚本共享修改其中一个会影响其他脚本。第二如果要用 MATLAB 并行的 Optimization Toolbox 多核版本跑参数估计需要显式调用useParallel并设置UseParallel true但要注意 GARCH-MIDAS 的似然函数中对每个时间点有循环依赖并行加速的效果远不如单变量独立估计的 DCC 阶段明显建议优先并行阶段一的多个资产边际模型。本文还有配套的精品资源点击获取
返回列表