【问题标题】:What function does .NET NPV() use? Doesn't match manual calculations.NET NPV() 使用什么函数?与人工计算不符
【发布时间】:2010-06-17 23:44:54
【问题描述】:

我在 VB.NET 中使用 NPV() 函数来获取一组现金流的 NPV。

但是,NPV() 的结果与我手动执行计算的结果不一致(Investopedia NPV calc... 也不符合我的手动结果)

我的正确手动结果和 NPV() 结果很接近,在 5% 以内。但不一样...

手动使用 NPV 公式: NPV = C0 + C1/(1+r)^1 + C2/(1+r)^2 + C3/(1+r)^3 + .... + Cn/(1+r)^n

手动结果存储在 RunningTotal 中 率 r = 0.04 周期 n = 10

这是我的相关代码:

编辑:我在某处有 OBOB 吗?

    YearCashOutFlow = CDbl(TxtAnnualCashOut.Text)
    YearCashInFlow = CDbl(TxtTotalCostSave.Text)

    YearCount = 1

    PAmount = -1 * (CDbl(TxtPartsCost.Text) + CDbl(TxtInstallCost.Text))
    RunningTotal = PAmount
    YearNPValue = PAmount
    AnnualRateIncrease = CDbl(TxtUtilRateInc.Text)

    While AnnualRateIncrease > 1
        AnnualRateIncrease = AnnualRateIncrease / 100
    End While
    AnnualRateIncrease = 1 + AnnualRateIncrease

    ' ZERO YEAR ENTRIES
    ListBoxNPV.Items.Add(Format(PAmount, "currency"))
    ListBoxCostSave.Items.Add("$0.00")
    ListBoxIRR.Items.Add("-100")
    ListBoxNPVCum.Items.Add(Format(PAmount, "currency"))
    CashFlows(0) = PAmount
    ''''

    Do While YearCount <= CInt(TxtLifeOfProject.Text)
        ReDim Preserve CashFlows(YearCount)

        CashFlows(YearCount) = Math.Round(YearCashInFlow - YearCashOutFlow, 2)
        If CashFlows(YearCount) > 0 Then OnePos = True


        YearNPValue = CashFlows(YearCount) / (1 + DiscountRate) ^ YearCount
        RunningTotal = RunningTotal + YearNPValue

        ListBoxNPVCum.Items.Add(Format(Math.Round(RunningTotal, 2), "currency"))
        ListBoxCostSave.Items.Add(Format(YearCashInFlow, "currency"))

        If OnePos Then
            ListBoxIRR.Items.Add((IRR(CashFlows, 0.1)).ToString)
            ListBoxNPV.Items.Add(Format(NPV(DiscountRate, CashFlows), "currency"))
        Else
            ListBoxIRR.Items.Add("-100")
            ListBoxNPV.Items.Add(Format(RunningTotal, "currency"))
        End If

        YearCount = YearCount + 1
        YearCashInFlow = AnnualRateIncrease * YearCashInFlow
    Loop

编辑:使用以下值: 折扣率 = 4% 项目寿命 = 10 年 现金流量 0 = -78110.00 现金流量 1 = 28963.23 现金流 2 = 30701.06 现金流 3 = 32543.12 现金流 4 = 34495.71 现金流 5 = 36565.45 现金流 6 = 38759.38 现金流 7 = 41084.94 现金流 8 = 43550.03 现金流 9 = 46163.04 现金流 10 = 48932.82

使用计算器http://www.investopedia.com/calculator/NetPresentValue.aspx 按照手册“教科书”公式,我得出了相同的结果:

净现值:225,761.70 美元

我似乎无法让 NPV() 复制这个结果......它吐出 217,078.59 美元

我使用示例相同的值手动迭代它...所以他们必须使用与我不同的功能...

MSDN 页面示例明确指出初始费用应包含在现金流量列表中。

【问题讨论】:

  • NVP?这个函数是在哪个程序集中定义的。我看不到你在提供的代码示例中引用它。
  • Microsoft.Visualbasic msdn.microsoft.com/en-us/library/…
  • 在下面查看我对我的回答的评论——我得到了适用于您的示例的 VB NPV() 函数。

标签: vb.net math finance


【解决方案1】:

通常您不会在 Visual Basic NPV() 函数中包含第一个现金流(或者至少在租赁领域中我们没有)。您将贴现除第一个现金流量之外的所有现金流量,然后将第一个现金流量金额添加到您的净​​现值中。这是我之前在计算引擎中所做的一个示例(减去错误检查以简化示例):

Dim leaseRentalsDiscounted As Double = 0.0

Dim rebatedCashFlows As IEnumerable(Of LeasePayment) = GetLeaseRentalsPaymentStream()

Dim firstFlow As LeasePayment = rebatedCashFlows(0)

Dim doubleStream As Double() = PaymentToDoubleArray(rebatedCashFlows.Skip(1))

If doubleStream.Length > 0 Then
    Dim rate As Decimal = New Decimal(Me.Lease.DiscountRate / 100.0 / 12.0)
    leaseRentalsDiscounted = NPV(rate, doubleStream)
End If

leaseRentalsDiscounted += firstFlow.Amount

Return leaseRentalsDiscounted

这可能占您的 5%——我知道我以前遇到过这样的问题。对我来说,在您发布的手动 NPV 公式中,C0 不需要在打折的流中,所以我不将它包含在 NPV() 函数中。

【讨论】:

  • 但是函数文档规定至少一个必须是负数。在我的手动示例中,我将初始现金流出用作 C0 如果我将其排除在 cashflows() 之外,那么我将没有数组所需的负成员....
  • 这不是要求,但通常是这样。这完全取决于您要完成的工作。对于我要计算的数字,我们不需要负数。我发布的示例中的第一个现金流量将是 0 或正值,具体取决于租赁的应计方法。抱歉,我帮不上忙:\
  • 我刚刚在 Excel 中尝试过,我得到了您正在寻找的答案。对于您编辑中的示例:=NPV(0.04, 28963.23, 30701.06, 32543.12, 34495.71, 36565.45, 38759.38, 41084.94, 43550.03, 46163.04, 48932.82) + -78110 = $225,761.70。也许这就是您将其标记为答案的原因?
【解决方案2】:

MSDN 页面指出,如果您的现金流出开始于第一期的开始(而不是期末),则第一个值必须添加到 NPV 值中,并且不包含在现金流量数组中。

您的手动计算显示您的现金流出 (C0) 发生在零时间(现值),这表明您应该遵循 MSDN 页面的建议。

【讨论】:

  • MSDN 页面上的示例清楚地显示了第一笔付款(负现金流)被包含在数组中的零位置: Dim values(4) As Double ' 业务启动成本。 values(0) = -70000 ' 反映连续四年收入的正现金流。值(1) = 22000 值(2) = 25000 值(3) = 28000 值(4) = 31000
  • 嗯,我只能说,从您的样本数据来看,VB 的 NPV 只是您计算的 NPV 再贴现一个时期(225761.7 / 1.04 = 217078.59)。这将对应于 MSDN 上的注释:If your first cash flow occurs at the beginning of the first period, the first value must be added to the value returned by NPV and must not be included in the cash flow values of ValueArray.
【解决方案3】:

Cory Larson 是对的,部分是...但 MSDN 文档对我来说似乎是错误的。

问题在于 NPV() 函数在不应该的情况下对数组的第一个 (n=0) 元素进行了折扣;它从 n=1 开始

尽管 MSDN 文档具体说明数组的第一个元素应该是初始费用,但它们的功能并非如此。

在 NPV() 函数中,数组的第一个元素(正如 Cory Larson 暗示的那样)应该是第一个真正的现金流。然后,在函数返回结果后,结果应该减去初始费用。

这是因为 NPV() 函数以 n=1 开头 使用 NPV 公式: NPV = C0 + C1/(1+r)^1 + C2/(1+r)^2 + C3/(1+r)^3 + .... + Cn/(1+r )^n

在手动公式 Cn/(1+r)^n 中,对于 n=0,您使用初始费用...那么分母为 1(因为 n=0)

在我看来,http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.financial.npv.aspx 的 MSDN 示例应该修改为以下内容:

从数组中排除初始的 -70000 值,将索引中的所有元素下移一位,并将数组大小减 1。 然后将初始费用(-70000)与变量 NetPVal 相加得到实际结果。

有人应该像 MS 一样知道他们的 OBOB :D (但它实际上是一个功能,对吧?)

编辑:以及“数组必须包含至少一个负值(付款)和一个正值(收据)”的部分。 在不准确。 正如 Cory Larson 指出的那样:数组中不需要负值(实际上应该省略!)

【讨论】:

  • 也许我没有完全解释清楚。我证明它在我上面的答案的评论中有效。感谢您支持我(并坚持我)!
猜你喜欢
  • 1970-01-01
  • 2019-08-21
  • 2019-08-26
  • 1970-01-01
  • 2012-12-02
  • 2023-02-25
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
相关资源
最近更新 更多