pandas 数据框中按组滚动回归

JL1*_*118 6 python pandas

我有一个 pandas 数据框,其中包含 1963 年至 2012 年各个公司的每日股票收益(近 6000 万行)。我想要估计 CAPM 贝塔值,因此我需要在过去 250 天内对每家公司运行滚动 OLS 回归,并将贝塔值添加到现有数据帧中。

我已经尝试将 pyfinance 包中的 PandasRollingOLS 函数与“groupby”结合起来,但它只返回内存错误。我还尝试编写两个 for 循环,第一个按公司分组(“PERMNO”),第二个 for 循环执行滚动回归。然而,这也行不通

我的数据框如下所示:

           PERMNO       RET       mkt       RF
date                                          
1986-01-08  10000 -0.024640 -0.020994  0.00025
1986-01-09  10000 -0.000250 -0.011469  0.00025
1986-01-10  10000 -0.000250 -0.000167  0.00025
1986-01-13  10000  0.049750  0.002499  0.00025
1986-01-14  10000  0.047369  0.000116  0.00025
1986-01-15  10000  0.045205  0.007956  0.00025
1986-01-16  10000  0.043228  0.004452  0.00025
1986-01-17  10000 -0.000250 -0.001991  0.00025
1986-01-20  10000 -0.000250 -0.003985  0.00025
1986-01-21  10000 -0.000250 -0.007242  0.00025

Run Code Online (Sandbox Code Playgroud)
rolling = daily.groupby('PERMNO').apply(lambda x: ols.PandasRollingOLS(y=daily['RET'], x=daily['mkt'], window=250))
Run Code Online (Sandbox Code Playgroud)
regression=np.zeros((len(daily.index),2))

for group_name, df_group in daily_grouped:
    for row in range(0,len(daily.index),1):
        y= daily.RET[row:row + 250]
        x= daily.mkt[row:row + 250]
        regression[row]=np.polyfit(x,y,1)

daily['beta']=regression[:,0]
Run Code Online (Sandbox Code Playgroud)

我想知道如何从公司的滚动回归中获取贝塔值

小智 2

我对 pyfinance 不太熟悉,但statsmodels.regression.rolling.RollingOLS可以工作:

# Importing
import pandas as pd
from statsmodels.regression.rolling import RollingOLS
import statsmodels.api as sm
import numpy as np

# Creating mock data
permno = []
for i in range(0, 10000):
    permno.append(int(i//2200)+10000)

daily = pd.DataFrame(data={"PERMNO": permno, "RET": np.random.random(10000)*2-1,
                           "mkt": np.random.random(10000)*2-1, "RF": np.random.random(10000)*2-1},
                     index=pd.date_range(start="1963-01-01", periods=10000, freq="B"))

# Rolling OLS calculation
rolling = daily.groupby("PERMNO").apply(lambda x: RollingOLS(endog=x['RET'], exog=sm.add_constant(x['mkt']), window=250).fit().params)
Run Code Online (Sandbox Code Playgroud)

请注意,我使用x["dataframe col name"]not daily["dataframe col name"]。我认为这就是问题的原因,因为您在计算中使用了apply(lambda x:但根本没有使用。x您也许可以将代码从 daily 更改为 x 并发现它有效。

我已经尝试使用您的滚动计算进行 pyfinance,但收到以下内容(这就是 statsmodels RollingOLS 当没有.fit().params添加到末尾来实际返回相关数据时发生的情况,这表明您在代码末尾需要更多信息 - 可能.beta到最后?)。要更改代码,如果您需要y=x=,请使用其他内容代替 x,例如lambda q,那么您可以使用y=q['RET'], x=q['mkt']

#Out: 
#PERMNO
#10000    <pyfinance.ols.PandasRollingOLS object at 0x00...
#10001    <pyfinance.ols.PandasRollingOLS object at 0x00...
#10002    <pyfinance.ols.PandasRollingOLS object at 0x00...
#10003    <pyfinance.ols.PandasRollingOLS object at 0x00...
#10004    <pyfinance.ols.PandasRollingOLS object at 0x00...
#dtype: object
Run Code Online (Sandbox Code Playgroud)