4、历史模拟法VaR:历史数据重采样、排序与分位数计算、优缺点分析

历史模拟法(Historical Simulation, HS)是计算VaR最直观的非参数方法。它不假设收益率服从任何特定分布,而是直接使用过去N个交易日的实际收益率数据,通过重采样、排序和分位数提取来估计未来风险。在低延迟环境中,历史模拟法的核心挑战在于:如何高效维护滚动窗口、快速执行部分排序,以及如何在数据更新时避免全量重算。

4.1 核心计算流程

历史模拟法VaR的计算分为三个步骤:历史数据重采样、收益率排序、分位数计算。以下流程图展示了完整的处理链路。

历史模拟法VaR计算流程 历史价格窗口 N+1个收盘价 收益率序列 N个日收益率 升序排序 最小→最大 对数/简单 分位数索引 k = ceil(α × N) VaR值提取 VaR = -R(k) 排序后数组 滚动窗口更新 移除最旧,加入最新 ⚠ 低延迟关键优化点 • 使用增量排序(插入排序)代替全量排序,仅调整新加入和移除的元素 • 维护一个有序链表或跳表,使每次窗口滑动的时间复杂度从O(N log N)降至O(log N) • 对于99% VaR,只需关注尾部极值,可使用部分排序算法(如nth_element)

4.2 历史数据重采样与滚动窗口

历史模拟法使用固定长度的滚动窗口。假设当前交易日为T,窗口长度为N(通常为250、500或1000个交易日),则使用从T-N到T-1的收益率数据。

窗口长度N 对应历史跨度 适用场景 低延迟影响
250 约1年 短期交易台、高频回测 排序快,但尾部稳定性差
500 约2年 中等持仓期、资管组合 内存占用适中,排序可接受
1000 约4年 监管资本、长期风险 全量排序延迟高,需增量优化

重采样实现要点:

  • 使用循环缓冲区(circular buffer)存储收益率序列,避免每次滑动时移动大量内存。
  • 新数据到达时,覆盖最旧数据的位置,更新尾指针。
  • 在低延迟系统中,预分配固定数组,避免动态内存分配。

4.3 排序与分位数计算

排序是历史模拟法中最耗时的步骤。在低延迟环境下,必须避免每次窗口滑动都执行O(N log N)的全量排序。

4.3.1 分位数索引公式

对于置信水平α(如95%、99%),VaR对应的分位数索引为:

k = ceil(α × N)   // 从最小端开始计数
VaR = -R(k)        // R(k)为排序后第k小的收益率

例如,N=500,α=0.99时,k=ceil(0.99×500)=495,VaR取排序后第495小的收益率的相反数。

4.3.2 增量排序策略

当窗口滑动时,只有两个元素发生变化:移除最旧的收益率Rold,加入最新的收益率Rnew。利用这一特性,可以采用增量排序:

// 伪代码:增量更新有序数组
1. 在有序数组中找到R_old的位置,将其删除(O(log N))
2. 找到R_new的插入位置,将其插入(O(log N))
3. 直接通过索引k获取VaR值(O(1))

// 使用平衡二叉搜索树(如std::multiset)
// 或跳表(Skip List)实现O(log N)的插入/删除

性能对比:全量排序每次O(N log N),增量排序每次O(log N)。当N=1000时,增量排序比全量排序快约1000倍,是低延迟VaR计算的核心优化手段。

4.3.3 部分排序优化

如果只关心尾部VaR(如99% VaR),不需要对整个数组排序,只需找到第k小的元素:

// 使用std::nth_element(快速选择算法)
// 平均时间复杂度O(N),最坏O(N²)
// 适用于窗口滑动后重新计算,但不如增量排序高效

std::nth_element(returns.begin(), returns.begin() + k - 1, returns.end());
double var = -returns[k - 1];

4.4 优缺点分析

历史模拟法在实际应用中既有显著优势,也有固有缺陷。以下表格从多个维度进行对比:

维度 优点 缺点
模型假设 无分布假设,完全基于历史数据 隐含假设“历史会重复”,无法捕捉结构性变化
实现复杂度 逻辑简单,易于理解和验证 低延迟下需增量排序优化,增加实现难度
尾部风险 能捕捉历史中的极端事件(如肥尾) 尾部估计受窗口长度影响大,样本外极端事件无法体现
计算效率 增量排序后可达O(log N)更新 全量排序O(N log N),不适合超大规模组合
可归因性 可直接回溯到具体历史日期,便于解释 无法提供敏感性(如Delta、Gamma)归因
适应性 适用于非线性产品、期权组合 对市场制度变化(如波动率突变)反应滞后

低延迟环境下的避坑指南:

  • 不要在每次窗口滑动时调用全量排序——这是最常见的性能陷阱。
  • 不要使用链表实现有序序列——缓存不友好,随机访问慢。
  • 建议使用数组+跳表或B树变体,兼顾缓存局部性和有序性。
  • 建议对VaR置信水平做预计算,避免每次查询都计算ceil(α×N)。

4.5 历史模拟法的变体与改进

为了克服传统历史模拟法的缺点,业界提出了多种改进方案:

  • 加权历史模拟法(Weighted HS):对近期数据赋予更高权重,使用指数衰减权重重新采样,提高对市场变化的响应速度。
  • 过滤历史模拟法(Filtered HS):先使用GARCH等模型对收益率进行波动率调整,再对标准化残差进行历史模拟,最后反推VaR。
  • 混合历史模拟法(Hybrid HS):结合参数法(如EWMA)估计波动率,用历史模拟估计尾部形状,兼顾效率和准确性。

在低延迟系统中,加权历史模拟法因其计算结构简单(只需在排序时考虑权重),成为最常用的改进方案。