簡體   English   中英

需要幫助計算每個投資在不同日期的不同投資的 IRR,在 python

[英]Need help calculating IRR for different investments at different dates for each investment, in python

我需要幫助計算不同投資的 IRR,以及這些投資在不同時間的 IRR。

所以有一個 dataframe 看起來像這樣:

日期 投資 流動
2012-05-12 1 -50
2013-09-04 1 100
2014-05-05 1 300
2013-09-04 2 -700
2015-05-12 2 1000
2012-04-04 3 100
2013-05-12 3 -50
2013-09-04 4 -60

另一個看起來像這樣

日期 投資 庫存
2012-09-05 1 400
2014-05-05 1 600
2014-05-05 2 300
2013-09-04 2 800
2012-09-14 3 1000
2013-09-05 4 6000

因此,我想創建多個數據框,其中包含每個投資的流向,直到我獲得有關股票的信息的日期,最后一行包含該日期的股票。 例如,我對投資 1 的股票有 2 個觀察結果,所以我應該為投資 1 創建 2 個數據框,如下所示:

日期 投資 流量+庫存(最后一行)
2012-05-12 1 -50
2012-09-05 1 400
日期 投資 流量+庫存(最后一行)
2012-05-12 1 -50
2013-09-04 1 100
2014-05-05 1 300
2014-05-05 1 600

對於投資 3,假設我對股票只有一個觀察結果,應該只有 1 個 dataframe 看起來像這樣:

日期 投資 流量+庫存(最后一行)
2012-04-04 3 100
2012-09-14 3 1000

鑒於我有很多數據,手動創建每個 dataframe 很麻煩,而且我希望此代碼在我有新信息時更新 IRR。 我想這樣做是因為我想查看每個日期的 IRR 演變,因為我擁有每項投資的股票信息。 有點像投資的內部收益率時間序列。 我將使用創建的數據框計算 IRR。

我已經嘗試為每項投資對我有股票信息的日期進行排名,但循環有問題。

非常感謝

編輯:根據 Henry Ecker 的要求,這是合並數據庫的示例。

         DATE_x       Investment         Flow     DATE_y         Stock
355  2018-08-29            1            1371300 2020-09-30    2904678,03
3076 2016-03-31            2           -4535569 2015-06-30             0
1564 2017-11-28            3            1142227 2014-09-30   10378007,31
3666 2018-02-22            2            1622857 2020-03-31  122203846,09
1394 2017-05-16            3            3116642 2017-12-31             0
472  2013-11-09            3           -4364500 2015-12-31   45789217,93
446  2021-02-23            1             325117 2020-03-31   13176648,97
1641 2018-01-31            3             623695 2015-09-30             0
1297 2017-03-21            3            1146193 2015-09-30    32103654,6
2080 2020-09-15            3             461123 2017-09-30   47763628,79

go 的一種方法是加入流和觀察以獲取關聯,然后按觀察日期和投資 ID 分組以獲取我們感興趣的每個組。

function process_df僅用於過濾掉觀察日期( DATE_y )之前的日子。

從第一行獲取值投資、觀察日期 ( DATE_y ) 和股票值,因為它們在組中都相同,並且 append 到表的末尾。 然后只需清理所有內容,刪除多余的列(Stock 和 DATE_y),重置索引,並重命名列以反映您想要的 output。

import pandas as pd

flows = pd.DataFrame({'DATE': {0: '2012-05-12', 1: '2013-09-04',
                               2: '2014-05-05', 3: '2013-09-04',
                               4: '2015-05-12', 5: '2012-04-04',
                               6: '2013-05-12', 7: '2013-09-04',
                               8: '2020-05-12', 9: '2016-07-12'},
                      'Investment': {0: 1, 1: 1, 2: 1, 3: 2,
                                     4: 2, 5: 3, 6: 3, 7: 4,
                                     8: 5, 9: 7},
                      'Flow': {0: -50, 1: 100, 2: 300, 3: -700,
                               4: 1000, 5: 100, 6: -50, 7: -60,
                               8: 100, 9: 800}})
flows['DATE'] = flows['DATE'].astype('datetime64[ns]')

observations = pd.DataFrame({'DATE': {0: '2012-09-05', 1: '2014-05-05',
                                      2: '2014-05-05', 3: '2013-09-04',
                                      4: '2012-09-14', 5: '2013-09-05',
                                      6: '2014-05-14', 7: '2015-12-14'},
                             'Investment': {0: 1, 1: 1, 2: 2,
                                            3: 2, 4: 3, 5: 4,
                                            6: 5, 7: 6},
                             'Stock': {0: 400, 1: 600, 2: 300,
                                       3: 800, 4: 1000, 5: 6000,
                                       6: 0, 7: 15}})
observations['DATE'] = observations['DATE'].astype('datetime64[ns]')


def process_df(df):
    out = df[df['DATE_x'] <= df['DATE_y']]  # Filter Out Out of Bound Dates
    if out.empty:
        # Handle Case Where Observation but No flows
        return df[['DATE_y', 'Investment', 'Stock']] \
            .reset_index(drop=True) \
            .rename(columns={'DATE_y': 'DATE', 'Stock': 'Flow + Stock(last row)'})
    return out.drop(['DATE_y', 'Stock'], axis=1) \
        .append(out[['Investment', 'DATE_y', 'Stock']]
                .iloc[0]
                .rename({'DATE_y': 'DATE_x', 'Stock': 'Flow'})) \
        .reset_index(drop=True) \
        .rename(columns={'DATE_x': 'DATE', 'Flow': 'Flow + Stock(last row)'})


merged = pd.merge(flows, observations, on='Investment', how='right')

dfs = [process_df(group) for _, group in merged.groupby(['Investment', 'DATE_y'])]

# For Display
for i, new_df in enumerate(dfs):
    print(f'DataFrame {i+1}')
    print(new_df)
    print()

dfs 是一個包含各個 DataFrame 的列表。

Output:

DataFrame 1
        DATE  Investment  Flow + Stock(last row)
0 2012-05-12           1                   -50.0
1 2012-09-05           1                   400.0

DataFrame 2
        DATE  Investment  Flow + Stock(last row)
0 2012-05-12           1                   -50.0
1 2013-09-04           1                   100.0
2 2014-05-05           1                   300.0
3 2014-05-05           1                   600.0

DataFrame 3
        DATE  Investment  Flow + Stock(last row)
0 2013-09-04           2                  -700.0
1 2013-09-04           2                   800.0

DataFrame 4
        DATE  Investment  Flow + Stock(last row)
0 2013-09-04           2                  -700.0
1 2014-05-05           2                   300.0

DataFrame 5
        DATE  Investment  Flow + Stock(last row)
0 2012-04-04           3                   100.0
1 2012-09-14           3                  1000.0

DataFrame 6
        DATE  Investment  Flow + Stock(last row)
0 2013-09-04           4                   -60.0
1 2013-09-05           4                  6000.0

DataFrame 7
        DATE  Investment  Flow + Stock(last row)
0 2014-05-14           5                       0

DataFrame 8
        DATE  Investment  Flow + Stock(last row)
0 2015-12-14           6                      15

編輯注釋:

  • 我最初的實現做了一個錯誤的假設,即所有觀察都至少有一個流。 我猜測您希望如何接收有關沒有流量關聯的觀察的信息,並選擇返回 DataFrame,它仍然有最后一行包含庫存信息但沒有流量。 如果您更喜歡空的 DataFrame,請直接返回。
    if out.empty:
        # Handle Case Where Observation but No flows
        return out
  • 我在樣本數據中添加了 3 個額外的測試用例。
    1. 有流動,但在觀察之后發生
    2. 給定的投資 ID 沒有流量
    3. 有流動但沒有觀察。
      • 鑒於您生成的 DataFrames 是基於觀察的,我選擇通過使用“正確”連接來排除觀察中不匹配的流。

暫無
暫無

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

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