使用Analytic_t计算VaR时R中nlminb的NA/NaN评估警告解决咨询
问题:基于Student-t分布的Analytic_t方法计算VaR时消除NA/NaN警告
问题背景
我想用基于Student-t分布的Analytic_t方法估算99%置信水平的风险价值(VaR),编写了如下R代码:
load("stocks.Rdata") plot(S,main="stock prices") loss.returns <- -diff(log(S)) ## loss returns plot(loss.returns,main="loss returns") Analytic_t <- function(L,RM,p){ input_check(RM,p) ## estimation of model parameters require(fGarch) std_par <- stdFit(L)$par nu <- std_par[3] mu <- std_par[1] s <- std_par[2] * sqrt((nu-2)/nu) ## calculation of risk measure q <- qt(p,df=nu) if (RM=="VaR") return(mu + s * q) if (RM=="ES") return(mu + s * dt(q,df=nu) * (nu+q^2)/(nu-1)/(1-p)) } if (T){ set.seed(123) i <- sample(1:5,1) L <- loss.returns[,i] } plot(L) VaR_t <- Analytic_t(L, "VaR",0.99)
运行VaR_t <- Analytic_t(L, "VaR",0.99)时控制台出现警告:
Warning messages: 1: In nlminb(start = start, objective = loglik, lower = c(-Inf, 0, : NA/NaN function evaluation 2: In nlminb(start = start, objective = loglik, lower = c(-Inf, 0, : NA/NaN function evaluation
已知L中无缺失数据,想消除该警告。
警告产生原因
stdFit内部用nlminb做参数优化时,迭代过程可能出现无效参数组合:比如自由度nu接近2时,方差项计算会出现异常;或者尺度参数被优化到非正值区间,导致对数似然函数返回NA/NaN。虽然最终优化收敛到了有效参数,但迭代路径中触发了警告。stdFit默认的初始参数和你的数据分布不匹配,优化过程容易踩进无效参数区域。
修复方法
方法1:指定合理初始参数(推荐)
给stdFit设置贴合数据的初始参数,从根源避免优化过程出现无效值。比如用数据的均值、标准差作为位置和尺度参数的初始值,自由度初始值设为5(Student-t分布常用的合理初始值):
Analytic_t <- function(L,RM,p){ # 补充input_check函数实现(原代码未定义,否则会报错) input_check <- function(RM, p){ if (!RM %in% c("VaR", "ES")) stop("RM must be 'VaR' or 'ES'") if (p <= 0 || p >= 1) stop("p must be between 0 and 1") } input_check(RM,p) ## estimation of model parameters require(fGarch) # 指定初始参数:位置mu=均值,尺度sigma=标准差,自由度nu=5 std_par <- stdFit(L, start = c(mean(L), sd(L), 5))$par nu <- std_par[3] mu <- std_par[1] s <- std_par[2] * sqrt((nu-2)/nu) ## calculation of risk measure q <- qt(p,df=nu) if (RM=="VaR") return(mu + s * q) if (RM=="ES") return(mu + s * dt(q,df=nu) * (nu+q^2)/(nu-1)/(1-p)) }
方法2:抑制特定警告(临时方案)
如果不想调整初始参数,可通过suppressWarnings包裹stdFit调用,只抑制该优化过程的NA/NaN警告:
Analytic_t <- function(L,RM,p){ # 补充input_check函数实现 input_check <- function(RM, p){ if (!RM %in% c("VaR", "ES")) stop("RM must be 'VaR' or 'ES'") if (p <= 0 || p >= 1) stop("p must be between 0 and 1") } input_check(RM,p) require(fGarch) # 抑制nlminb的NA/NaN函数计算警告 std_par <- suppressWarnings(stdFit(L)$par) nu <- std_par[3] mu <- std_par[1] s <- std_par[2] * sqrt((nu-2)/nu) q <- qt(p,df=nu) if (RM=="VaR") return(mu + s * q) if (RM=="ES") return(mu + s * dt(q,df=nu) * (nu+q^2)/(nu-1)/(1-p)) }
内容的提问来源于stack exchange,提问作者user22168531
相关产品推荐
相关产品推荐

