欢迎访问369期货网 369会员登录 注册

当前位置: 主页 > 期货量化

量化交易实战12 - 因子来了(三) 哪个因子最有效呢?(含代码)

时间:2025-10-15 16:06|来源:369期货网|作者:369期货网|点击:

昨天,西西跟朋友们一起挖了4个因子--市值、市现率倒数、净利润率和净利润增长率。

朋友们可能也会会问同样的问题:既然有4个因子,那我们究竟应该采用哪个指标来进行选股呢?是选择市值更大的?还是现金流更好的?抑或是选择净利润高净利润增长率高的呢?

如果让西西来做出选择,这个题目确实有难度。所以让机器帮我们梳理一下答案。

将4个因子存入一个DataFrame

这里的思路是,把4个因子进行降维处理,用一个主成分表示4个因子,这样我们就可以按照主成分的数值高低来选择股票了。输入代码如下:

    # 导入聚宽的因子分析库from jqfactor import get_factor_values# 使用 get_index_stocks 函数获取沪深300成分股# 使用 get_factor_values 函数获取这些成分股的市值、市现率倒数、净利润率和净利润增长率factor_mc = get_factor_values(    securities=get_index_stocks('000300.XSHG'),  # 获取沪深300成分股    factors=['market_cap'],  # 获取市值因子    end_date='2025-06-10',  # 结束日期    count=1  # 获取最近1天的数据)['market_cap']factor_cfp = get_factor_values(    securities=get_index_stocks('000300.XSHG'),      factors=['cash_flow_to_price_ratio'],     end_date='2025-06-10',      count=1)['cash_flow_to_price_ratio']factor_npr = get_factor_values(    securities=get_index_stocks('000300.XSHG'),  # 获取沪深300成分股    factors=['net_profit_ratio'],  # 获取净利润率因子    end_date='2025-06-10',  # 结束日期    count=1  # 获取最近1天的数据)['net_profit_ratio']factor_npgr = get_factor_values(    securities=get_index_stocks('000300.XSHG'),  # 获取沪深300成分股    factors=['net_profit_growth_rate'],  # 获取净利润增长率因子    end_date='2025-06-10',  # 结束日期    count=1  # 获取最近1天的数据)['net_profit_growth_rate']# 创建一个新的 DataFrame,索引与 factor_mc 的转置后的索引相同factors = pd.DataFrame(index=factor_mc.T.index)# 在新的 DataFrame 中创建 4 个字段,并存储特定日期的数据factors['mc'] = factor_mc.T['2025-06-10 00:00:00']  # 市值factors['cfp'] = 1 / factor_cfp.T['2025-06-10 00:00:00']  # 市现率倒数factors['npr'] = factor_npr.T['2025-06-10 00:00:00']  # 净利润率factors['npgr'] = factor_npgr.T['2025-06-10 00:00:00']  # 净利润增长率# 检查结果print(factors.head())

    运行代码:

    图片

    这一步比较简单,就是把之前定义过的市值、实现率倒数、净利润率和净利润增长率存在一个数据表中。

    使用PCA提取主成分

    下面我们就开始进行主成分分析的过程。说到主成分分析,第一个想到的就是主成分分析(Principle Component Analysis,PCA)算法。PCA是一种无监督学习算法,在数据科学领域,常用于进行样本特征的降维处理。关于PCA的原理,就不解释了,只要大家明白,这个算法就是通过方差来确定样本各个特征的重要性,并且给它们分配不同的权重(重要性越高的特征,分配的权重也越高),并根据权重,将高维数据降到低维的过程。如果还是有朋友对详细的 PCA 原理感兴趣,自行在网上进行搜索即可。为了便于计算,数据中不能有空值,所以要用下面的代码进行处理。

      #为了计算,先把数据中的空值去掉factors = factors.dropna()#检查是否还有空值factors.isnull().sum()
      图片

      【结果分析】从上面的代码运行结果中可以看到,经过去除空值的处理后,样本的4个因子中均没有空值了。

      接下来,我们使用PCA来对4个因子进行降维处理。考虑到各个因子的量纲差异比较大,这里我们先进行数据缩放的步骤,再进行主成分分析。

      输入代码如下:(只是这部分的代码,最终代码在最后)

        # 使用 StandardScaler 缩放原始的因子值scaler = StandardScaler()factors_scl = scaler.fit_transform(factors)# 使用 PCA,提取主成分数量指定为 1pca = PCA(n_components=1)pca.fit(factors_scl)# 查看 PCA 给各因子分配的权重print("PCA 给各因子分配的权重:", pca.components_)# 检查结果print(factors.head())
        图片

        【结果分析】仔细观察代码运行结果(PCA给4个因子分配的权重),我们会发现,PCA给净利润率增长率分配的权重是最高的,约为0.61;市现率倒数的权重紧随其后,约为0.59。大家是不是也觉得这个结果有一定的合理性--毕竟净利润率高确实代表企业的盈利能力不错,现金流高也说明企业处于比较好的运营状态。


        找到主成分数值最高的股票


        接着西西就尝试将PCA提取的主成分添加到数据表里,并找到主成分数值最高的几只股票。

        代码:

          # 在factors数据表中添加一个pca字段# 存储提取出来的主成分factors['pca'] = pca.transform(factors_scl)  # 将主成分值添加到factors数据表中# 看一下主成分数值最高的5只股票# 按pca字段降序排序并展示前5行top_5_stocks = factors.sort_values(by='pca', ascending=False).head()print("主成分数值最高的5只股票:")print(top_5_stocks)




          图片



          【结果分析】从表可以看到,系统返回了主成分分值最高的5只股票。以第一只股票000617为例,这只股票的总市值并不算很大,只有862亿元左右:需要注意的是,其净利润率竟然约为1075.23%!虽然净利润增长率在减少,但是基础高啊。仅从数据上看,这算是很优秀的股票了。

          注意:这里展示的只是一个简单的思路。实际上,关于因子选股的思路和方法有很多种。朋友们可以发挥自己的聪明才智,通过使用不同的因子与算法,找到最适合自己的投资组合。

          全部代码:

            # 导入聚宽的因子分析库from jqfactor import get_factor_valuesimport pandas as pdimport numpy as npfrom sklearn.preprocessing import StandardScalerfrom sklearn.decomposition import PCA# 使用 get_index_stocks 函数获取沪深300成分股# 使用 get_factor_values 函数获取这些成分股的市值、市现率、净利润率和净利润增长率factor_mc = get_factor_values(    securities=get_index_stocks('000300.XSHG'),  # 获取沪深300成分股    factors=['market_cap'],  # 获取市值因子    end_date='2025-06-10',  # 结束日期    count=1  # 获取最近1天的数据)['market_cap']factor_cfp = get_factor_values(    securities=get_index_stocks('000300.XSHG'),      factors=['cash_flow_to_price_ratio'],     end_date='2025-06-10',      count=1)['cash_flow_to_price_ratio']factor_npr = get_factor_values(    securities=get_index_stocks('000300.XSHG'),  # 获取沪深300成分股    factors=['net_profit_ratio'],  # 获取净利润率因子    end_date='2025-06-10',  # 结束日期    count=1  # 获取最近1天的数据)['net_profit_ratio']factor_npgr = get_factor_values(    securities=get_index_stocks('000300.XSHG'),  # 获取沪深300成分股    factors=['net_profit_growth_rate'],  # 获取净利润增长率因子    end_date='2025-06-10',  # 结束日期    count=1  # 获取最近1天的数据)['net_profit_growth_rate']# 创建一个新的 DataFrame,索引与 factor_mc 的转置后的索引相同factors = pd.DataFrame(index=factor_mc.T.index)# 在新的 DataFrame 中创建 4 个字段,并存储特定日期的数据factors['mc'] = factor_mc.T['2025-06-10 00:00:00']  # 市值factors['cfp'] = 1 / factor_cfp.T['2025-06-10 00:00:00']  # 市现率倒数# 检查市现率是否为零,避免除以零的情况factors.loc[factor_cfp.T['2025-06-10 00:00:00'] == 0, 'cfp'] = np.nanfactors['npr'] = factor_npr.T['2025-06-10 00:00:00']  # 净利润率factors['npgr'] = factor_npgr.T['2025-06-10 00:00:00']  # 净利润增长率# 检查数据中的 NaN 和无穷大值print("检查数据中的 NaN 和无穷大值:")print(factors.isnull().sum())  # 检查每列的 NaN 数量print(factors.apply(lambda x: np.isinf(x).sum()))  # 检查每列的无穷大值数量# 填充 NaN 值(例如用均值填充)factors.fillna(factors.mean(), inplace=True)# 确保没有无穷大值factors.replace([np.inf, -np.inf], np.nan, inplace=True)factors.fillna(factors.mean(), inplace=True)# 使用 StandardScaler 缩放原始的因子值scaler = StandardScaler()factors_scl = scaler.fit_transform(factors)# 使用 PCA,提取主成分数量指定为 1pca = PCA(n_components=1)pca.fit(factors_scl)# 查看 PCA 给各因子分配的权重print("PCA 给各因子分配的权重:", pca.components_)# 在factors数据表中添加一个pca字段# 存储提取出来的主成分factors['pca'] = pca.transform(factors_scl)  # 将主成分值添加到factors数据表中# 看一下主成分数值最高的5只股票# 按pca字段降序排序并展示前5行top_5_stocks = factors.sort_values(by='pca', ascending=False).head()print("主成分数值最高的5只股票:")print(top_5_stocks)


            编辑推荐

            Copyright © 2024-2025 成都宁时科技有限公司 版权所有

            蜀ICP备2022023994号