``` import pandas as pd import numpy as np import matplotlib.pyplot as plt import warnings warnings.filterwarnings("ignore") from Dylan import factor_correlation as FactorIC from Dylan import factor_group as FactorGroup sw_ind = pd.read_pickle('IndexComponent_SWN_I.txt') stock_close = pd.read_pickle('StockQuote_ClosePrice_BackwardAdj.txt') stock_open = pd.read_pickle('StockQuote_OpenPrice_BackwardAdj.txt') monthly_trading_day = pd.read_pickle('monthly_trading_day.pkl') monthly_trading_day['start_date'] = pd.to_datetime(monthly_trading_day['start_date'], format='%Y%m%d') monthly_trading_day['end_date'] = pd.to_datetime(monthly_trading_day['end_date'], format='%Y%m%d') start_date = pd.to_datetime('20120101', format='%Y%m%d') end_date = pd.to_datetime('20231231', format='%Y%m%d') filtered_trading_days = monthly_trading_day.loc[(monthly_trading_day['end_date'] >= start_date) & (monthly_trading_day['end_date'] <= end_date)] stock_close.index = pd.to_datetime(stock_close.index) stock_open.index = pd.to_datetime(stock_open.index) stock_ret_monthly = stock_close.reindex(index = filtered_trading_days.end_date).pct_change() stock_ret_monthly_nextopen = stock_open.shift(-1).reindex(filtered_trading_days.end_date).pct_change() def simple_factor_test(factor,use_data = 'this_close'): if use_data=='this_close': this_ret_data = stock_ret_monthly.shift(-1) else: this_ret_data = stock_ret_monthly_nextopen.shift(-1) ic,rankic = FactorIC(factor,this_ret_data) factor_group = FactorGroup(factor) condata = pd.concat([factor_group.unstack(),this_ret_data.unstack()],axis=1).dropna().reset_index() condata.columns =['stockcode','date','group_id','ret'] group_ret = condata.groupby(['date','group_id'])['ret'].mean().unstack() return ic,rankic,group_ret pe = pd.read_pickle('StockQuote_PEttm.txt') pe```添加注释
首先,代码开始导入了几个库:pandas、numpy、matplotlib,还有warnings模块。用户可能知道这些库的基本用途,但可能需要注释说明为什么在这里使用它们。例如,pandas用于数据处理,numpy用于数值计算,matplotlib用于绘图,而warnings模块用来忽略警告信息,避免输出干扰。
接下来,从Dylan模块导入了factor_correlation和factor_group,分别重命名为FactorIC和FactorGroup。这里需要注释说明这两个函数的作用,可能涉及因子分析和分组计算,比如计算因子与收益的相关性,或者将因子分组。
然后,读取了几个pickle文件,包括sw_ind、stock_close、stock_open和monthly_trading_day。这些文件可能存储了行业指数成分、股票的收盘价、开盘价以及每月的交易日信息。注释需要解释每个变量的内容和结构,比如sw_ind可能是申万行业指数成分股的数据,stock_close是后复权的收盘价等。
处理monthly_trading_day的部分,将日期列转换为datetime对象,并进行筛选,保留指定开始和结束日期之间的交易日。这里需要说明转换日期格式的原因,以及筛选的目的,可能是为了后续分析的时间范围限制。
调整stock_close和stock_open的索引为datetime格式,方便时间序列操作。注释应指出这一步的重要性,确保时间对齐。
接下来计算月度收益率stock_ret_monthly和stock_ret_monthly_nextopen。前者使用收盘价的重采样和下期收益,后者考虑了下个月的开盘价。这里需要解释pct_change()的作用,以及reindex如何与交易日对齐,可能涉及避免未来数据的问题。
定义simple_factor_test函数,这个函数似乎用于因子测试,计算IC、Rank IC和分组收益。参数use_data决定使用哪种收益率数据。注释需要详细说明函数的参数、返回值,以及内部如何调用FactorIC和FactorGroup函数。可能还要解释condata的构建过程,如何将因子分组与收益数据合并,计算各组的平均收益。
最后读取pe数据,即市盈率指标,作为因子之一。需要说明这是因子测试中的一个示例因子。
在添加注释时,要注意代码的结构,分块进行解释,确保每部分的功能清晰。同时,要使用中文,保持注释简洁但信息量足够,帮助用户理解代码的逻辑和实现细节。可能需要检查是否有遗漏的关键步骤,比如日期处理、数据对齐、函数参数的具体作用等,确保注释覆盖所有重要部分。以下是添加注释后的代码及逐段解析:
# 导入基础数据分析库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 忽略警告提示
import warnings
warnings.filterwarnings("ignore")
# 导入自定义因子分析模块
from Dylan import factor_correlation as FactorIC # 因子IC分析
from Dylan import factor_group as FactorGroup # 因子分组分析
# 读取申万行业成分数据
sw_ind = pd.read_pickle('IndexComponent_SWN_I.txt')
# 读取后复权收盘价数据(用于计算常规收益率)
stock_close = pd.read_pickle('StockQuote_ClosePrice_BackwardAdj.txt')
# 读取后复权开盘价数据(用于计算开盘收益率)
stock_open = pd.read_pickle('StockQuote_OpenPrice_BackwardAdj.txt')
# 加载月度交易日历数据
monthly_trading_day = pd.read_pickle('monthly_trading_day.pkl')
# 转换日期格式:字符串 -> datetime对象
monthly_trading_day['start_date'] = pd.to_datetime(monthly_trading_day['start_date'], format='%Y%m%d')
monthly_trading_day['end_date'] = pd.to_datetime(monthly_trading_day['end_date'], format='%Y%m%d')
# 设置分析时间段
start_date = pd.to_datetime('20120101', format='%Y%m%d') # 起始日期:2012-01-01
end_date = pd.to_datetime('20231231', format='%Y%m%d') # 结束日期:2023-12-31
# 筛选在时间范围内的交易日
filtered_trading_days = monthly_trading_day.loc[
(monthly_trading_day['end_date'] >= start_date) &
(monthly_trading_day['end_date'] <= end_date)
]
# 统一时间索引格式(确保后续数据对齐)
stock_close.index = pd.to_datetime(stock_close.index)
stock_open.index = pd.to_datetime(stock_open.index)
# 计算月度收盘收益率(使用月末收盘价计算)
stock_ret_monthly = stock_close.reindex(index=filtered_trading_days.end_date).pct_change()
# 计算月度开盘收益率(使用次月开盘价计算)
stock_ret_monthly_nextopen = stock_open.shift(-1).reindex(filtered_trading_days.end_date).pct_change()
def simple_factor_test(factor, use_data='this_close'):
"""
单因子测试框架
参数:
factor: 输入的因子数据(DataFrame格式,索引为日期,列为股票代码)
use_data: 收益率数据选择,默认使用常规收盘收益率
返回:
ic: 普通IC序列
rankic: 秩IC序列
group_ret: 分组收益率
"""
# 选择收益率类型
if use_data == 'this_close':
this_ret_data = stock_ret_monthly.shift(-1) # 常规收盘收益率(避免未来数据)
else:
this_ret_data = stock_ret_monthly_nextopen.shift(-1) # 开盘收益率
# 计算因子IC值
ic, rankic = FactorIC(factor, this_ret_data)
# 进行因子分组
factor_group = FactorGroup(factor)
# 合并因子分组与收益率数据
condata = pd.concat([factor_group.unstack(), this_ret_data.unstack()], axis=1).dropna().reset_index()
condata.columns = ['stockcode', 'date', 'group_id', 'ret']
# 计算分组平均收益率
group_ret = condata.groupby(['date', 'group_id'])['ret'].mean().unstack()
return ic, rankic, group_ret
# 读取市盈率因子数据(示例因子)
pe = pd.read_pickle('StockQuote_PEttm.txt')
关键功能说明:
- 数据对齐机制:通过
reindex()
确保所有数据使用统一的交易日历 - 收益率计算逻辑:
- 常规收益率:$R_t = \frac{Close_{t+1}}{Close_t} - 1$
- 开盘收益率:$R_t = \frac{Open_{t+1}}{Close_t} - 1$
- 避免未来数据:使用
shift(-1)
将收益率滞后一期,确保因子值不会使用未来信息 - 分组收益计算:将股票按因子值分为若干组,计算各组在下一期的平均收益率
统计指标说明:
- IC(信息系数):衡量因子值与下期收益率的线性相关性,计算公式: $$ IC_t = corr(factor_t, ret_{t+1}) $$
- Rank IC:使用因子排序和收益排序的Spearman相关系数,计算公式: $$ RankIC_t = corr(rank(factor_t), rank(ret_{t+1})) $$
相关推荐



















