2

我在 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 页面示例明确指出初始费用应包含在现金流量列表中。

4

3 回答 3

1

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

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()函数中的原因。

于 2010-06-18T00:02:37.983 回答
1

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

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

于 2010-06-18T00:33:09.447 回答
0

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,并将数组大小减 1。然后将初始费用 (-70000) 添加到变量 NetPVal 以得出实际结果。

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

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

于 2010-06-18T18:07:58.163 回答