首页 > 解决方案 > Python 复合回报分组依据

问题描述

我正在尝试计算每只股票在 python 中的每日回报的每月复合回报。

我的数据集如下所示:

DATE    STOCK   RETURN  Year    Month
1/1/2020    A   0.02    2020    1
1/1/2020    B   0.03    2020    1
1/2/2020    A   0.04    2020    1
1/2/2020    B   0.05    2020    1
...             
6/30/2020   A   0.01    2020    6
6/30/2020   B   0.03    2020    6

我已经尝试过df. groupby([STOCK','Year',’Month’])[‘RETURN'].apply(cum_returns),但它并没有给出分组结果。理想情况下,我试图得到类似的东西:

DATE       STOCK CUMULATIVE RETURN
01/2020    A      (1+0.02)*(1+0.04).... (1+rn) / (1/n) 
01/2020    B       same formula above for B daily stock returns
02/20      A
02/20      B
...
06/30     A
06/30     B

我使用的功能是:

def cum_returns (x):
    a = x.add(1).cumprod()
    a.iloc[0] = 1
    return a

感谢您的帮助!

标签: pythonpandaspandas-groupby

解决方案


假设我们有数据框:

DATE STOCK RETURN Year Month
1/1/2020 A 0.02 2020 1
2/1/2020 A 0.01 2020 1
3/1/2020 A 0.04 2020 1
1/1/2020 B 0.03 2020 1
2/1/2020 B 0.01 2020 1
3/1/2020 B 0.04 2020 1
1/2/2020 A 0.05 2020 2
2/2/2020 A 0.02 2020 2
3/2/2020 A 0.01 2020 2
4/2/2020 A 0.04 2020 2
1/2/2020 B 0.01 2020 2
2/2/2020 B 0.03 2020 2
3/2/2020 B 0.02 2020 2
4/2/2020 B 0.05 2020 2

要计算每个月和股票使用的每日回报的几何平均值(检查定义):

df.groupby(['STOCK','Year','Month'])[['RETURN']].apply(lambda g: ((g+1).cumprod()**(1/len(g))-1).iloc[-1])

结果:

                    RETURN
STOCK Year Month          
A     2020 1      0.023258
           2      0.029879
B     2020 1      0.026591
           2      0.027394

您可以手动检查计算是否正确,例如股票 A 和 Jan:

(1.02*1.01*1.04)**(1/3)-1 = 0.023258

请注意,iloc[-1]在 lambda 函数中选择每组最后计算的回报。


推荐阅读