Какую функцию использует .NET NPV ()?Не соответствует ручным расчетам - PullRequest
2 голосов
/ 18 июня 2010

Я использую функцию NPV () в VB.NET, чтобы получить NPV для набора денежных потоков.

Однако результат NPV () не согласуется с моими результатами, выполняющими вычисление вручную (ни подсчет NPV Investopedia ... который соответствует моим ручным результатам)

Мои правильные ручные результаты и результаты 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

Iне может заставить NPV () воспроизвести этот результат ... он выплевывает $ 217,078.59

Я повторяю это вручную, используя пример того же значения ... поэтому они должны использовать функцию, отличную от меня ...

В примере страницы MSDN четко указано, что первоначальные расходы должны быть включены в список денежных потоков.

Ответы [ 3 ]

1 голос
/ 18 июня 2010

На странице MSDN отмечается, что если отток денежных средств начинается в начале первого периода (а не в конце), первое значение должно быть добавлено к значению NPV и не включено в массив денежных потоков.

Ваш ручной расчет показывает, что ваш отток денежных средств (C0) происходит в нулевое время (текущая стоимость), что указывает на то, что вы должны следовать предложению страницы MSDN.

1 голос
/ 18 июня 2010

Обычно вы не включаете первый денежный поток в функцию 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().

0 голосов
/ 18 июня 2010

Кори Ларсон прав, отчасти ... но документация MSDN мне кажется ошибочной.

Проблема в том, что функция NPV () отбрасывает самый первый (n = 0) элемент массива, когда не должна; оно начинается при n = 1

Несмотря на то, что в документации MSDN указано, что первый элемент массива должен быть начальным расходом, это не относится к их функции.

В функции NPV () первый элемент массива (как подразумевал Кори Ларсон) должен быть первым реальным денежным потоком. Затем, после того, как функция вернет результат, результат должен быть вычтен из первоначального расхода.

Это потому, что функция NPV () начинается с n = 1 используя формулу NPV: NPV = C0 + C1 / (1 + r) ^ 1 + C2 / (1 + r) ^ 2 + C3 / (1 + r) ^ 3 + .... + Cn / (1 + r ) ^ п

В ручной формуле Cn / (1 + r) ^ n, для n = 0 вы используете свои начальные расходы ... тогда знаменатель равен 1 (потому что n = 0)

На мой взгляд, пример MSDN на http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.financial.npv.aspx должен быть изменен следующим образом:

Исключить начальное значение -70000 из массива, сместить все элементы на единицу в индексе и уменьшить размер массива на 1. Затем добавьте начальный расход (-70000) к переменной NetPVal, чтобы получить фактический результат.

Кому-то хотелось, чтобы М.С. знал об их ОБОБ: D (Но на самом деле это особенность, верно?)

РЕДАКТИРОВАТЬ: И раздел, который говорит: «Массив должен содержать как минимум одно отрицательное значение (платеж) и одно положительное значение (получение).» В не точно. Как указал Кори Ларсон: отрицательное значение не требуется в массиве (и, на самом деле, должно быть пропущено!)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...