量化因子(三)市值、市现率倒数、净利润率和净利润增长率哪个因子最有效?
发布时间:2025-7-16 13:39阅读:236
前一篇文章一起挖了4个因子--市值、市现率倒数、净利润率和净利润增长率。
朋友们可能也会会问同样的问题:既然有4个因子,那我们究竟应该采用哪个指标来进行选股呢?是选择市值更大的?还是现金流更好的?抑或是选择净利润高净利润增长率高的呢?
这个题目确实有难度。所以让机器帮我们梳理一下答案。
将4个因子存入一个DataFrame
这里的思路是,把4个因子进行降维处理,用一个主成分表示4个因子,这样我们就可以按照主成分的数值高低来选择股票了。输入代码如下:
我司上市券商,佣金成本价,专项两融利率4.0,免费提供量化软件qmt和ptrade,欢迎咨询!!!
# 导入聚宽的因子分析库
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,提取主成分数量指定为 1
pca = 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_values
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from 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.nan
factors['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,提取主成分数量指定为 1
pca = 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)


温馨提示:投资有风险,选择需谨慎。
-
2025国庆长假投资“不放假”:中信证券推荐闲钱理财攻略
2025-09-09 09:53
-
【麒麟芯片】时隔四年重现华为发布会,释放了哪些关键信号?
2025-09-09 09:53
-
6只中证A500系列指数即将发布,对投资者有啥参考价值?
2025-09-09 09:53