
为什么需要自己计算股票因子
公开的因子数据往往滞后或经过平滑处理,直接用于实盘容易失效。用python从原始行情和财务数据出发,构建自定义因子,能更好控制因子暴露和更新频率。期货因子与股票因子存在联动,跨品种因子挖掘可以提高策略夏普比率。
数据准备与清洗
从tushare、akshare或本地数据库获取日频行情。处理停牌、涨跌停、新股上市不足60日等异常样本。复权价格用后复权,避免除权跳空干扰动量因子。
import pandas as pd
def clean_price(df):
df = df[df['volume'] > 0]
df = df[~df['trade_status'].isin(['停牌', '一字板'])]
df['adj_close'] = df['close'] * df['adj_factor']
return df
财务数据需要按公告日对齐,不能用报告期直接匹配,否则引入未来函数。季度数据用最新公告值填充,滞后45天更安全。
常见股票因子计算逻辑
动量因子
过去20日收益率减去过去5日收益率,剔除短期反转。python向量化计算:

factors['mom_20_5'] = df.groupby('code')['adj_close'].pct_change(20) - df.groupby('code')['adj_close'].pct_change(5)
波动率因子
20日收益率标准差除以60日标准差,衡量短期波动相对长期波动。低波动因子在A股长期有效。
换手率因子
过去20日平均换手率除以过去120日平均换手率。高换手往往伴随投机,因子值取负向。
估值因子
EP等于净利润除以总市值,BP等于净资产除以总市值。使用TTM净利润,市值用当日总市值。
质量因子
ROE稳定性用过去8个季度ROE标准差倒数,毛利率变化用同比差值。
期货因子的特殊处理
期货因子需要处理展期收益和保证金杠杆。计算基差动量:近月合约价格减远月合约价格,除以远月价格,取20日变化率。持仓量因子用会员持仓多空比变化。
def futures_basis_mom(near, far, window=20):
basis = (near - far) / far
return basis.pct_change(window)
期货因子与股票因子合成时,注意波动率量纲差异,用滚动zscore标准化。
因子标准化与中性化
横截面标准化:每个交易日对因子做zscore,剔除极值3倍标准差以外。
行业中性化:用申万一级行业哑变量回归,取残差。市值中性化:对对数市值回归,取残差。
import statsmodels.api as sm
def neutralize(factor, industry, mktcap):
X = pd.concat([industry, np.log(mktcap)], axis=1)
X = sm.add_constant(X)
model = sm.OLS(factor, X, missing='drop').fit()
return model.resid
因子有效性检验
IC值:Rank IC用spearman相关系数,月度IC均值大于0.03,IR大于0.5可用。
分层回测:按因子值分5组,多空组合年化收益大于15%,最大回撤小于20%。
换手率分析:因子自相关系数低于0.7需要控制调仓频率。
多因子合成与期货对冲
用等权或IC加权合成股票因子。期货端用股指期货对冲beta,用商品期货因子做跨品种套利。
合成因子 = 0.3 * 动量 + 0.2 * 波动 + 0.2 * 换手 + 0.3 * 估值
权重用滚动36个月IC均值确定,每季度调整。
实盘注意事项
因子失效监控:连续3个月IC为负,降权处理。
数据延迟:财务因子用公告日,行情因子用收盘后数据。
交易成本:双边千分之三,期货万分之五。
避免过拟合:因子逻辑先于回测,样本外测试至少2年。
python股票因子计算需要扎实的数据工程和严谨的统计检验,期货因子提供额外分散化收益。持续迭代因子库比寻找单一神奇因子更重要。