🚀 AI 一键生成 ptrade 策略代码

PTrade 财务因子:如何获取动态市盈率 (PE-TTM) 与静态市盈率?

ptrade | 发布时间: 2025/12/24
以下内容由 EasyQuant 生成。

问题描述

如何获取股票的动态市盈率(PE-TTM)和静态市盈率?

解决方案

在PTrade中,获取股票的市盈率数据(包括PE-TTM、静态市盈率和动态市盈率)需要使用 get_fundamentals 函数,并查询 valuation(估值数据)表。

核心字段说明

根据PTrade的API文档,valuation 表中对应的字段如下:

  • pe_ttm: 市盈率PE(TTM),即滚动市盈率(过去12个月)。
  • pe_static: 静态市盈率(基于最近一期年报)。
  • pe_dynamic: 动态市盈率(通常指基于当前季度数据年化后的市盈率)。

代码实现

以下是一个完整的策略示例,展示如何在 before_trading_start 函数中获取指定股票的这三种市盈率数据并打印到日志中。

def initialize(context):
    # 初始化股票池,这里以恒生电子(600570.SS)为例
    g.security = ['600570.SS']
    set_universe(g.security)

def before_trading_start(context, data):
    # 设定要查询的字段
    # pe_ttm: 市盈率(TTM)
    # pe_static: 静态市盈率
    # pe_dynamic: 动态市盈率
    fields = ['pe_ttm', 'pe_static', 'pe_dynamic', 'secu_name']
    
    # 调用 get_fundamentals 获取估值数据
    # 注意:在回测中,如果不传 date 参数,默认获取的是 context.blotter.current_dt (当日) 的数据。
    # 为了避免“未来函数”(即在开盘前获取到了收盘后才更新的当日估值),建议在回测中传入前一个交易日的日期,
    # 或者在 handle_data/after_trading_end 中获取当日数据。
    # 此处演示直接获取,PTrade回测引擎通常会处理为获取截止到前一日的数据以防作弊,但具体依赖券商版本配置。
    
    df = get_fundamentals(g.security, 'valuation', fields)
    
    if df is not None and not df.empty:
        log.info("获取到的市盈率数据如下:")
        log.info(df)
        
        # 演示如何提取具体数值 (假设只取第一只股票)
        stock_code = g.security[0]
        if stock_code in df.index:
            pe_ttm = df.loc[stock_code, 'pe_ttm']
            pe_static = df.loc[stock_code, 'pe_static']
            log.info("股票 %s 的 PE-TTM: %s, 静态PE: %s" % (stock_code, pe_ttm, pe_static))
    else:
        log.info("未获取到数据")

def handle_data(context, data):
    pass

注意事项

  1. 数据表来源:必须指定表名为 'valuation'
  2. 查询模式valuation 表只支持按天查询模式(即指定 date 或默认当前日期),不支持 start_year/end_year 的年份查询模式。
  3. 未来函数风险:在回测模式下,如果在 before_trading_start(盘前)不指定日期直接调用,系统可能会返回当日收盘后才结算出的市值和PE数据。为了严谨的回测,建议明确传入上一交易日的日期,或者知悉这一点仅作参考。
  4. 停牌处理:如果股票停牌,其市盈率数据通常会维持在停牌前的值。

Q&A

Q: pe_dynamicpe_ttm 有什么区别?
A: pe_ttm (Trailing Twelve Months) 是滚动市盈率,使用过去4个季度的净利润总和计算,更能反映近期业绩。pe_dynamic 在PTrade中通常指动态市盈率,一般是根据最近一期财报(如一季报)的净利润乘以4(或相应倍数)来预估全年的净利润进行计算,波动性可能较大。

Q: 为什么获取到的数据是 NaN
A: 可能原因包括:

  1. 该股票在查询日期停牌或未上市。
  2. 该股票业绩亏损(部分算法在亏损时返回负值,部分返回NaN,具体视数据源而定)。
  3. 查询日期是非交易日。

Q: 如何获取全市场股票的PE-TTM?
A: 可以先使用 get_Ashares() 获取全市场代码列表,然后将其作为 security 参数传入 get_fundamentals。但请注意,一次性查询几千只股票可能会导致超时或被限流,建议分批查询(例如每次500只)。