问题描述
成长因子包含了三个参考变量:
主营业务收入增长率
净利润增长率
内部增长率
价值因子包含了四个参考变量:
股息收益率(D/P)
每股净资产与价格比率(B/P)
每股净现金流与价格比率(CF/P)
每股收益与价格比率(E/P)
成长因子和价值因子的变量具体数值还没找到,谁有回测过的?
解决方案
在 JoinQuant (聚宽) 平台上,您提到的成长因子和价值因子都可以通过平台内置的财务数据 API (get_fundamentals) 或 因子库 API (get_factor_values) 直接获取。下面为您详细梳理这些变量在聚宽中的对应字段,并提供一个结合成长与价值因子的回测策略示例。
一、 变量在 JoinQuant 中的对应字段
1. 成长因子 (Growth Factors)
可以通过聚宽因子库 (jqfactor) 直接获取:
- 主营业务收入增长率:对应因子库中的
operating_revenue_growth_rate(营业收入增长率)。 - 净利润增长率:对应因子库中的
net_profit_growth_rate(净利润增长率)。 - 内部增长率:聚宽基础因子中没有直接叫“内部增长率”的字段,但可以通过
ROE * 留存收益率计算,或者使用相近的total_asset_growth_rate(总资产增长率) 或np_parent_company_owners_growth_rate(归属母公司股东的净利润增长率) 替代。
2. 价值因子 (Value Factors)
价值因子通常是估值指标的倒数,可以通过因子库或财务估值表 (valuation) 获取:
- 股息收益率 (D/P):对应因子库中的
divyild(分红因子) 或财务数据中的股息率。 - 每股净资产与价格比率 (B/P):对应因子库中的
book_to_price_ratio(账面市值比),或者使用1 / valuation.pb_ratio(市净率的倒数)。 - 每股净现金流与价格比率 (CF/P):对应因子库中的
cash_flow_to_price_ratio(现金流市值比),或者使用1 / valuation.pcf_ratio(市现率的倒数)。 - 每股收益与价格比率 (E/P):对应因子库中的
earnings_yield(盈利预期因子),或者使用1 / valuation.pe_ratio(市盈率的倒数)。
二、 如何获取这些因子的具体数值?
您可以在聚宽的研究环境中使用 get_factor_values 快速拉取这些数值进行分析:
from jqfactor import get_factor_values
from jqdata import get_index_stocks
# 获取沪深300成分股
stocks = get_index_stocks('000300.XSHG')
# 定义需要获取的因子列表
factor_list = [
'operating_revenue_growth_rate', # 营收增长率
'net_profit_growth_rate', # 净利润增长率
'book_to_price_ratio', # B/P
'earnings_yield' # E/P
]
# 获取 2023-01-01 的因子数据
factor_data = get_factor_values(securities=stocks, factors=factor_list, end_date='2023-01-01', count=1)
# 查看 B/P 因子数值
print(factor_data['book_to_price_ratio'])
三、 成长+价值双因子选股回测示例
下面是一个简单的回测策略框架:每月初调仓,选取沪深300中,市盈率大于0且E/P最高(低估值),同时净利润增长率最高(高成长)的前10只股票进行等权重买入。
# 导入聚宽函数库
import jqdata
from jqfactor import get_factor_values
import pandas as pd
def initialize(context):
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 过滤掉order系列API产生的比error级别低的log
log.set_level('order', 'error')
# 设置交易手续费
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
# 每月第一个交易日运行调仓函数
run_monthly(trade, monthday=1, time='09:30')
def trade(context):
# 1. 获取沪深300成分股作为股票池
stocks = get_index_stocks('000300.XSHG', date=context.current_dt)
# 2. 获取前一交易日的因子数据
# earnings_yield (E/P), net_profit_growth_rate (净利润增长率)
factors = ['earnings_yield', 'net_profit_growth_rate']
factor_data = get_factor_values(securities=stocks, factors=factors, end_date=context.previous_date, count=1)
# 3. 数据处理与打分
# 提取截面数据并转置为 DataFrame
df_ep = factor_data['earnings_yield'].iloc[0]
df_growth = factor_data['net_profit_growth_rate'].iloc[0]
df = pd.DataFrame({'EP': df_ep, 'Growth': df_growth})
# 剔除缺失值和 E/P < 0 (亏损) 的股票
df = df.dropna()
df = df[df['EP'] > 0]
# 对因子进行排序打分 (数值越大,排名越靠前,得分越高)
df['EP_Rank'] = df['EP'].rank(ascending=True)
df['Growth_Rank'] = df['Growth'].rank(ascending=True)
# 计算总分 (等权相加)
df['Total_Score'] = df['EP_Rank'] + df['Growth_Rank']
# 按总分降序排列,选取前 10 只股票
target_list = df.sort_values(by='Total_Score', ascending=False).head(10).index.tolist()
# 4. 执行调仓
# 卖出不在目标列表中的持仓
for security in list(context.portfolio.positions.keys()):
if security not in target_list:
order_target(security, 0)
# 等权重买入目标股票
if len(target_list) > 0:
weight = 1.0 / len(target_list)
target_value = context.portfolio.total_value * weight
for security in target_list:
order_target_value(security, target_value)
总结建议
- 因子正交化与去极值:在实际的量化回测中,直接使用原始因子值可能会受到极端值的影响。建议使用聚宽提供的
winsorize(去极值) 和standardlize(标准化) 函数对截面数据进行预处理。 - 财务数据滞后性:使用
get_factor_values获取的财务衍生因子已经处理了财报披露的滞后性(即避免了未来函数),您可以放心在回测中使用。