🚀 AI 一键生成 joinquant 策略代码

解决 JoinQuant 中 get_valuation 获取 ETF 估值数据为空的问题

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

问题描述

为什么get_valuation总取不到PE数据?

from jqdata import *

获取当前ETF的估值PE_TTM(前3个交易日,取平均)
df1 = get_valuation('510050.XSHG', end_date=context.previous_date, count=3, fields=['pe_ratio'])
print(df1)
PE_TTM = mean(df1['pe_ratio'])

但总是显示:
INFO - Empty DataFrame

日期,我也调整了最近的时间,但还是这样的,为什么呢?是否这个API不提供估值PE_TTM的数据?!

解决方案

您好!您在使用 get_valuation 获取 ETF(如 510050.XSHG)的 PE 数据时返回 Empty DataFrame,是因为 get_valuation API 仅支持获取上市股票的市值和估值数据,不支持直接获取 ETF 基金或指数的估值数据。

为什么不支持?

pe_ratio(市盈率)等财务估值指标是基于上市公司的财务报表(如净利润)计算得出的。ETF 作为一种基金,本身并不直接产生营业收入和净利润,它的估值本质上是其底层跟踪的指数(如上证50指数 000016.XSHG)成分股的整体估值。

如何正确获取 ETF/指数的 PE_TTM?

如果您需要获取 ETF 的估值,通常的做法是计算该 ETF 所跟踪指数的成分股加权 PE。指数 PE 的经典计算公式为:指数 PE = 成分股总市值 / 成分股总净利润

以下是为您编写的在 JoinQuant 中计算特定指数(如上证50)PE_TTM 的替代代码方案:

from jqdata import *
import pandas as pd

def get_index_pe_ttm(index_code, date):
    """
    计算指定指数在指定日期的 PE_TTM
    :param index_code: 指数代码,例如上证50为 '000016.XSHG'
    :param date: 查询日期
    :return: 指数的 PE_TTM
    """
    # 1. 获取指数成分股
    stocks = get_index_stocks(index_code, date)
    if not stocks:
        return None
        
    # 2. 查询成分股的市值 (market_cap) 和 市盈率 (pe_ratio)
    q = query(
        valuation.code, 
        valuation.market_cap, 
        valuation.pe_ratio
    ).filter(
        valuation.code.in_(stocks)
    )
    df = get_fundamentals(q, date=date)
    
    if df.empty:
        return None
        
    # 3. 剔除 PE 为负或为空的异常数据(亏损企业通常不计入或特殊处理,这里做简单剔除)
    df = df[df['pe_ratio'] > 0]
    
    # 4. 计算隐含的净利润:净利润 = 市值 / PE
    df['earnings'] = df['market_cap'] / df['pe_ratio']
    
    # 5. 计算指数整体 PE:总市值 / 总净利润
    total_market_cap = df['market_cap'].sum()
    total_earnings = df['earnings'].sum()
    
    if total_earnings > 0:
        index_pe = total_market_cap / total_earnings
        return index_pe
    else:
        return None

# --- 在策略中的使用示例 ---
def initialize(context):
    run_daily(market_open, time='09:30')

def market_open(context):
    # 510050.XSHG 跟踪的是上证50指数 (000016.XSHG)
    index_code = '000016.XSHG'
    
    # 获取前一个交易日的 PE_TTM
    pe_ttm = get_index_pe_ttm(index_code, context.previous_date)
    
    log.info(f"上证50指数在 {context.previous_date} 的 PE_TTM 为: {pe_ttm:.2f}")

总结

  1. 不要将 ETF 代码(如 510050.XSHG)传入 get_valuationget_fundamentals
  2. 找到 ETF 对应的底层指数代码(如上证50为 000016.XSHG)。
  3. 通过提取指数成分股的市值和 PE,自行汇总计算出指数级别的 PE_TTM。