You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R中使用cvar包计算参数化Expected Shortfall结果不符排查求助

问题排查与修正:cvar包与自定义/QRM包ES结果不一致

核心问题

你的代码出现结果差异的原因有两个:

  1. ES的方向定义不匹配:自定义函数和QRM的ESnorm计算的是收益分布的右尾ES(收益高于95%分位数的条件期望),而cvar包默认计算的是损失分布的上侧ES(对应收益的左尾ES),方向完全相反。
  2. 分布参数传递错误:直接传递pnorm给cvar的ES函数时,mean和sd无法正确绑定到分布函数上,导致计算用的是标准正态分布而非你指定的参数分布。

修正后的代码

# 自定义正态分布ES函数(右尾)
calculate_expected_shortfall <- function(mean, sigma, alpha) {
  z_alpha <- qnorm(alpha)
  phi_z_alpha <- dnorm(z_alpha)
  mean + sigma * (phi_z_alpha / (1 - alpha))
}

# 参数配置
mean <- 100   
sigma <- 15   
alpha <- 0.95 

# 方法1:自定义函数
es_custom <- calculate_expected_shortfall(mean, sigma, alpha)

# 方法2:QRM包(默认右尾ES)
library(QRM)
es_qrm <- ESnorm(0.95, mu = mean, sd = sigma)

# 方法3:修正后的cvar包调用(两种有效方式)
library(cvar)
# 方式A:用分位数函数qnorm,直接指定右尾ES
es_cvar_qf <- ES(qnorm, dist.type = "qf", p_loss = alpha, mean = mean, sd = sigma, side = "upper")

# 方式B:用匿名函数绑定pnorm参数,指定右尾ES
es_cvar_cdf <- ES(
  function(q) pnorm(q, mean = mean, sd = sigma),
  dist.type = "cdf", 
  p_loss = 1 - alpha, 
  side = "upper"
)

# 验证一致性
cat("自定义函数结果:", round(es_custom, 4), "\n")
cat("QRM包结果:", round(es_qrm, 4), "\n")
cat("cvar包(分位数函数)结果:", round(es_cvar_qf, 4), "\n")
cat("cvar包(CDF匿名函数)结果:", round(es_cvar_cdf, 4), "\n")

关键修正说明

1. 对齐ES方向

  • 自定义函数和ESnorm的alpha=0.95对应右尾5%的极端收益,cvar包需要通过side="upper"指定计算上侧(右尾)ES,并调整p_loss参数:
    • 用分位数函数时,p_loss=alpha=0.95直接对应收益的95%分位数。
    • 用CDF时,p_loss=1-alpha=0.05表示右尾5%的概率区间。

2. 正确传递分布参数

  • 使用分位数函数qnorm时,mean和sd可直接通过...参数传递给qnorm,无需额外处理。
  • 使用CDF时,必须用匿名函数将mean和sd绑定到pnorm上,否则cvar会默认使用标准正态分布进行计算。

验证结果

运行修正后的代码,四个结果将完全一致(约为130.9402),符合你的预期。

内容的提问来源于stack exchange,提问作者R_us3r

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 00:05:03