我写了一些代码来计算IRR,效果很好...
import scipy.optimize as optimize
import datetime
def npv(cf, rate=0.1):
if len(cf) >= 2:
first_date = min([x[0] for x in cf])
dcf = [x[1] * (1 /
((1 + rate) ** ((x[0] - first_date).days / 365))) for x in cf]
return sum(dcf)
elif len(cf) == 1:
return cf[0][1]
else:
return 0
def irr(cf):
f = lambda x: npv(cf, rate=x)
r = optimize.newton(f, 0, maxiter=70)
return r
...但是当我尝试此现金流
cf=[(datetime.datetime(2018, 1, 10), -51089.94),
(datetime.datetime(2022, 10, 6), 4941.0)]
我收到此错误:
File "/Users/maxim/Dropbox/Python/FinProject/fintrack/main/models.py", line 503, in getIRR
return irr(cf)
File "/Users/maxim/Dropbox/Python/FinProject/fintrack/main/models.py", line 37, in irr
r = optimize.newton(f, 0, maxiter=70)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/scipy/optimize/zeros.py", line 204, in newton
q1 = func(p1, *args)
File "/Users/maxim/Dropbox/Python/FinProject/fintrack/main/models.py", line 36, in <lambda>
f = lambda x: npv(cf, rate=x)
File "/Users/maxim/Dropbox/Python/FinProject/fintrack/main/models.py", line 27, in npv
((1 + rate) ** ((x[0] - first_date).days / 365))) for x in cf]
File "/Users/maxim/Dropbox/Python/FinProject/fintrack/main/models.py", line 27, in <listcomp>
((1 + rate) ** ((x[0] - first_date).days / 365))) for x in cf]
OverflowError: complex exponentiation
[30/Nov/2018 21:28:36] "GET /inv/19/ HTTP/1.1" 500 299065
但是我知道正确答案是-38.912 ..%,我通过Excel得到了这个结果。 怎么了使用其他数据,我得到的结果与Excel IRR函数的结果相同...是否应该使用其他函数查找参数?
P.S .:这是迭代的参数和结果列表(财务中的OMG复数%-)):
rate= 0.0 result= -46148.94
rate= 0.0001 result= -46151.281226688276
rate= -1.9711435988300456 result= (-54972.27265283515-4141.40178622848j)
rate= (8.450859228811169-3.967580022971747j) result= (-51089.96465099011+0.07614432462298902j)
rate= (46.548868303534285-96.82120737804672j) result= (-51089.93999938349-9.638432563347345e-07j)
rate= (63880696.05472335+4880892.707757121j) result= (-51089.94-1.7420169038104924e-34j)
rate= (-1.3534185437764045e+18-2.52038641964956e+18j) result= (-51089.94-5.721141417411886e-85j)
rate= (-7.391799165398238e+56+3.969311207511089e+56j) result= (-51089.94+9.185514002355334e-269j)
rate= (3.5446051170119047e+145+6.600895665730368e+145j) result= ERROR!!!
答案 0 :(得分:0)
似乎newton
无法正确处理(不确定原因)。但是,您可以使用https://github.com/cran/Rpoppler/blob/819bc04dd113f3ec12d8f7d8eecfab79569478d6/configure#L1830,它可以为您带来预期的结果,并且只需要对代码进行很小的修改即可:
import scipy.optimize as optimize
import datetime
def npv(cf, rate=0.1):
if len(cf) >= 2:
first_date = min([x[0] for x in cf])
dcf = [x[1] * (1 /
((1 + rate) ** ((x[0] - first_date).days / 365))) for x in cf]
return sum(dcf)
elif len(cf) == 1:
return cf[0][1]
else:
return 0
def irr(cf):
f = lambda x: npv(cf, rate=x)
r = optimize.root(f, [0])
return r
cf = [(datetime.datetime(2018, 1, 10), -51089.94),
(datetime.datetime(2022, 10, 6), 4941.0)]
print(irr(cf))
这将打印:
fjac: array([[-1.]])
fun: array([-2.91038305e-11])
message: 'The solution converged.'
nfev: 18
qtf: array([2.37701897e-06])
r: array([396401.23327105])
status: 1
success: True
x: array([-0.38912302])
如您所见,x
包含预期的-0.38912
。
答案 1 :(得分:0)
工作代码为:
import scipy.optimize as optimize
import datetime
def npv(cf, rate=0.1):
if len(cf) >= 2:
first_date = min([x[0] for x in cf])
dcf = [x[1] * (1 /
((1 + rate) ** ((x[0] - first_date).days / 365))) for x in cf]
return sum(dcf)
elif len(cf) == 1:
return cf[0][1]
else:
return 0
def irr(cf):
f = lambda x: npv(cf, rate=x)
r = optimize.root(f, [0])
return r
非常感谢克莱布!