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

为什么在 JoinQuant 中使用 calc_factors 获取的 book_to_price_ratio 是负数?

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

问题描述

calc_factors 600519 数据问题?

# 导入函数库
from jqfactor import Factor, calc_factors

class BookToPriceRatio(Factor):
name = 'book_to_price_ratio'
max_window = 1
dependencies = ['book_to_price_ratio']
def calc(self, data):
return data['book_to_price_ratio'].iloc[0]

# 定义股票池
securities = ['600519.XSHG']
# 计算因子值
factors = calc_factors(securities, [BookToPriceRatio()], start_date='2017-01-01', end_date='2017-03-01', use_real_price=False, skip_paused=False)

# 查看因子值
factors['book_to_price_ratio'].head()
600519.XSHG
2017-01-03 -1.572684
2017-01-04 -1.602377
2017-01-05 -1.593870
2017-01-06 -1.621405
2017-01-09 -1.610634

book_to_price_ratio怎么是负的?

解决方案

您好!您在使用 calc_factors 获取 book_to_price_ratio(账面市值比)时发现贵州茅台(600519.XSHG)的数据为负数,这是因为聚宽因子库中的风格因子(Style Factors)在底层已经经过了标准化(Z-score)处理

原因解析

根据 JoinQuant API 文档中关于风格因子数据处理说明的规定,系统会对风格因子(如 book_to_price_ratiosizemomentum 等)进行以下正规化处理:

  1. 去极值:将2.5倍标准差之外的值,赋值成2.5倍标准差的边界值。
  2. 标准化:采用市值加权标准化,公式为:
    $$x = \frac{x - mean(x)}{std(x)}$$

为什么茅台是负数?
book_to_price_ratio(账面市值比)是市净率(PB)的倒数。贵州茅台(600519)作为典型的高估值、高股价白马股,其市净率(PB)远高于市场平均水平,因此其账面市值比(1/PB)远低于市场平均水平。在经过上述 $x = (x - mean) / std$ 的标准化处理后,低于均值的数据就会呈现为负数。这代表该股票的账面市值比在全市场中处于较低的分位数位置。

解决方案

如果您希望获取原始的、未经过标准化的账面市值比或市净率数据,建议不要直接使用风格因子库中的 book_to_price_ratio,而是通过财务数据 API get_fundamentals 来获取市净率(pb_ratio),然后自行取倒数。

获取原始 PB 数据的代码示例:

from jqdata import *

# 查询 600519 在指定日期的市净率 (PB)
q = query(valuation.code, valuation.pb_ratio).filter(valuation.code == '600519.XSHG')
df = get_fundamentals(q, date='2017-01-03')

# 计算原始的账面市值比 (1 / PB)
if not df.empty:
    raw_book_to_price = 1 / df['pb_ratio'][0]
    print("原始账面市值比:", raw_book_to_price)

总结来说,您代码中获取的负值是正确的标准化因子暴露度(Factor Exposure),常用于多因子模型的回归和打分;如果用于基本面绝对值分析,请改用 get_fundamentals 获取原始财务指标。