R 用optim计算内部收益率

R 用optim计算内部收益率,r,finance,irr,R,Finance,Irr,我想用optim函数找到内部收益率(IRR),基本上就是使净现值函数变为零的“利率” 我目前的净现值功能代码(有效)是: 如果您只需要计算IRR或NPV(或MIRR),并且不清楚为什么您绝对需要使用 OpTime/Cult>,那么您可以简单地考虑包财务或 FiCala,而不是入侵您自己的函数。像这样: > require(financial) > cf(c(-123400, 36200, 54800, 48100), i = 2.5) Cash Flow Model Flows:

我想用
optim
函数找到内部收益率(IRR),基本上就是使净现值函数变为零的“利率”

我目前的净现值功能代码(有效)是:


如果您只需要计算IRR或NPV(或MIRR),并且不清楚为什么您绝对需要使用<代码> OpTime/Cult>,那么您可以简单地考虑包<代码>财务<代码>或<代码> FiCala<代码>,而不是入侵您自己的函数。像这样:

> require(financial)
> cf(c(-123400, 36200, 54800, 48100), i = 2.5)

Cash Flow Model

Flows:
      1       2       3       4 
-123400   36200   54800   48100 

 IRR%: 5.96 
 NPV Extremes at I%:  

   I%     NPV     NFV     NUS
1 2.5 8742.13 9414.32 3060.95

> require(FinCal)
> npv(c(-123400, 36200, 54800, 48100), r = 0.025)
[1] 8742.134
> irr(c(-123400, 36200, 54800, 48100))
[1] 0.05959787

有一个很酷的例子,使用
optim
通过

####IRR函数:获取支付向量并返回一个列表,其中包括内部回报率($IRR)和可能的警告词($当心)----

irr好吧,我可以看到一个问题,它可能不是唯一的:
optim
优化函数中的第一个参数(例如,
rate
,它是函数
npv
中的标量)。您提供的初始值是两个元素的向量,因此
optim
将抛出一个错误。您可以将初始值设为标量以解决此问题,或者将
速率
打包到
npv
中的向量中。但是,当我试图复制此问题时,我遇到了一个与您不同的错误,因此可能需要尝试修复和更新。@tkmckenzie我理解您的意思。然而,我对这个网站(或一般的编程)非常陌生,不知道如何在npv中将速率和值打包成向量。有没有可能再详细说明一下,或者让我找到一个相关的链接?非常感谢你的帮助。啊,很抱歉,这没有帮助我也遇到了角色限制(很抱歉,我想把这作为一个答案,但我不确定这是否真的解决了问题)。你想做的是
npv@tkmckenzie,很抱歉,我仍然没有完全理解你,好像我们将速率嵌入到npv函数中,我无法指定(因此优化)速率。我试着用粗体的npv制作所有向量。请问为什么不使用
FinCal
软件包中的
irr
irr1 <- function(cf) {
    uniroot(npv, c(0, 1), cf=cf)$root
}
> require(financial)
> cf(c(-123400, 36200, 54800, 48100), i = 2.5)

Cash Flow Model

Flows:
      1       2       3       4 
-123400   36200   54800   48100 

 IRR%: 5.96 
 NPV Extremes at I%:  

   I%     NPV     NFV     NUS
1 2.5 8742.13 9414.32 3060.95

> require(FinCal)
> npv(c(-123400, 36200, 54800, 48100), r = 0.025)
[1] 8742.134
> irr(c(-123400, 36200, 54800, 48100))
[1] 0.05959787
### IRR Function:  Takes a vector of payments and returns a list which includes the internal rate of return ($IRR) and possible word of warning ($beware) ----

irr <- function(x, period = 1, starting.value = .1){

### This should detect the number of sign changes.  Should correctly not warn if there are many negative cash flows (so long as there is only 1 change in sign).

    irr.func <- function(r){ ( sum(x / (1 + r)^{0:(length(x)-1)}) )^2 }
    result <- optim(par = starting.value, fn = irr.func, method = "Brent", lower = -1000000, upper = 1000000)

    ## detecting number of sign changes
    x.ge.0 <- 1 * (x >= 0)
    changes <- diff(x.ge.0)
    changes <- changes * changes
    num.changes <- sum(changes)

    if( num.changes > 1) {

        statement <- "Your cash flows change more than once -- so you may have multiple IRRs. This function will only return the first IRR it finds. To find the others, you can try different starting values.  However, note the IRR does not make sense if the signs change more than once (try Modified IRR or NPV)."
        value <- period * result$par
        return(list(beware = statement, IRR = value))

    } else {

        return(list(IRR = period * result$par))

    }
}
### Modified IRR (MIRR) Function:  Takes a vector of payments and returns the MIRR by ----

mirr <- function(x, period = 1, starting.value = .1, discount.rate = 0.1, investment.rate = 0.05){

    ## move cash flows
    ## negative
    cf.neg <- (x < 0) * x
    ## discounted
    pv.cf.neg <- cf.neg / (1 + discount.rate)^{0:(length(x)-1)}
    pv <- sum(pv.cf.neg)

    ## positive
    cf.pos <- (x > 0) * x
    fv.cf.pos <- cf.pos * (1 + investment.rate)^{0:(length(x)-1)}
    fv <- sum(fv.cf.pos)

    mirr.per.period <- ( fv / abs(pv) )^{1 / (length(x))} - 1

    return( period * mirr.per.period )
}