🚀 AI 一键生成 ptrade 策略代码

PTrade 交易技巧:利用行情快照计算实时市盈率 (PE)

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

问题描述

盘中怎么计算实时的动态市盈率?

解决方案

在PTrade中,get_fundamentals 函数获取的估值数据(如市盈率)通常是基于前一个交易日收盘价计算的静态数据,盘中不会实时更新。

要在盘中计算实时的动态市盈率,我们需要利用“昨收动态市盈率”和“实时股价涨跌幅”进行推算。

计算逻辑

由于当天的每股收益(EPS)在盘中是固定的(除非当天发布财报,但通常财报在盘后发布),动态市盈率的变化仅由股价变化引起。

公式如下:
$$ \text{实时动态市盈率} = \text{昨日动态市盈率} \times \frac{\text{当前最新价}}{\text{昨日收盘价}} $$

或者理解为:

  1. 先算出动态EPS:$ \text{动态EPS} = \frac{\text{昨日收盘价}}{\text{昨日动态市盈率}} $
  2. 再算实时PE:$ \text{实时动态市盈率} = \frac{\text{当前最新价}}{\text{动态EPS}} $

策略代码实现

以下是一个完整的策略示例,展示了如何在盘中每隔几秒计算并打印实时的动态市盈率。

def initialize(context):
    # 设置我们要操作的股票,以恒生电子为例
    g.security = '600570.SS'
    set_universe(g.security)
    
    # 设置每3秒运行一次计算函数,模拟盘中实时监控
    run_interval(context, calculate_realtime_pe, seconds=3)

def calculate_realtime_pe(context):
    # 1. 获取基础数据:昨日的动态市盈率 (pe_dynamic)
    # get_fundamentals 默认获取的是最近一个交易日结束后的数据
    # 注意:PTrade文档指出 pe_dynamic 返回类型为 str,需要转换
    q = get_fundamentals(g.security, 'valuation', ['pe_dynamic'])
    
    if q is None or len(q) == 0:
        log.info("未获取到财务数据")
        return

    # 获取昨日动态PE字符串并转为浮点数
    # get_fundamentals 返回的是DataFrame,索引是股票代码
    try:
        pe_dynamic_yesterday = float(q['pe_dynamic'][g.security])
    except:
        log.info("财务数据格式转换失败")
        return

    # 2. 获取实时行情快照
    snapshot = get_snapshot(g.security)
    
    if not snapshot:
        log.info("未获取到行情快照")
        return
        
    # 获取当前最新价 (last_px) 和 昨日收盘价 (preclose_px)
    current_price = snapshot[g.security].get('last_px')
    pre_close = snapshot[g.security].get('preclose_px')
    
    # 数据有效性检查
    if current_price == 0 or pre_close == 0:
        log.info("当前集合竞价或停牌,无有效价格")
        return
        
    # 3. 计算实时动态市盈率
    # 公式:实时PE = 昨日PE * (当前价 / 昨收价)
    realtime_pe = pe_dynamic_yesterday * (current_price / pre_close)
    
    # 4. 打印结果
    log.info("股票: %s" % g.security)
    log.info("昨日收盘价: %.2f, 昨日动态PE: %.2f" % (pre_close, pe_dynamic_yesterday))
    log.info("当前最新价: %.2f" % current_price)
    log.info("实时动态市盈率: %.4f" % realtime_pe)
    log.info("-" * 30)

def handle_data(context, data):
    pass

代码详解

  1. 获取基准PE (get_fundamentals):

    • 我们查询 valuation 表中的 pe_dynamic 字段。
    • 在PTrade中,这个数据通常是基于前一交易日的收盘数据计算好的。
    • 注意类型转换:文档说明该字段返回类型为 str,因此代码中使用 float() 进行了转换。
  2. 获取实时价格 (get_snapshot):

    • 使用 get_snapshot 获取毫秒级的实时行情。
    • 提取 last_px (最新成交价) 和 preclose_px (昨收价)。
  3. 计算逻辑:

    • 利用比例关系:实时PE / 昨日PE = 当前价 / 昨收价
    • 这种方法避免了手动去计算EPS(每股收益)和处理复杂的财报季度年化问题,直接利用了PTrade系统已经计算好的昨日基准数据,计算速度快且准确。

Q&A

Q: 为什么不直接用 get_fundamentals 获取实时的 PE?
A: get_fundamentals 是基于财务报表和日终数据更新的,它不会随着盘中股价的每一笔跳动而更新。如果在盘中调用它,返回的仍然是昨日收盘时的静态市盈率。

Q: 这个计算方法适用于 pe_ttm (滚动市盈率) 吗?
A: 适用。如果你想计算实时的 TTM 市盈率,只需将代码中的 pe_dynamic 替换为 pe_ttm 即可,计算逻辑完全一致。

Q: 如果股票停牌了怎么办?
A: 如果股票停牌,get_snapshot 返回的 last_px 通常为 0 或者等于 preclose_px(取决于停牌类型和时间),且成交量为0。代码中加入了 if current_price == 0 的判断来防止数据异常。