BIPV 指数的可预测性边界:滚动样本外竞赛、安慰剂检验与区间覆盖(优秀范文三)
摘要
范文一完成了清洗、联动与趋势预测,范文二做了分布诊断与概率化情景。但两篇留下一个更根本的问题悬而未决:这条指数到底有多少可预测性?复杂模型相对朴素基准的真实增益是多大? 本文把「预测」本身放上解剖台,在 BIPV 主指数的 750 个交易日上做八组实验,得到四个结论:第一,指数近乎无记忆——日涨跌自相关与绝对日涨跌自相关各查 10 个滞后共 20 组检验,仅 2 组越过 ±0.0716 的显著性带,Bonferroni 校正后无一存活;第二,样本外竞赛中朴素基准全胜——628 个样本外点上,AR(1) 的 RMSE 反而比「明天等于今天」差 0.9%,追涨型动量差 7.3%,方向命中率全部落在掷硬币 50%±3.9 个百分点的噪声带内;第三,最迷惑人的「动量多空差 +52.4%(年化)」经平移安慰剂检验后与噪声完全同阶——9 组里 7 组的朴素 t 值超过 2,但把信号整体平移 60 日得到的安慰剂值在 −20.9%~+27.0% 之间游走,表观超额回报全是抽样噪声;第四,可预测性的真正残值在风险管理而非点位预测——EWMA 自适应方差虽让 QLIKE 略逊于常数方差,却把 95% 区间的实际覆盖从 93.5% 拉回 94.8%,在最动荡的 21 日里把区间违约从 3 次压到 1 次。本文的方法论警告同样重要:低 MAPE 是幻觉,高 t 值会骗人,只有样本外竞赛加安慰剂检验才是硬标准。
一、问题重述与数据
赛题以光伏建筑一体化(BIPV)板块指数为对象,要求清洗、联动分析与发展趋势预测。范文一的 Holt 与机器学习模型报告了 1.13%/1.02% 的 MAPE,看似「预测得很准」;范文二测得五板块超额峰度均在 ±0.4 以内,分布接近高斯。
本文不改前两篇的任何数字,只追问一个被 MAPE 掩盖的问题:如果明天真的不可知,这些指标会是多少? 我们复用范文一的确定性面板(750 个交易日、5 个板块指数、BIPV 年化波动 21.1%),把全部实验设计成「训练窗 120 日、其后逐日滚动」的样本外形式,用四把尺子度量可预测性:自相关体检、误差比、方向命中、区间覆盖。
二、结果 I:记忆体检
图 1 对 BIPV 对数日涨跌与其绝对值分别计算滞后 1~10 的自相关函数。日涨跌侧最大自相关仅 0.0741,一阶自相关更是只有 +0.0055;绝对值侧最大 0.0813。以 ±1.96/√n = ±0.0716 为显著带,20 组检验里只有 2 组越带——而当一次家族里做 20 个检验时,5% 假阳性率的期望就是约 1 组越带,实测 2 组与期望完全相容。换用 Bonferroni 校正带(±0.1027)后无一显著。
这为全文定下基调:均值无记忆,波动也无记忆。任何声称能利用「历史模式」的模型,都必须先过样本外这一关。
三、结果 II:单步样本外模型竞赛
图 2 是全文的核心实验。训练窗 120 日、逐日滚动重新估计,在 628 个样本外点上比较四个模型的 RMSE,「朴素基准」(预测明天涨跌为零,即水平平推)定为 1.0000:AR(1) 为 1.0091,半仓反转为 1.0459,五日动量为 1.0725——三个「聪明」模型全军覆没,没有一个跑赢什么都不做的平推。
机理很直白:AR(1) 拟合出的自回归系数在总体本应为零,样本内的微小非零纯粹是噪声拟合,到样本外只会叠加方差;动量类策略则把近五日的平均涨跌直接当作明天的预期,等于赌「惯性存在」,而无记忆序列对这种赌注的惩罚恰好是其额外波动。范文一 1.13% 的 MAPE 在这里得到了解释——日涨跌本身只有 1.3% 量级的标准差,平推就能拿到同级误差,低 MAPE 度量的不是洞察力,而是序列本身的平静程度。
四、结果 III:预测视界衰减
预测误差指标
平均绝对误差(MAE)与均方根误差(RMSE)评估预测精度:
MAE对异常值鲁棒,RMSE对大误差更敏感。相对误差MAPE便于跨数据集比较:
图 3 把竞赛拉长到多步视界:h=1/5/10/20 日时,AR(1) 迭代预测的相对误差 RMSE 与朴素平推之比为 1.0289/1.0223/1.0389/1.0653。即便 h=1 处 AR(1) 落后的幅度不大(1.364% 对 1.326%),随视界拉长劣化单调加深——h=20 时 AR(1) 已差出 6.5%。多步迭代会把一阶自相关的微小偏差按几何级数放大(φ 的各次幂累加进累计漂移),而朴素平推的误差只随视界的平方根增长。结论对实践者很友好:越是要看中长期,越应该承认「平推」的正当性,把精力转向区间而不是点位。
五、结果 IV:方向命中率的真相
图 4 检查另一个常被误读的指标:涨跌方向的命中率。628 个样本外点上,朴素 48.25%、AR(1) 50.32%、五日动量 52.07%、半仓反转 47.93%,二项 95% 置信半宽均为 ±3.91 个百分点——四个模型的置信区间全部覆盖 50%。动量的 52.07% 看似最有希望,但要把 52.07% 与 50% 区分开需要约 (1.96×0.5/0.0207)² ≈ 2237 个样本外点,现有样本量远远不够。
值得强调的是命中率与 RMSE 的背离:动量命中率最高、RMSE 却最差(1.0725),因为它猜对了方向时往往幅度很小、猜错时幅度很大。单一指标的「好看」在无记忆序列上是纯粹的陷阱。
六、结果 V:动量谱与安慰剂检验
图 5 是全文方法论上最重要的一张图。我们按「过去 f 日累计涨跌的符号」分组、持有 k 日,扫 f/k ∈ {5,10,20}² 共九组组合,记录多空差(年化):最高的一组 f=10/k=5 达到 +52.42%,f=5/k=10 为 +40.98%。按连续分块算出的 t 值,九组里有七组超过 2——如果止步于此,这是一份多么诱人的「动量发现」。
但我们补做了平移安慰剂:把信号整体向后平移 60 日再分组,九组的「多空差」变成 −20.9%~+23.5%;平移 120 日则在 −4.7%~+27.0% 之间。安慰剂值与真实信号同量级交错,说明分块 t 值系统性低估了不确定性——重叠的前向窗口让相邻观测高度相关,区块间标准误形同虚设。真实的多空差没有一组能把自己从安慰剂分布里分离出来。这个教训值得写进每一份量化报告:t 值骗了你,安慰剂才是硬标准。
七、结果 VI:波动同样无记忆
均值不可测并不自动意味着「波动可测」,图 6 直接检验这一点。以 QLIKE 损失比较 EWMA(λ=0.94)与常数方差的单步波动预测:EWMA 2.2643 反而高于常数方差的 2.2388;解释 |r| 的 R² 只有 0.0003,作为对照,解释 r 本身的 R² 是 0.00026——两侧双双归零。在这块近 iid 的面板上,连金融计量里最稳健的「波动聚集」现象都不存在,EWMA 的递更新息无从发力。
这与范文二的分布诊断(峰度 ±0.4 以内)互相印证:当创新项接近独立高斯时,一切条件异方差模型都退化为昂贵的常数。因此下一节的结果才显得珍贵——自适应方差虽不改善点预测,却在别处创造价值。
八、结果 VII:收缩曲线
图 7 给「模型融合派」一个量化回答:把 AR(1) 预测按权重 w 与朴素预测混合,扫描 w 从 0 到 1,样本外 RMSE 在 w*=0.15 处取得谷底,但相对纯朴素的增益只有 0.026%(0.01331→0.01330),而整条曲线的最大落差也不足千分之九。「最优融合权重」存在的统计证据如此之弱,以至于调它纯属数据挖掘。面对无记忆序列,收缩的方向只有一个:一路收到朴素。
九、结果 VIII:区间覆盖率的启示
图 8 是可预测性搜索中唯一的正面收获。用「零预期 ±z 倍标准差」构造单步预测区间,名义 90% 时 EWMA 方差的实现覆盖 89.0%,常数方差 87.9%;名义 95% 时两者分别为 94.8% 与 93.5%——EWMA 在两个水平上都更贴近名义值。差距在最动荡的 21 日窗口里拉大:95% 区间的违约次数 EWMA 仅 1 次、常数方差 3 次。
机理在于 EWMA 的「快速遗忘」:即便序列无真聚集,近期实现波动仍是对下期波动的有限信息,自适应估计在动荡段自动放宽区间、在平静段收窄,等于免费的风险节气阀。这为赛题的「不确定性讨论」给出了正确姿势:不要试图预测点位,把预算花在让区间可信上。
十、结论
八组实验共同画出了一条清晰的可预测性边界:
- 均值侧:自相关 20 组检验 Bonferroni 后无一显著,样本外竞赛朴素全胜,方向命中率全部落在噪声带;
- 事件侧:动量谱的表观超额(最高年化 +52.4%)被平移安慰剂完全覆盖,分块 t 值因重叠窗口而失效;
- 波动侧:QLIKE 上 EWMA 不敌常数方差,两个 R² 归零,条件异方差在本面板不存在;
- 风险侧:EWMA 把 95% 区间覆盖拉回 94.8%、动荡段违约 3→1 次,可预测性的残值全部兑现在区间管理上。
对建模者,本文的忠告是三句话:先用朴素基准定锚,再用安慰剂检验排除幻觉,最后把剩余精力投入区间而非点位。 这三步不依赖任何高深模型,却能过滤掉绝大多数「看起来能赚」的伪发现。
十一、模型验证(四路一致)
本文正文、配图、附录代码、真源 tools/gen_dgcup2020b_3.py 四路数字完全一致。面板复用 gen_dgcup2020b.py 的固定种子输出,本脚本所有实验为确定性统计计算、不含新随机数,双跑逐位一致;附录代码块可在 tools/ 目录下独立运行复现全部关键数字(ACF 体检、628 点样本外竞赛、四档视界、九组动量谱与两组安慰剂、QLIKE 对比、21 点收缩曲线、两种名义水平的覆盖率)。
参考文献
[1] 电工杯全国大学生数学建模竞赛组委会. 2020 年 B 题:光伏建筑一体化板块指数发展趋势分析及预测.
[2] Box, G. E. P., Jenkins, G. M. Time Series Analysis: Forecasting and Control. Holden-Day.
附录:核心 Python 实现
import sys, os
_HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.abspath(os.path.join(_HERE, "..", "..", "..", "tools")))
import gen_dgcup2020b_3 as SRC
r = SRC.gen_dgcup2020b_3()
# E1 记忆体检
e = r["e1"]
print("E1 带±%.4f r_max=%.4f abs_max=%.4f" % (e["band"], e["r_max"], e["abs_max"]))
# E2 样本外竞赛
for k in ("naive", "ar1", "mom5", "half_rev"):
v = r["e2"][k]
print("E2 %-8s RMSE比 %.4f 命中 %.2f%%" % (k, v["ratio"], v["hit_pct"]))
# E3 视界衰减
for h, v in sorted(r["e3"].items()):
print("E3 h=%d 比 %.4f" % (h, v["ratio"]))
# E5 动量谱与安慰剂
for kk, v in sorted(r["e5"].items()):
print("E5 f=%d k=%d WML %+.2f%% 安慰剂60 %+.1f%% 120 %+.1f%%"
% (kk[0], kk[1], v["wml_ann_pct"], v["placebo60"], v["placebo120"]))
# E6/E7/E8
print("E6 QLIKE ewma %.4f const %.4f R2|r|=%.4f"
% (r["e6"]["qlike_ewma"], r["e6"]["qlike_const"], r["e6"]["r2_abs"]))
print("E7 w*=%.2f 增益 %.3f%%" % (r["e7"]["best_w"], r["e7"]["gain_pct"]))
for nom, v in r["e8"].items():
if isinstance(v, dict):
print("E8 名义%.0f%% EWMA %.1f%% 常数 %.1f%%"
% (nom * 100, v["ewma_cov_pct"], v["const_cov_pct"]))