带置信水平的损失上限
在险价值回答的是:在糟糕的一天(但不是最糟的一天)我可能亏多少?一日 95% 的 VaR 为 2%,意思是每 100 天里有 95 天亏损不应超过 2%。历史法不需要任何模型:取过去的收益率,排序,读出第 5 个百分位处的亏损,VaR 就是这个分位数取负。监管和风险限额到处都在用它,因为它是一个可以和限额比较的单一数字。
import numpy as np
rng = np.random.default_rng(3)
returns = rng.normal(0.0004, 0.012, size=500) # two years of daily returns
var_95 = -np.quantile(returns, 0.05) # minus the 5th percentile
var_99 = -np.quantile(returns, 0.01)
print(round(float(var_95), 5), round(float(var_99), 5)) # 0.01928 0.027 the 99% loss limit is larger检验 VaR:突破次数
VaR 是一种预测,所以可以检验。突破指亏损超过 VaR 的那一天,即 return < -VaR。95% 的 VaR 预期约有 5% 的天数突破:多得多说明模型低估了风险,少得多则说明过于保守。监管机构以 250 天为窗口统计突破次数,正是为此。注意是严格不等号:恰好等于 VaR 的亏损不算突破。
import numpy as np
rng = np.random.default_rng(3)
returns = rng.normal(0.0004, 0.012, size=500)
var_95 = -np.quantile(returns, 0.05)
exceptions = int(np.sum(returns < -var_95))
print(exceptions, "exceptions in", len(returns), "days; expected about", int(0.05 * len(returns))) # 25 25更长的期限,以及还原当时
经常要求 10 日 VaR。若每日收益相互独立,波动率随时间的平方根增长,因此平方根时间规则这样换算:VaR_T = VaR_1 * sqrt(T)。这只是近似,对厚尾和自相关的收益效果更差。诚实的回测还要尊重时间:第 t 天使用的 VaR 只能用第 t 天之前的收益,这与避免前视偏差是同一种纪律。滚动 VaR 就是用最近 n 天的窗口来做到这一点。
# The square-root-of-time rule for several horizons
import math
one_day = 0.0186
for days in (1, 5, 10, 20):
print(days, round(one_day * math.sqrt(days), 4)) # 1: 0.0186, 5: 0.0416, 10: 0.0588, 20: 0.0832import numpy as np
def historical_var(returns, confidence):
return float(-np.quantile(returns, 1 - confidence))
def rolling_var(returns, window, confidence):
out = np.full(len(returns), np.nan)
for t in range(window, len(returns)):
out[t] = historical_var(returns[t - window:t], confidence) # the days BEFORE day t
return out
rng = np.random.default_rng(3)
returns = rng.normal(0.0004, 0.012, size=500)
rolling = rolling_var(returns, 250, 0.99)
print(np.isnan(rolling[:250]).all(), round(float(rolling[250]), 5), round(float(rolling[-1]), 5))
exceptions = int(np.sum(returns[250:] < -rolling[250:]))
print(exceptions, "exceptions in", len(returns) - 250, "days (about 2 expected at 99%)")
print(round(historical_var(returns, 0.99) * np.sqrt(10), 5)) # a 10-day figure by the square-root ruleVaR 没有告诉你的事VaR 是一个阈值,不是最坏情形:它没有说明超过阈值之后的亏损有多严重,所以后面几节会讲预期损失和压力测试。历史法的好坏取决于窗口:平静的两年会在危机前给出很小的 VaR,而 99% 的数字只依赖少数几个观测。
- 历史 VaR 是过去收益率
(1 - confidence)分位数取负(np.quantile):无需模型的正损失比例。 - 通过统计突破(
return < -VaR)来回测:约占1 - confidence的天数;更多说明 VaR 偏低。 - 用
var * sqrt(days)换算期限;滚动窗口只用之前的天数;VaR 给出阈值,而不是超出部分的损失大小。
下一节:参数化 VaR,用正态分布而不是原始历史来计算同一个阈值。
实验:评分内容
- 用
historical_var从历史中读出损失25 分 - 用
var_exceptions统计突破次数25 分 - 用
scale_var拉长期限25 分 - 用
rolling_var还原当时的估计25 分