代码之家  ›  专栏  ›  技术社区  ›  Matthew

.NET NPV()使用什么函数?与手动计算不匹配

  •  2
  • Matthew  · 技术社区  · 14 年前

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

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

    净现值=C0+C1/(1+r)^1+C2/(1+r)^2+C3/(1+r)^3+…+Cn/(1+r)^n

    手动结果存储在RunningTotal中 率r=0.04

    以下是我的相关代码:

        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
    

    编辑:使用以下值: 项目寿命=10年 现金流0=-78110.00 现金流量1=28963.23 现金流量2=30701.06 现金流量3=32543.12 现金流量5=36565.45 现金流量7=41084.94 现金流量8=43550.03 现金流量10=48932.82

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

    我似乎无法让NPV()复制这个结果。。。总共217078.59美元

    我使用相同的值手动迭代它。。。所以他们使用的函数肯定和我不同。。。

    MSDN页面的例子清楚地说明了初始费用应该包括在现金流列表中。

    3 回复  |  直到 14 年前
        1
  •  1
  •   Cᴏʀʏ bcherry    14 年前

    通常情况下,您不会在visualbasic中包含第一个现金流 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不需要在折扣流中,所以这就是为什么我不把它包括在 功能。

        2
  •  1
  •   Jeff Meatball Yang    14 年前

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

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

        3
  •  0
  •   Matthew    14 年前

    科里·拉森是对的,在某种程度上。。。但是MSDN文档在我看来是错误的。

    问题是NPV()函数在数组的第一个(n=0)元素不应该被贴现的时候,却在贴现它;从n=1开始

    在NPV()函数中,数组的第一个元素(正如Cory Larson所暗示的)应该是第一个实际现金流。然后,在函数返回结果后,结果应该减去初始开销。

    使用净现值公式:净现值=C0+C1/(1+r)^1+C2/(1+r)^2+C3/(1+r)^3+…+Cn/(1+r)^n

    在我看来,MSDN的例子 http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.financial.npv.aspx 应修改如下:

    从数组中排除初始的-70000值,将索引中的所有元素下移一位,并将数组大小减小1。

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

    不准确。