Python量化选股:如何通过因子模型筛选股票池?
在现代金融投资中,量化选股已成为主流策略之一。与传统的主观判断不同,量化选股依赖于数据和数学模型来选择具有潜在超额收益的股票。其中,因子模型(Factor Model) 是最常用的方法之一。本文将介绍如何使用 Python 搭建一个基于因子模型的量化选股系统,并实现从海量股票中筛选出优质股票池。
一、什么是因子模型?
因子模型是一种通过分析影响股票收益率的多个因子(变量),来预测未来股票表现的方法。其基本思想是:某些特定因素对股票价格变动具有显著影响,例如市盈率(PE)、市值(Market Cap)、动量(Momentum)等。
常见的因子包括:
估值类因子:如市盈率(PE)、市净率(PB)、市销率(PS) 成长类因子:如营收增长率、净利润增长率 质量类因子:如ROE(净资产收益率)、毛利率、负债率 动量类因子:如过去60日涨幅、换手率 规模类因子:总市值、流通市值这些因子可以组合起来构建一个多因子模型,用于评估每只股票的投资价值。
二、因子模型选股的基本流程
数据获取 因子选取与处理 因子标准化与去极值 因子权重确定 综合得分计算 排序并筛选股票池我们将使用 Python 来逐步实现上述流程。
三、Python 实现多因子选股模型
1. 数据获取
我们可以使用 Tushare 或 akshare 等库获取 A 股市场数据。
import tushare as ts import pandas as pd # 初始化 Tushare 接口 ts.set_token(‘你的token’) pro = ts.pro_api() # 获取股票基本信息 stock_basic = pro.query(‘stock_basic’, exchange=”, list_status=’L’) # 获取财务数据 def get_financial_data(ts_code): df = pro.query(‘fina_indicator’, ts_code=ts_code, limit=1) return df[[‘ts_code’, ‘roa’, ‘grossprofit_margin’, ‘pb’, ‘pe’, ‘total_assets’, ‘revenue_yoy’]] # 获取行情数据 def get_market_data(ts_code): df = ts.pro_bar(ts_code=ts_code, adj=’qfq’, start_date=’20230101′, end_date=’20240101′) if not df.empty: df[‘momentum’] = df[‘close’].pct_change(60).iloc[-1] # 计算60日动量 return df[[‘ts_code’, ‘momentum’]].iloc[[0]] return pd.DataFrame({‘ts_code’: [ts_code], ‘momentum’: [None]})2. 构建因子表
我们选取以下因子:
PE(市盈率) PB(市净率) ROA(资产回报率) Gross Profit Margin(毛利率) Momentum(动量) Revenue YoY(营收同比增长) factor_list = [] for ts_code in stock_basic[‘ts_code’]: financial_df = get_financial_data(ts_code) market_df = get_market_data(ts_code) combined_df = pd.merge(financial_df, market_df, on=’ts_code’, how=’left’) factor_list.append(combined_df) all_factors = pd.concat(factor_list, ignore_index=True)3. 因子清洗与处理
我们需要剔除缺失值、异常值,并进行标准化处理。
from sklearn.preprocessing import StandardScaler # 去除空值 all_factors.dropna(inplace=True) # 去极值(winsorize) def winsorize(df, cols): for col in cols: q1 = df[col].quantile(0.01) q99 = df[col].quantile(0.99) df[col] = df[col].clip(q1, q99) return df cols_to_winsorize = [‘pe’, ‘pb’, ‘roa’, ‘grossprofit_margin’, ‘momentum’, ‘revenue_yoy’] all_factors = winsorize(all_factors, cols_to_winsorize) # 标准化 scaler = StandardScaler() scaled_factors = scaler.fit_transform(all_factors[cols_to_winsorize]) all_factors_scaled = pd.DataFrame(scaled_factors, columns=cols_to_winsorize, index=all_factors.index) all_factors.reset_index(drop=True, inplace=True) all_factors_scaled.reset_index(drop=True, inplace=True) final_df = pd.concat([all_factors[[‘ts_code’]], all_factors_scaled], axis=1)4. 设置因子权重
我们可以采用等权法或根据历史回测结果优化权重。
weights = { ‘pe’: -0.2, # 越低越好 ‘pb’: -0.2, ‘roa’: 0.2, # 越高越好 ‘grossprofit_margin’: 0.2, ‘momentum’: 0.1, ‘revenue_yoy’: 0.1 } # 计算综合得分 final_df[‘score’] = ( final_df[‘pe’] * weights[‘pe’] + final_df[‘pb’] * weights[‘pb’] + final_df[‘roa’] * weights[‘roa’] + final_df[‘grossprofit_margin’] * weights[‘grossprofit_margin’] + final_df[‘momentum’] * weights[‘momentum’] + final_df[‘revenue_yoy’] * weights[‘revenue_yoy’] )5. 筛选股票池
按综合得分排序,选出前20%的股票作为候选池。
top_stocks = final_df.sort_values(by=’score’, ascending=False).head(int(len(final_df) * 0.2)) print(top_stocks[[‘ts_code’, ‘score’]])四、因子有效性检验(可选)
为了验证所选因子是否有效,可以做如下分析:
IC值(信息系数):衡量因子与未来收益的相关性。 分层回测:将股票按因子得分分为几组,观察各组的历史收益差异。 因子间相关性分析:避免因子之间高度相关,导致模型不稳定。 import seaborn as sns import matplotlib.pyplot as plt corr_matrix = final_df[cols_to_winsorize].corr() sns.heatmap(corr_matrix, annot=True, cmap=’coolwarm’) plt.title(“Factor Correlation Matrix”) plt.show()五、总结与展望
本文介绍了如何使用 Python 构建一个基于多因子模型的量化选股系统。核心步骤包括:
数据获取与清洗; 因子选取与处理; 因子标准化与加权; 综合得分计算; 筛选优质股票池。该模型可以进一步扩展为自动化交易系统,结合择时策略和风险管理模块,实现完整的量化投资闭环。
在未来的工作中,可以尝试引入机器学习方法(如随机森林、XGBoost)来自动生成因子权重,甚至进行特征工程优化,从而提升选股效果。
六、参考资料
Tushare 官方文档:https://tushare.pro/ 《量化投资:策略与技术》——丁鹏 《多因子选股模型详解》,雪球专栏 Scikit-learn 文档:https://scikit-learn.org/stable/如果你正在学习量化投资或者希望进入量化交易领域,掌握因子模型是非常重要的一步。希望这篇文章能为你提供清晰的思路和实践指导!