Python中财务数据的优化

问题描述 投票:0回答:1

我正在尝试计算给定 IRR 的盈亏平衡价格,但陷入范围的根求解器中。一个简单的例子:

n = 10. # no of periods
years = np.arange(n) + 1
initial_investment = [-1000]
quantity_sold = np.full(n, 20)
price = np.full(n, 20)
revenue = quantity_sold * price
expense = np.full(n, 50)

cash_flow = np.concatenate([initial_investment, revenue - expense])

这样我们就可以计算 IRR 并使用

numpy_financial
验证 NPV 是否为 0:

npf.irr(cash_flow), npf.npv(0.32975, cash_flow)
# (0.32975, 0.008)

我想做的恰恰相反:假设 IRR 为 40%,盈亏平衡价格所需的现金流量是多少(NPV = 0)。

我正在使用

scipy.optimize.root
但对于如何构建它却迷失了方向。我可以反转
npf.npv
来获得 IRR:

optimize.root(npf.npv, args=cash_flow, x0=0.5)

但 cash_flow 是一个数组,甚至允许该数组的值保持不变。给定 IRR,我该如何求解

cash_flow

python python-3.x optimization finance scipy-optimize
1个回答
0
投票

这当然是可能的,但除非你进一步限制问题(例如通过固定初始投资),否则意义不大。否则,系统是欠定的:

import numpy as np
import scipy.optimize

n = 10  # no of periods
years = np.arange(1, 1 + n)
initial_investment = -1000
quantity_sold = np.full(shape=n, fill_value=20)
price = np.full(shape=n, fill_value=20.)
revenue = quantity_sold * price
expense = np.full(shape=n, fill_value=50.)
cash_flow = np.concatenate(((initial_investment,), revenue - expense))

# Forward calculation of IRR, shown without use of `npf`
def npv(rate: float) -> float:
    return (cash_flow / (1 + rate)**np.arange(cash_flow.size)).sum()
result = scipy.optimize.root_scalar(f=npv, x0=0.5, bracket=(0, 1))
assert result.converged
irr = result.root
assert np.isclose(0.32975, irr, atol=0, rtol=1e-5)
np.isclose(0, npv(irr), rtol=0, atol=1e-12)
print('irr =', irr)

# Back-calculation of cash flow, again without `npf`
def npv_from_series(cash_flow: np.ndarray) -> float:
    return (cash_flow / (1 + irr)**np.arange(cash_flow.size)).sum()
result = scipy.optimize.least_squares(
    fun=npv_from_series,
    x0=np.concatenate(((-1,), np.ones(n))),
    bounds=scipy.optimize.Bounds(
        lb=np.concatenate(((-np.inf,), np.zeros(n))),
        ub=np.concatenate(((0,), np.full(shape=n, fill_value=np.inf))),
    ),
)
assert result.success
cash_flow = result.x
print(f'Cash flow for IRR of {irr:.1%}:')
print(cash_flow)
print(f'NPV error: {result.fun[0]:.2e}')
irr = 0.3297531334357468
Cash flow for IRR of 33.0%:
[-3.32043506  0.99765753  1.06177051  1.11807742  1.17345293  1.23855932
  1.33771217  1.5628038   3.13235102  0.0914474   0.674785  ]
NPV error: 1.80e-16
© www.soinside.com 2019 - 2024. All rights reserved.