Python:通过添加累积股息并采用复合年增长率(CAGR)来计算总回报

nli*_*eb7 6 python quantitative-finance cumulative-sum pandas pandas-groupby

我有一个数据框,其中包含许多公司的年度价格和股息数据。我希望通过将三年内收到的所有股息添加到期末股价中,然后计算复合年增长率来计算三年年化回报率。我知道如何计算复合年增长率,但我遇到的困难是将期间收到的股息添加到最终价格。

样本数据:

       RIC  Date    Price   Dividend
0   RSG.AX  2018    0.814   0.000
1   RSG.AX  2017    0.889   0.015
2   RSG.AX  2016    0.937   0.012
3   RSG.AX  2015    0.181   0.000
4   RSG.AX  2014    0.216   0.000
5   RSG.AX  2013    0.494   0.000
6   QBE.AX  2018    7.119   0.352
7   QBE.AX  2017    8.331   0.202
8   QBE.AX  2016    8.961   0.389
9   QBE.AX  2015    9.159   0.363
10  QBE.AX  2014    9.156   0.302
Run Code Online (Sandbox Code Playgroud)

使用公司 RSG.AX(RIC=公司代码),2015 年至 2018 年的计算示例如下:

3年回报=(最终价格+累计股息)/起始价格=(0.814+0.015+0.012)/0.182 = 4.63

年化回报率 = (回报)^(1/年)-1 = (4.63)^(1/3)-1 = 0.66 = 66%

我如何使用 Python 来做到这一点?也许.groupby()会努力分离每个公司的数据。任何帮助表示赞赏!

hen*_*gkk 2

使用shift()从上/下行获取值进行计算


方法 1:使用 RIC 循环

df.RIC.unique()我在每个 RIC 上使用子数据帧的副本循环它sub_df。假设当年的价格是股息后的,3-year return则为:

sub_df['3-year Return'] = (sub_df.Price +
                           sub_df.Dividend +
                           sub_df.shift(-1).Dividend +
                           sub_df.shift(-2).Dividend) / sub_df.Price.shift(-3)
Run Code Online (Sandbox Code Playgroud)

之后将 sub_df 更新为原始 df。然后Annualized return根据你的公式计算pow()

df['3-year Return'] = None
for ric in df.RIC.unique():
    sub_df = df.loc[df['RIC'] == ric].copy()
    sub_df['3-year Return'] = (sub_df.Price + 
                               sub_df.Dividend + 
                               sub_df.shift(-1).Dividend + 
                               sub_df.shift(-2).Dividend) / sub_df.Price.shift(-3)
    df.update(sub_df)
df['Annualized return'] = pow(df['3-year Return'], 1/3)  - 1
print(df)

       RIC    Date  Price  Dividend 3-year Return Annualized return
0   RSG.AX  2018.0  0.814     0.000       4.64641          0.668678
1   RSG.AX  2017.0  0.889     0.015       4.24074          0.618629
2   RSG.AX  2016.0  0.937     0.012       1.92105           0.24312
3   RSG.AX  2015.0  0.181     0.000          None               NaN
4   RSG.AX  2014.0  0.216     0.000          None               NaN
5   RSG.AX  2013.0  0.494     0.000          None               NaN
6   QBE.AX  2018.0  7.119     0.352      0.880227        -0.0416336
7   QBE.AX  2017.0  8.331     0.202       1.01409        0.00467449
8   QBE.AX  2016.0  8.961     0.389          None               NaN
9   QBE.AX  2015.0  9.159     0.363          None               NaN
10  QBE.AX  2014.0  9.156     0.302          None               NaN
Run Code Online (Sandbox Code Playgroud)

方法 2 - 在自定义函数上使用 groupby() 和 apply()

基于方法1,我们可以定义一个自定义函数,通过groupbyRIC来应用

def three_year_return(row):
    row['3-year Return'] = (row.Price + 
                            row.Dividend + 
                            row.shift(-1).Dividend + 
                            row.shift(-2).Dividend) / row.Price.shift(-3)
    return row

df = df.groupby(['RIC']).apply(three_year_return)
df['Annualized return'] = pow(df['3-year Return'], 1/3)  - 1


       RIC  Date  Price  Dividend  3-year Return  Annualized return
0   RSG.AX  2018  0.814     0.000       4.646409           0.668678
1   RSG.AX  2017  0.889     0.015       4.240741           0.618629
2   RSG.AX  2016  0.937     0.012       1.921053           0.243120
3   RSG.AX  2015  0.181     0.000            NaN                NaN
4   RSG.AX  2014  0.216     0.000            NaN                NaN
5   RSG.AX  2013  0.494     0.000            NaN                NaN
6   QBE.AX  2018  7.119     0.352       0.880227          -0.041634
7   QBE.AX  2017  8.331     0.202       1.014089           0.004674
8   QBE.AX  2016  8.961     0.389            NaN                NaN
9   QBE.AX  2015  9.159     0.363            NaN                NaN
10  QBE.AX  2014  9.156     0.302            NaN                NaN
Run Code Online (Sandbox Code Playgroud)

仅供参考 - 结果看起来与您的示例有点不同,因为我发现您使用0.182as start pricewhile 它应该0.181基于您的示例数据。