问题描述
根据因子库的定义:
账面市值比因子 book_to_price_ratio
定义:book_to_price_ratio
解释:最新一季财报的账面价值与当前市值的比值(pb_ratio的倒数)。其中小于0的值设置为nan。
但是在研究环境中,用以下代码,获得300750.XSHE(宁德时代)的book_to_price_ratio却是负值,不知道哪位大佬可以指点一下。宁德时代市净率(pb_ratio大致为5.2)的倒数肯定应该是大于0的呀。
factor_data = get_factor_values(securities=['300750.XSHE'], factors=['book_to_price_ratio'], start_date='2023-06-01', end_date='2023-06-30')
print(factor_data)
输出:
{'book_to_price_ratio': code 300750.XSHE
2023-06-01 -1.230042
2023-06-02 -1.239169
2023-06-05 -1.222466
2023-06-06 -1.233899
2023-06-07 -1.205004
2023-06-08 -1.217421
2023-06-09 -1.215547
2023-06-12 -1.213620
2023-06-13 -1.206020
2023-06-14 -1.197089
2023-06-15 -1.230272
2023-06-16 -1.216936
2023-06-19 -1.194147
2023-06-20 -1.185258
2023-06-21 -1.201105
2023-06-26 -1.213196
2023-06-27 -1.211824
2023-06-28 -1.220011
2023-06-29 -1.210580
2023-06-30 -1.224714}
解决方案
您好!您遇到的这个问题是因为通过 get_factor_values 获取到的风格因子值,并不是原始的计算比值,而是经过了去极值、标准化等数据处理后的“因子暴露度”(Z-score)。
详细原因解析:
根据 JoinQuant API 文档中关于**【风格因子数据处理说明】**的描述,平台对风格因子(如 book_to_price_ratio、size、momentum 等)进行了正规化处理,主要步骤包括:
- 去极值:将异常大的或异常小的值限制在一定范围内。
- 标准化(Z-score):公式为
x = (x - mean(x)) / std(x)。其中,均值的计算使用的是股票的市值加权均值。
为什么宁德时代是负数?
book_to_price_ratio的原始值确实是1 / pb_ratio,对于宁德时代来说,这个原始值肯定是大于 0 的。- 但是,宁德时代作为典型的高成长股,其市净率(PB)通常较高(如您所说大致为 5.2),这意味着它的账面市值比(PB的倒数)非常小。
- 当这个非常小的原始值减去全市场的加权平均值
mean(x)时,结果就变成了负数。然后再除以标准差,最终得到的标准化因子值就是一个负数。 - 结论:这里的负数并不代表它的账面价值是负的,而是代表宁德时代的账面市值比低于市场平均水平。
如何获取原始的账面市值比?
如果您在策略中需要使用原始的账面市值比(即纯粹的 1 / pb_ratio),建议您不要直接从因子库获取风格因子,而是通过获取财务估值数据来自己计算:
from jqdata import *
# 获取宁德时代的 PB 数据
q = query(valuation.code, valuation.pb_ratio).filter(valuation.code == '300750.XSHE')
df = get_fundamentals(q, date='2023-06-01')
# 自己计算原始的 book_to_price_ratio
if not df.empty and df['pb_ratio'][0] > 0:
raw_book_to_price = 1.0 / df['pb_ratio'][0]
print(f"原始账面市值比: {raw_book_to_price}")
总结来说,因子库中的 book_to_price_ratio 是用于多因子模型(如 Barra 风险模型)的标准化暴露度,存在负数是正常的统计学处理结果。