Функция, которая рассчитывает NPV из списка денежных потоков

Я создал простую библиотеку, которая выводит необходимые кодеры для сложных типов продуктов на основе параметров входного типа.

https://github.com/lesbroot/typedudf

import typedudf.TypedUdf
import typedudf.ParamEncoder._

case class Foo(x: Int, y: String)
val fooUdf = TypedUdf((foo: Foo) => foo.x + foo.y.length)
df.withColumn("sum", fooUdf($"foo"))

0
задан GSatterwhite 30 March 2019 в 23:02
поделиться

3 ответа

Вам необходимо сложить отдельные денежные потоки в рамках вашей функции и вернуть их. В данный момент вы возвращаете значение pv первого денежного потока, поскольку у вас есть отчет о возврате в цикле for.

Кроме того, я думаю, что то, как вы проверите свой цикл while по i, будет означать, что вы пропустите последний платеж. Обычно вам не нужно создавать экземпляры встречных переменных самостоятельно (см. Мои примеры ниже):

def npv(cfList, r):
    f = 0
    i = 1

    pv = cfList[f] / ((1 + r) ** i)  # <-- this needs to be in the loop

    while i < len(cfList): # <-- i will break loop before last payment is calculated.
        f += 1
        i += 1
        return pv  # <-- this return here is the issue


print(npv(cfList, r))

NPV - это сумма PV всех будущих денежных потоков, это то, что вам нужно рассчитать. Например :

def npv(cfList, r):

    sum_pv = 0  # <-- variable used to sum result

    for i, pmt in enumerate(cfList, start=1):  # <-- use of enumerate allows you to do away with the counter variables.
        sum_pv += pmt / ((1 + r) ** i)  # <-- add pv of one of the cash flows to the sum variable

    return sum_pv  # <-- only return the sum after your loop has completed.

Всегда помните, что оператор return в цикле for выйдет из цикла при первом обнаружении return.

Альтернативной реализацией будет получение отдельных PV от генератора PV и суммирование результатов:

def pv_gen(cfList, r):

    for i, pmt in enumerate(cfList, start=1):

        yield pmt / ((1 + r) ** i)

print(sum(pv_gen(cfList, r)))
0
ответ дан SuperShoot 30 March 2019 в 23:02
поделиться

Если вы выполняете итерацию по списку с помощью цикла while, то вы должны иметь действие, выполняющее строку кода внутри цикла while.

Также похоже, что ваш цикл будет обрезаться раньше, когда i = 2 = len (cflist) на второй итерации (не забывайте, что python использует индексирование на основе 0 ) и потому что обратный вызов находится внутри цикла while.

Это должно работать:

def npv(cfList, r):
    f = 0
    i = 1

    pv = 0

    while f <= len(cfList):
        pv += (cfList[f] / ((1 + r) ** i))
        f += 1
        i += 1
    return pv
0
ответ дан mackdelany 30 March 2019 в 23:02
поделиться

Возвращение NPV из списка денежных потоков будет выглядеть так:

def npv(cfList, r):
    return sum(f / ((1 + r) ** i) for i, f in enumerate(cfList, 1))

In []:
cfList = [20, 50, 90]
r = 0.05
npv(cfList, r)

Out[]:
142.14447683835436
0
ответ дан AChampion 30 March 2019 в 23:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: