2012-01-19 26 views

Trả lời

8

Với sự giúp đỡ của hiện thực khác nhau tôi tìm thấy trong mạng, tôi đã đưa ra một thực hiện python:

def xirr(transactions): 
    years = [(ta[0] - transactions[0][0]).days/365.0 for ta in transactions] 
    residual = 1 
    step = 0.05 
    guess = 0.05 
    epsilon = 0.0001 
    limit = 10000 
    while abs(residual) > epsilon and limit > 0: 
     limit -= 1 
     residual = 0.0 
     for i, ta in enumerate(transactions): 
      residual += ta[1]/pow(guess, years[i]) 
     if abs(residual) > epsilon: 
      if residual > 0: 
       guess += step 
      else: 
       guess -= step 
       step /= 2.0 
    return guess-1 

from datetime import date 
tas = [ (date(2010, 12, 29), -10000), 
    (date(2012, 1, 25), 20), 
    (date(2012, 3, 8), 10100)] 
print xirr(tas) #0.0100612640381 
+0

CẢNH BÁO: Nếu bạn sử dụng các giá trị 'bước' và' đoán' này, sẽ không thể có được dấu hiệu trong '(-100%, -95%)' –

0

Với Pandas, tôi đã nhận như sau để làm việc: ACT (lưu ý, tôi đang sử dụng/365 convention)

rate = 0.10 
dates= pandas.date_range(start=pandas.Timestamp('2015-01-01'),periods=5, freq="AS") 
cfs = pandas.Series([-500,200,200,200,200],index=dates) 

# intermediate calculations(if interested) 
# cf_xnpv_days = [(cf.index[i]-cf.index[i-1]).days for i in range(1,len(cf.index))] 
# cf_xnpv_days_cumulative = [(cf.index[i]-cf.index[0]).days for i in range(1,len(cf.index))] 
# cf_xnpv_days_disc_factors = [(1+rate)**(float((cf.index[i]-cf.index[0]).days)/365.0)-1 for i in range(1,len(cf.index))] 

cf_xnpv_days_pvs = [cf[i]/float(1+(1+rate)**(float((cf.index[i]-cf.index[0]).days)/365.0)-1) for i in range(1,len(cf.index))] 

cf_xnpv = cf[0]+ sum(cf_xnpv_days_pvs) 
6

Đây là một cách để thực hiện hai chức năng.

import scipy.optimize 

def xnpv(rate, values, dates): 
    '''Equivalent of Excel's XNPV function. 

    >>> from datetime import date 
    >>> dates = [date(2010, 12, 29), date(2012, 1, 25), date(2012, 3, 8)] 
    >>> values = [-10000, 20, 10100] 
    >>> xnpv(0.1, values, dates) 
    -966.4345... 
    ''' 
    if rate <= -1.0: 
     return float('inf') 
    d0 = dates[0] # or min(dates) 
    return sum([ vi/(1.0 + rate)**((di - d0).days/365.0) for vi, di in zip(values, dates)]) 

def xirr(values, dates): 
    '''Equivalent of Excel's XIRR function. 

    >>> from datetime import date 
    >>> dates = [date(2010, 12, 29), date(2012, 1, 25), date(2012, 3, 8)] 
    >>> values = [-10000, 20, 10100] 
    >>> xirr(values, dates) 
    0.0100612... 
    ''' 
    try: 
     return scipy.optimize.newton(lambda r: xnpv(r, values, dates), 0.0) 
    except RuntimeError: # Failed to converge? 
     return scipy.optimize.brentq(lambda r: xnpv(r, values, dates), -1.0, 1e10) 
Các vấn đề liên quan