问题描述
df1 = get_fundamentals(query(
valuation.code, valuation.market_cap, valuation.pe_ratio, income.total_operating_revenue
).filter(
valuation.market_cap < 30, # 总市值小于1000亿元
valuation.pe_ratio < 15, # 市盈率小于10
valuation.pe_ratio > 0,
income.total_operating_revenue > 1e1 #营业总收入大于1百万元
).order_by(
valuation.market_cap.desc() # 按市值降序排列
).limit(9900) # 最多返回100个
,date='2020-12-22')
print(df1)
解决方案
您好!聚宽的 pe_ratio 数据本身通常是没有错误的。您觉得数据看起来不对,很可能是因为财务数据表中的字段单位理解有误。
根据您提供的代码,主要存在以下几个单位和逻辑上的问题:
1. 营业总收入的单位是“元”
在聚宽的财务数据中,income.total_operating_revenue(营业总收入)的单位是元。您在代码中写了 income.total_operating_revenue > 1e1,注释里写的是“大于1百万元”。
1e1在 Python 中等于 10,这意味着您筛选的是营业收入大于 10 元的股票,这几乎包含了所有股票。- 如果您想筛选大于 1 百万元,应该写成
1e6(即 1,000,000 元)。
2. 总市值的单位是“亿元”
在聚宽的市值表(valuation)中,market_cap(总市值)的单位是亿元。
- 您代码中写了
valuation.market_cap < 30,这意味着筛选的是总市值小于 30 亿元 的股票,而不是注释里写的“小于1000亿元”。 - 如果您想筛选小于 1000 亿元,应该写成
valuation.market_cap < 1000。
3. 市盈率 (pe_ratio) 的定义
聚宽市值表中的 valuation.pe_ratio 默认指的是 市盈率(PE, TTM),即滚动市盈率(按过去12个月的净利润计算)。如果您想查询静态市盈率(LYR),应该使用 valuation.pe_ratio_lyr。
修正后的代码示例
如果您真实的意图是:总市值小于30亿元,市盈率在0到15之间,且营业总收入大于1百万元,正确的代码应该如下:
from jqdata import *
# 查询2020-12-22的财务数据
df1 = get_fundamentals(query(
valuation.code,
valuation.market_cap,
valuation.pe_ratio,
income.total_operating_revenue
).filter(
valuation.market_cap < 30, # 总市值小于30亿元 (单位: 亿元)
valuation.pe_ratio < 15, # 市盈率小于15
valuation.pe_ratio > 0, # 市盈率大于0 (剔除亏损股)
income.total_operating_revenue > 1e6 # 营业总收入大于1百万元 (单位: 元,1e6 = 100万)
).order_by(
valuation.market_cap.desc() # 按市值降序排列
).limit(9900), # 限制返回条数
date='2020-12-22')
print(df1)
总结避坑指南
在使用聚宽 get_fundamentals 查询财务数据时,务必查阅官方 API 文档中的数据字典,特别注意以下常用字段的单位:
- 市值类 (
valuation):market_cap(总市值)、circulating_market_cap(流通市值) 的单位都是 亿元。 - 三大财务报表 (
income,balance,cash_flow):绝大多数金额字段(如营业收入、净利润、总资产等)的单位都是 元。
调整单位后,您查询出的数据应该就符合您的预期了。