Python:通过添加累计股息并取复合年增长率(CAGR)计算总计return
Python: Calculate total return by adding cumulative dividends and taking the compound annual growth rate (CAGR)
我有一个数据框,其中包含许多公司的年度价格和股息数据。我希望通过将三年内收到的所有股息添加到期末股价,然后计算复合年增长率来计算 3 年年化 return。我知道如何计算 CAGR,但我遇到的问题是将期间收到的股息添加到期末价格。
示例数据:
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
使用公司 RSG.AX(RIC=公司代码),2015 年至 2018 年的计算示例为:
3-year return = (End price + cumulative dividends) / Start price = (0.814+0.015+0.012)/0.182 = 4.63
Annualized return = (return)^(1/years)-1 = (4.63)^(1/3)-1 = 0.66 = 66%
如何使用 Python 执行此操作?也许 .groupby()
可以分离每个公司的数据。感谢您的帮助!
保持可读性 - 如果您真的想避免创建字典,可以使用 .apply
代替。
result = {}
for ric, grp in df.groupby('RIC'):
first, last = grp.iloc[-1], grp.iloc[0]
start_price, end_price = first.Price, last.Price
cum_div = grp.Dividend.sum()
return_ = (end_price + cum_div) / start_price
years = (last.Date - first.Date).days / 365
ann_return = return_ ** (1 / years) - 1
result[ric] = ann_return
result_df = pd.DataFrame.from_dict(result, orient='index')
print(result_df)
这适用于您数据框中的整个时期 - 如果您希望最后三年的更改为 grp.iloc[3]
(确保检查是否存在大量数据)。这也依赖于您的数据与样本建议的日期时间排序不变量一致这一事实。
使用shift()
从行above/below中获取值进行计算
方法一:对RIC使用循环
我在每个 RIC 上使用子数据帧 sub_df
的副本通过 df.RIC.unique()
循环它。假设当年的价格是 post-股息,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)
之后将 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
方法 2 - 在自定义函数上使用 groupby() 和 apply()
在方法一的基础上,我们可以定义一个自定义函数,通过groupby
RIC
来应用
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
仅供参考 - 结果看起来与您的示例有点不同,因为我发现您将 0.182
用作 start price
,而根据您的样本数据,它应该是 0.181
。
我有一个数据框,其中包含许多公司的年度价格和股息数据。我希望通过将三年内收到的所有股息添加到期末股价,然后计算复合年增长率来计算 3 年年化 return。我知道如何计算 CAGR,但我遇到的问题是将期间收到的股息添加到期末价格。
示例数据:
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
使用公司 RSG.AX(RIC=公司代码),2015 年至 2018 年的计算示例为:
3-year return = (End price + cumulative dividends) / Start price = (0.814+0.015+0.012)/0.182 = 4.63
Annualized return = (return)^(1/years)-1 = (4.63)^(1/3)-1 = 0.66 = 66%
如何使用 Python 执行此操作?也许 .groupby()
可以分离每个公司的数据。感谢您的帮助!
保持可读性 - 如果您真的想避免创建字典,可以使用 .apply
代替。
result = {}
for ric, grp in df.groupby('RIC'):
first, last = grp.iloc[-1], grp.iloc[0]
start_price, end_price = first.Price, last.Price
cum_div = grp.Dividend.sum()
return_ = (end_price + cum_div) / start_price
years = (last.Date - first.Date).days / 365
ann_return = return_ ** (1 / years) - 1
result[ric] = ann_return
result_df = pd.DataFrame.from_dict(result, orient='index')
print(result_df)
这适用于您数据框中的整个时期 - 如果您希望最后三年的更改为 grp.iloc[3]
(确保检查是否存在大量数据)。这也依赖于您的数据与样本建议的日期时间排序不变量一致这一事实。
使用shift()
从行above/below中获取值进行计算
方法一:对RIC使用循环
我在每个 RIC 上使用子数据帧 sub_df
的副本通过 df.RIC.unique()
循环它。假设当年的价格是 post-股息,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)
之后将 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
方法 2 - 在自定义函数上使用 groupby() 和 apply()
在方法一的基础上,我们可以定义一个自定义函数,通过groupby
RIC
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
仅供参考 - 结果看起来与您的示例有点不同,因为我发现您将 0.182
用作 start price
,而根据您的样本数据,它应该是 0.181
。