使用所有在上交所交易股票2000年1月至2021年12月的月度收益率数据,注意,该数据为excel格式,第一列为股票代码,第二列为日期,第三列为股票的收盘价数据,总共有800余只股票的19万余行数据,需要先对数据进行处理。然后,以2001年1月至2020年12月作为投资组合构造期,在每一个月,首先,计算过去 1个月、3个月、6个月和12个月的累积收益率;然后,在每个月的月末,根据过去1个月、3个月、6个月和12个月的收益率,由低到高分别将所有股票排序,根据排序构造5个等权重投资组合;接下来将这5个组合持有1个月、3个月、6个月或12个月;最后计算每个组合的平均持有期收益率。给出上述过程的python代码,以检验股市中具有惯性效应还是反转效应。注意不要出现AttributeError: 'numpy.ndarray' object has no attribute 'index'的错误形式。
时间: 2024-03-10 21:48:48 浏览: 133
由于数据量较大,处理数据的过程可能较为耗时,建议采用Pandas库进行处理。以下为代码实现:
```python
import pandas as pd
import numpy as np
# 读取数据
data = pd.read_excel('data.xlsx')
# 重命名列名为code, date, close
data.columns = ['code', 'date', 'close']
# 将日期转换为时间格式
data.date = pd.to_datetime(data.date)
# 将数据按照时间排序
data = data.sort_values(['date', 'code'])
# 计算每只股票的月度收益率
data['return'] = data.groupby('code')['close'].pct_change()
# 去除第一行数据
data = data.dropna()
# 构造投资组合
start_date = pd.to_datetime('2001-01-01')
end_date = pd.to_datetime('2020-12-31')
portfolio_dates = pd.date_range(start_date, end_date, freq='BM')
month_returns = pd.DataFrame(index=portfolio_dates, columns=['1m', '3m', '6m', '12m'])
for date in portfolio_dates:
# 计算过去1个月、3个月、6个月和12个月的收益率
past_1m = data[(data.date < date) & (data.date >= date - pd.DateOffset(months=1))]
past_3m = data[(data.date < date) & (data.date >= date - pd.DateOffset(months=3))]
past_6m = data[(data.date < date) & (data.date >= date - pd.DateOffset(months=6))]
past_12m = data[(data.date < date) & (data.date >= date - pd.DateOffset(months=12))]
month_returns.loc[date]['1m'] = past_1m.groupby('code')['return'].sum().mean()
month_returns.loc[date]['3m'] = past_3m.groupby('code')['return'].sum().mean()
month_returns.loc[date]['6m'] = past_6m.groupby('code')['return'].sum().mean()
month_returns.loc[date]['12m'] = past_12m.groupby('code')['return'].sum().mean()
# 构造等权重投资组合
portfolios = []
for date in portfolio_dates:
# 按照过去1个月、3个月、6个月和12个月的收益率分别排序
past_1m = data[(data.date < date) & (data.date >= date - pd.DateOffset(months=1))].groupby('code')['return'].sum().sort_values()
past_3m = data[(data.date < date) & (data.date >= date - pd.DateOffset(months=3))].groupby('code')['return'].sum().sort_values()
past_6m = data[(data.date < date) & (data.date >= date - pd.DateOffset(months=6))].groupby('code')['return'].sum().sort_values()
past_12m = data[(data.date < date) & (data.date >= date - pd.DateOffset(months=12))].groupby('code')['return'].sum().sort_values()
# 分别取排名前20%的股票构造投资组合
p1 = past_1m[past_1m.index.isin(past_1m.index[:int(len(past_1m)/5)])]
p3 = past_3m[past_3m.index.isin(past_3m.index[:int(len(past_3m)/5)])]
p6 = past_6m[past_6m.index.isin(past_6m.index[:int(len(past_6m)/5)])]
p12 = past_12m[past_12m.index.isin(past_12m.index[:int(len(past_12m)/5)])]
portfolios.append({'1m': p1, '3m': p3, '6m': p6, '12m': p12})
# 计算持有期收益率
holding_periods = [1, 3, 6, 12]
portfolio_returns = pd.DataFrame(index=portfolio_dates, columns=holding_periods)
for i, portfolio in enumerate(portfolios):
for period in holding_periods:
start = portfolio_dates[i]
end = start + pd.DateOffset(months=period)
# 获取持有期内的所有股票收益率
returns = data[(data.date >= start) & (data.date < end)].groupby('code')['return'].sum()
# 计算持有期收益率
portfolio_returns.loc[start][period] = portfolio[str(period)][portfolio[str(period)].index.isin(returns.index)].mean()
# 计算每个持有期的平均持有期收益率
average_returns = portfolio_returns.mean()
# 输出结果
print('平均持有期收益率:')
print(average_returns)
```
运行结果将会输出每个持有期的平均持有期收益率。根据这些数据,可以进行惯性效应和反转效应的检验。
阅读全文