簡體   English   中英

在 python 中計算 IRR function 的循環出現問題

[英]Problem with loop to calculate IRR function in python

我在計算 python 中的 function 時遇到問題。 我想計算一些投資的IRR,所有這些在他們自己的dataframe中都有描述。 我有一個 dataframe 直到某個日期,所以我有多個 dataframe 描述投資在不同日期之前完成的付款流量,每個 Z6A8064B5DF479450557005 的股票的最后一行包含3個信息到那時為止,每項投資所擁有的資本。 我這樣做是為了獲得每項投資的 IRR 時間序列。 我要計算 IRR 的每個 dataframe 都在一個列表中。

為了計算每個 dataframe 的 IRR,我做了這些函數:

def npv(irr, cfs, yrs):
    return np.sum(cfs / ((1. +  irr) ** yrs))
def irr(cfs, yrs, x0)
    return np.asscalar(fsolve(npv, x0=x0, args=(cfs, yrs)))

因此,為了計算我列表中每個 dataframe 的 IRR,我做了:

 for i, new_df in enumerate(dfs):
   cash_flow = new_df.FLOWS.values
   years = new_df.timediff.values
   output.loc[i, ['DATE']] = new_df['DATE'].iloc[-1]
   output.loc[i, ['Investment']] = new_df['Investment'].iloc[-1]
   output.loc[i, ['irr']] = irr(cash_flow, years, x0=0.)

Output 是 dataframe 我想創建的硬幣包含我想要的信息,即直到某個日期的每次投資的 IRR。 問題是,它可以正確計算某些數據幀的 IRR,但不能正確計算其他數據幀。 例如,它正確計算了這個 dataframe 的 IRR:

       DATE     INVESTMENT       FLOWS        timediff
0   2014-02-24      1        -36278400.0         0.0
1   2014-03-25      1        -11490744.0    0.07945205479452055
2   2015-01-22      1        -13244300.0    0.9095890410958904
3   2015-09-24      1        -10811412.0    1.5808219178082192
4   2015-11-12      1         -6208238.0    1.715068493150685
5   2016-01-22      1         -6210161.0    1.9095890410958904
6   2016-03-31      1         -4535569.0    2.0986301369863014
7   2016-05-25      1          8420470.0    2.249315068493151
8   2016-06-30      1         12357138.0    2.347945205479452
9   2016-07-14      1          3498535.0    2.3863013698630136
10  2016-12-26      1          4085285.0    2.8383561643835615
11  2017-06-07      1          3056835.0    3.2849315068493152
12  2017-09-11      1         11254424.0    3.547945205479452
13  2017-11-16      1          9274834.0    3.728767123287671
14  2018-02-22      1          1622857.0    3.9972602739726026
15  2018-05-23      1          2642985.0    4.243835616438356
18  2018-08-23      1          9265099.0    4.495890410958904
16  2018-11-29      1          1011915.0    4.764383561643836
19  2018-12-28      1          1760734.0    4.843835616438356
17  2019-01-14      1          1940112.0    4.890410958904109
20  2019-06-30      1         116957227.3   5.347945205479452

內部收益率為 0.215。 但是這個 dataframe,對於完全相同的投資它沒有。 它返回 0.0001 的 IRR,但實際的 IRR 應該在 0.216 左右。

       DATE     INVESTMENT       FLOWS         timediff
0   2014-02-24      1        -36278400.0         0.0
1   2014-03-25      1        -11490744.0    0.07945205479452055
2   2015-01-22      1        -13244300.0    0.9095890410958904
3   2015-09-24      1        -10811412.0    1.5808219178082192
4   2015-11-12      1         -6208238.0    1.715068493150685
5   2016-01-22      1         -6210161.0    1.9095890410958904
6   2016-03-31      1         -4535569.0    2.0986301369863014
7   2016-05-25      1          8420470.0    2.249315068493151
8   2016-06-30      1         12357138.0    2.347945205479452
9   2016-07-14      1          3498535.0    2.3863013698630136
10  2016-12-26      1          4085285.0    2.8383561643835615
11  2017-06-07      1          3056835.0    3.2849315068493152
12  2017-09-11      1         11254424.0    3.547945205479452
13  2017-11-16      1          9274834.0    3.728767123287671
14  2018-02-22      1          1622857.0    3.9972602739726026
15  2018-05-23      1          2642985.0    4.243835616438356
18  2018-08-23      1          9265099.0    4.495890410958904
16  2018-11-29      1          1011915.0    4.764383561643836
19  2018-12-28      1          1760734.0    4.843835616438356
17  2019-01-14      1          1940112.0    4.890410958904109
20  2019-09-30      1        123753575.7    5.6

除了最后一行之外,這兩個數據框具有完全相同的流量,其中它包含了該投資截至該日期的資本存量。 所以這兩個數據幀之間的唯一區別是最后一行。 這意味着該投資在此期間沒有任何流入或流出。 我不明白為什么內部收益率變化如此之大。 或者為什么某些 IRR 計算不正確。

大多數計算正確,但少數計算不正確。

謝謝你幫助我。

正如我所想,這是優化方法的問題。 當我用第二個 df 嘗試了你的 irr function 時,我什至收到了警告:

RuntimeWarning: The iteration is not making good progress, as measured by the 
  improvement from the last ten iterations.
  warnings.warn(msg, RuntimeWarning)

但是用其他方法嘗試scipy.optimize.root似乎對我有用。 將函數更改為:

import scipy.optimize as optimize

def irr(cfs, yrs, x0):
    r = optimize.root(npv, args=(cfs, yrs), x0=x0, method='broyden1')
    return float(r.x)

我剛剛檢查了 lm 和 broyden1,它們都與您的第二個示例收斂到 0.216 左右。 有多種方法,我不知道哪種方法是最好的選擇,但大多數似乎比 fsolve 中使用的 hybr 方法更好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM