跳到正文
格致开物MATHWIKI

条件风险价值

条件风险价值(conditional value-at-risk,CVaR)衡量损失分布中最坏一部分概率质量的平均损失。约定损失越大越不利,置信水平为 0<α<1,所考察的尾部概率为 1−α。离散分布在分位数处可能集中一整块概率,尾部只需取其中一部分;这正是它与直接条件平均容易混淆的地方。

三种损失与部分尾部

设损失L以概率1/2、3/10、1/5分别取0、2、10。置信水平 α=7/10 时,下分位数即风险价值为 q=VaRα(L)=inf⁡{t:Pr⁡(L≤t)≥α}=2. 最坏三成概率包含全部的“损失10”情景,占两成;还需要从“损失2”的三成概率中取一成,才能凑齐三成。所以 CVaR0.7(L)=(1/5)⋅10+(1/10)⋅23/10=223≈7.333333. 直接算 𝔼[L∣L≥2]=(2+3/5)/(1/2)=26/5=5.2,却把损失2的全部三成概率都放进了尾部;而 𝔼[L∣L>2]=10 又只取了两成。两者都不是这里的CVaR。

最坏三成尾部由两块概率质量组成
损失十的两成质量全部选入,损失二的三成质量只选入一成;金色总质量为0.3。

有解变式取 α=0.8,尾部只需两成,恰好全部由损失10构成,所以CVaR为10。此时按下分位数约定,VaR仍为2;只要稍微提高α,VaR便跳到10。概率质量的边界与分位数约定必须一并说明。

一个把尾部写成最小值的定义

对任意实值可积损失 𝔼|L|<∞,定义 CVaRα(L)=mint∈ℝΨα(t),Ψα(t)=t+𝔼(L−t)+1−α. t是可调阈值。第一项提高基准,第二项只累计超过阈值的部分;二者平衡便选出正确分位数。该变分公式适用于有原子的分布,不能仅用连续分布的条件期望公式代替。[1]

下面证明阈值和部分尾部的关系。对每个固定损失值,(L−t)+ 关于t凸,故其期望以及Ψ均凸且有限。并且 Ψ(t)≥t,当t趋于正无穷时趋于正无穷;由 (L−t)+≥L−t 又得 Ψ(t)≥[𝔼L−αt]/(1−α),当t趋于负无穷时也趋于正无穷。连续凸函数因而达到最小值。

正部函数关于t的左导数是 −𝟏{L≥t},右导数是 −𝟏{L>t}。差商绝对值不超过一,可将极限移入期望。令 F(t)=Pr⁡(L≤t),便得到 Ψ'−(t)=F(t−)−α1−α,Ψ'+(t)=F(t)−α1−α. 凸函数在t最小,当且仅当左斜率不正、右斜率不负,即 F(t−)≤α≤F(t)。因此下分位数q必是最小阈值之一;当F在α处有水平区段时,最优阈值还可能是一整段。

在q处展开正部期望,有 CVaRα(L)=𝔼[L𝟏{L>q}]+q[F(q)−α]1−α. 严格超过q的概率为 1−F(q),还差的尾部质量是 F(q)−α;由分位数条件,该差不超过q处的原子概率。于是公式恰好是“取最坏的 1−α 质量再平均”,主例的一成部分质量由此导出。连续分布在该分位数无原子时,补入量为零,才化成通常的上尾条件平均。

阈值目标的最小值与最优区间
α为0.7时最优阈值为二;α为0.8时从二到十整段目标恒为十。

主例中 Ψ0.7(2)=22/3,阈值2唯一最优;变式 Ψ0.8(t)=10 对所有 t∈[2,10] 成立。CVaR的值唯一不代表最优阈值唯一,程序若只返回其中一个阈值也不应宣称找到全部最优阈值。

情景规划、凸性与概率约束

若S个情景损失为 Ls(x),概率 ps≥0、总和一且不随x改变,可引入 us≥0、us≥Ls(x)−t,最小化 t+∑spsus/(1−α)。给定x,t后取最小可行u即为正部,因此与原变分式等价。损失仿射、决策硬约束线性时得到线性规划;损失关于x凸时,联合目标 t+∑spsmax⁡(Ls(x)−t,0)/(1−α) 凸,对t取最小仍给x的凸函数。后者可由任意两组决策与最优阈值的凸组合直接验证。

由q处公式或 Ψ(q)≥q 可知CVaR不小于VaR。因此 CVaRα(Z)≤0 蕴含 Pr⁡(Z≤0)≥α,可作为机会约束的一种保守替代,反向一般不成立。例:Z以九成概率为−100、一成概率为1,Pr⁡(Z≤0)=0.9,但 CVaR0.9(Z)=1>0。CVaR还约束尾部损失大小,概率约束只限制是否越界。

两条独立计算路径

下例使用 Python 3 标准库有理数,先在所有有正概率的损失断点计算Ψ,再独立从最大损失向下截取指定尾部质量,两条路径必须一致。输入有限“损失、概率”对和α;概率用十进制数、字符串或Fraction精确指定,总和须恰为一。函数复制合并输入,返回下VaR、CVaR、达到最小值的断点及被截取的质量,不改写输入。枚举S个断点各求一次S项和需 O(S2) 算术操作,另需排序;空间为 O(S),有理数位数成本另计。

Python 3
from fractions import Fraction

def finite_cvar(scenarios,alpha):
    alpha = Fraction(str(alpha))
    if not 0 < alpha < 1:
        raise ValueError("alpha must lie strictly between zero and one")
    masses = {}
    for loss,probability in scenarios:
        z,p = Fraction(str(loss)),Fraction(str(probability))
        if p < 0:
            raise ValueError("nonnegative probabilities required")
        if p:
            masses[z] = masses.get(z,Fraction(0))+p
    if sum(masses.values()) != 1:
        raise ValueError("probabilities must sum exactly to one")
    ordered = sorted(masses.items())
    cdf,q = Fraction(0),None
    for z,p in ordered:
        cdf += p
        if q is None and cdf >= alpha:
            q = z
    psi = lambda t:t+sum(p*max(z-t,0) for z,p in ordered)/(1-alpha)
    table = [(t,psi(t)) for t,_ in ordered]
    value = min(v for _,v in table)
    optimal_breakpoints = [t for t,v in table if v == value]
    remaining,numerator,tail = 1-alpha,Fraction(0),[]
    for z,p in reversed(ordered):
        used = min(p,remaining)
        if used:
            tail.append((z,used))
            numerator += z*used
            remaining -= used
        if not remaining:
            break
    assert numerator/(1-alpha) == value
    return q,value,optimal_breakpoints,tail

data = [(0,.5),(2,.3),(10,.2)]
for alpha in (.7,.8):
    print(alpha,finite_cvar(data,alpha))
assert finite_cvar(data,.7)[1] == Fraction(22,3)
assert finite_cvar([(-100,.9),(1,.1)],.9)[1] == 1

输出α=0.7时VaR为2、CVaR为22/3,尾部由损失10的1/5和损失2的1/10组成;α=0.8时CVaR为10,最优断点为2、10,两者之间整段也最优。若损失不可积,有限实数的论证失效;若用抽样情景估计原分布,程序精确得到的是情景模型的风险,仍须另查抽样与模型误差。

参考文献

  1. ↑ Rockafellar and Uryasev, Conditional Value-at-Risk for General Loss Distributions,作者稿2001年11月28日版,§2—3,命题8、定理10及推论11;发表于Journal of Banking & Finance 26 (2002)。