快速贷款利率计算大量贷款

时间:2012-12-13 21:43:27

标签: r finance

我有一个大数据集(大约20万行),每行都是贷款。我有贷款金额,付款数量和贷款支付。 我正试图获得贷款利率。 R没有计算它的函数(至少基数R没有它,我找不到它)。 编写npv和irr函数并不困难

Npv <- function(i, cf, t=seq(from=0,by=1,along.with=cf)) sum(cf/(1+i)^t)
Irr <- function(cf) { uniroot(npv, c(0,100000), cf=cf)$root }

你可以做到

rate = Irr(c(amt,rep(pmt,times=n)))

问题是当您尝试计算大量付款的费率时。因为uniroot没有矢量化,并且因为rep需要花费大量时间,所以最终会导致计算速度变慢。如果你做一些数学运算并发现你正在寻找以下等式的根

,你可以加快速度
zerome <- function(r) amt/pmt-(1-1/(1+r)^n)/r

然后将其用作uniroot的输入。在我的电脑上,这需要大约20秒来运行我的200k数据库。

问题是我正在尝试做一些优化,这是优化的一个步骤,所以我试图加快它的速度。

我尝试了矢量化,但由于uniroot没有矢量化,我不能再这样了。是否存在任何矢量化的根发现方法?

由于

1 个答案:

答案 0 :(得分:7)

您可以使用线性插值器,而不是使用根查找器。您必须为n的每个值(剩余付款的数量)创建一个插补器。每个插补器都会将(1-1/(1+r)^n)/r映射到r。当然,您必须构建足够精细的网格,以便将r返回到可接受的精度级别。这种方法的好处在于线性插值器具有快速和矢量化的特点:您可以在对相应插补器的单次调用中找到具有相同剩余支付数量(n)的所有贷款的费率。

现在有些代码证明这是一个可行的解决方案:

首先,我们创建插值器,每个可能的值为n

n.max <- 360L  # 30 years

one.interpolator <- function(n) {
    r <- seq(from = 0.0001, to = 0.1500, by = 0.0001)
    y <- (1-1/(1+r)^n)/r
    approxfun(y, r)
}

interpolators <- lapply(seq_len(n.max), one.interpolator)

请注意,我使用了1/100百分比(1bp)的精度。

然后我们创建一些假数据:

n.loans <- 200000L
n     <- sample(n.max, n.loans, replace = TRUE)
amt   <- 1000 * sample(100:500, n.loans, replace = TRUE)
pmt   <- amt / (n * (1 - runif(n.loans)))
loans <- data.frame(n, amt, pmt)

最后,我们解决r

library(plyr)
system.time(ddply(loans, "n", transform, r = interpolators[[n[1]]](amt / pmt)))
#    user  system elapsed 
#   2.684   0.423   3.084

这很快。请注意,某些输出速率为NA,但这是因为我的随机输入毫无意义,并且会返回我选择的[0~15%]网格之外的速率。你的真实数据不会有这个问题。