🚀 AI 一键生成 joinquant 策略代码
立即体验

聚宽平台如何构建结合 PEG、净利率与成长能力的多因子选股策略?

joinquant | 发布时间: 2026/8/11
以下内容由 EasyQuant 生成。

问题描述

聚宽 PEG 与净利率因子选股:如何组合盈利和成长因子?
如何在聚宽中构建结合 PEG、净利率和成长能力的多因子选股策略,并验证因子在不同年份的稳定性?

解决方案

在量化投资中,将盈利能力(如净利率)与成长能力(如 PEG、营收增长率)相结合,是构建高胜率基本面选股策略的经典方法。聚宽(JoinQuant)平台提供了丰富的财务因子库与因子分析工具,能够帮助我们高效实现这一策略。

以下是在聚宽中构建该多因子选股策略并验证其稳定性的完整指南:

一、 核心因子定义与获取

在聚宽因子库中,我们可以直接获取或计算以下核心因子:

  1. PEG(市盈率相对盈利增长比率):代码为 PEG。计算公式为 PE / (归母净利润(TTM)增长率 * 100)。PEG 越低,代表成长性性价比越高。
  2. 净利率(销售净利率):代码为 net_profit_ratio。计算公式为 净利润(TTM)/ 营业收入(TTM)。反映公司的盈利质量。
  3. 营业收入增长率:代码为 operating_revenue_growth_rate。反映公司的规模扩张速度。

二、 聚宽多因子选股策略构建(Python 源码)

以下是一个在聚宽回测环境中运行的简单多因子选股策略示例。策略逻辑:每月初获取沪深300成分股的因子数据,剔除停牌股,筛选出高净利率、高营收增长且低 PEG的股票进行等权重调仓。

import pandas as pd
from jqdata import *
from jqfactor import get_factor_values

def initialize(context):
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    # 设定交易税费
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    # 每月第一个交易日开盘运行调仓
    run_monthly(handle_rebalance, monthday=1, time='09:30')

def handle_rebalance(context):
    # 获取沪深300成分股
    stocks = get_index_stocks('000300.XSHG')
    current_date = context.current_dt.date()
    
    # 过滤停牌与ST股
    current_data = get_current_data()
    stocks = [s for s in stocks if not current_data[s].paused and not current_data[s].is_st]
    
    # 获取因子值
    factors = ['PEG', 'net_profit_ratio', 'operating_revenue_growth_rate']
    factor_data = get_factor_values(securities=stocks, factors=factors, end_date=current_date, count=1)
    
    # 提取当日因子值 DataFrame
    df = pd.DataFrame(index=stocks)
    for f in factors:
        df[f] = factor_data[f].iloc[-1]
        
    # 因子清洗:剔除空值,且 PEG 必须大于 0(避免负增长导致的负PEG误判)
    df = df.dropna()
    df = df[df['PEG'] > 0]
    
    # 因子打分/筛选法:
    # 1. 筛选出净利率在前 50% 的股票
    df = df[df['net_profit_ratio'] >= df['net_profit_ratio'].median()]
    # 2. 筛选出营收增长率在前 50% 的股票
    df = df[df['operating_revenue_growth_rate'] >= df['operating_revenue_growth_rate'].median()]
    # 3. 在通过上述筛选的股票中,选择 PEG 最低的前 10 只股票
    target_stocks = df.sort_values(by='PEG', ascending=True).head(10).index.tolist()
    
    # 执行调仓
    # 卖出不在目标持仓中的股票
    for stock in list(context.portfolio.positions.keys()):
        if stock not in target_stocks:
            order_target(stock, 0)
            
    # 等权重买入目标股票
    if target_stocks:
        position_value = context.portfolio.total_value / len(target_stocks)
        for stock in target_stocks:
            order_target_value(stock, position_value)

三、 如何验证因子在不同年份的稳定性?

为了确保策略不是“历史拟合”,必须验证因子在不同年份(不同市场牛熊周期)下的表现。在聚宽研究模块中,可以使用 analyze_factor 工具进行单因子及多因子分析:

1. 滚动区间 IC(信息系数)分析

IC 值代表因子值与未来收益率的相关性。通过计算不同年份的月度 IC 均值和 IR(信息比率),可以评估因子的预测能力是否稳定。

from jqfactor import analyze_factor

# 验证 2018 年(熊市)与 2020 年(牛市)因子的 IC 稳定性
for year in ['2018', '2020']:
    start = f'{year}-01-01'
    end = f'{year}-12-31'
    
    # 分析 PEG 因子
    far = analyze_factor(
        factor='PEG', 
        start_date=start, 
        end_date=end, 
        universe='000300.XSHG', 
        quantiles=5, 
        periods=(1, 5, 20)
    )
    
    print(f"{year} 年月度 IC 均值:")
    print(far.ic_monthly.mean())

2. 分位数收益单调性检验

一个稳定的因子应该满足分位数收益单调性。例如,将股票按 PEG 从小到大分成 5 组(Quantiles=5),第一组(低 PEG)的年化收益在不同年份都应该显著高于第五组(高 PEG)。

  • 使用 far.plot_quantile_returns_bar() 绘制各分位数平均收益图。
  • 使用 far.plot_cumulative_returns_by_quantile() 观察不同年份下,多头组合(低 PEG)与空头组合(高 PEG)的净值走势是否持续分化。

3. 行业中性化与市值中性化

盈利和成长因子容易受到行业和市值的干扰(例如,科技股普遍高成长高 PEG,银行股低成长低 PEG)。在分析前,建议使用聚宽的 neutralize 函数对因子进行行业和市值中性化,以确保因子的超额收益不是来自于单纯的“超配某行业”或“偏好小盘股”。