🚀 AI 一键生成 ptrade 策略代码

如何使用 PTrade API 获取全市场实时可转债列表并筛选可交易品种?

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

问题描述

我想获取市场上所有可转债的代码,并且只对其中没有停牌的进行操作,应该怎么做?

解决方案

在PTrade中,要获取市场上所有可转债代码并过滤掉停牌的标的,主要需要结合使用以下两个接口:

  1. get_cb_list():用于获取当前市场上所有的可转债代码(包含停牌的)。
  2. get_snapshot(security_list):用于获取标的的实时行情快照,其中包含 trade_status(交易状态)字段,通过该字段可以判断是否停牌。

实现逻辑

  1. initialize 中设置定时任务或在 before_trading_start 中执行。
  2. 调用 get_cb_list() 获取全量可转债代码。
  3. 调用 get_snapshot() 获取这些代码的状态。
  4. 遍历快照数据,剔除状态为 HALT (暂停交易)、SUSP (停盘)、STOPT (长期停盘) 或 DELISTED (退市) 的代码。

以下是完整的策略代码示例:

def initialize(context):
    # 初始化全局变量
    g.trade_cb_list = []
    
    # 设定每天9:30开盘后执行一次筛选(确保能获取到当天的准确状态)
    # 注意:如果在盘前(before_trading_start)调用get_snapshot,部分状态可能未更新
    run_daily(context, filter_tradable_bonds, time='9:30')

def filter_tradable_bonds(context):
    """
    获取所有可转债并过滤掉停牌标的
    """
    # 1. 获取当前市场所有可转债代码
    all_cb_list = get_cb_list()
    
    if not all_cb_list:
        log.info("未获取到可转债代码列表")
        return

    # 2. 获取行情快照
    # 注意:一次性获取大量标的快照可能会比较慢,实盘中如果数量巨大建议分批获取
    cb_snapshot = get_snapshot(all_cb_list)
    
    # 3. 过滤停牌标的
    # trade_status 状态说明:
    # HALT: 暂停交易, SUSP: 停盘, STOPT: 长期停盘, DELISTED: 退市
    # None: 获取失败或无数据
    tradable_list = []
    
    for code in all_cb_list:
        # 获取单只标的的快照信息,如果获取不到默认为空字典
        info = cb_snapshot.get(code, {})
        status = info.get("trade_status")
        
        # 判断状态是否正常
        if status not in [None, "HALT", "SUSP", "STOPT", "DELISTED"]:
            tradable_list.append(code)
            
    # 更新到全局变量
    g.trade_cb_list = tradable_list
    
    log.info("当前市场可转债总数: %d" % len(all_cb_list))
    log.info("剔除停牌后可交易数量: %d" % len(g.trade_cb_list))
    # 打印前10个可交易代码示例
    log.info("可交易代码示例(前10): %s" % g.trade_cb_list[:10])

def handle_data(context, data):
    # 在这里进行具体的交易逻辑
    # 示例:遍历筛选后的可交易列表
    if g.trade_cb_list:
        # 仅作演示:获取第一个可交易转债的最新价
        first_cb = g.trade_cb_list[0]
        if first_cb in data:
            price = data[first_cb]['close']
            # log.info("%s 当前价格: %s" % (first_cb, price))
    pass

代码关键点说明

  1. get_cb_list()

    • 该函数仅在交易模块可用(回测和实盘)。它返回的是一个包含所有可转债代码的列表,例如 ['110033.SS', '128010.SZ', ...]
  2. get_snapshot()

    • 这是判断停牌最准确的方法。返回的字典中 trade_status 字段代表当前状态。
    • 重要提示:在回测模式下,get_snapshot 可能无法使用或返回模拟数据。如果在回测中需要过滤停牌,通常使用 get_stock_status(stocks, query_type='HALT') 替代,或者利用 get_history 获取数据,如果成交量为0通常意味着停牌。但在实盘交易中,get_snapshot 是标准做法。
  3. 执行时间

    • 代码中使用了 run_daily(..., time='9:30')。这是因为在早盘集合竞价结束进入连续竞价后,交易状态(trade_status)是最准确的。如果在 before_trading_start(通常是9:00前)调用,交易所可能尚未推送当天的停牌信息,导致数据不准。
  4. 状态过滤

    • 代码显式排除了 ['HALT', 'SUSP', 'STOPT', 'DELISTED'] 以及 None。这确保了 g.trade_cb_list 中只包含当前正常交易(如 TRADESTART 状态)的标的。

Q&A

Q1: 为什么不直接在 before_trading_start 里调用 get_snapshot
A1: 在实盘交易中,before_trading_start 通常在 9:00 之前运行。此时交易所可能还没有推送完整的当日停牌信息,或者行情服务尚未连接到实时流,导致 get_snapshot 返回的数据大部分是 0 或状态不准确。建议在 9:15 之后或 9:30 使用 run_daily 调用。

Q2: 回测模式下可以使用 get_snapshot 吗?
A2: 根据 PTrade 文档,get_snapshot 仅在交易模块可用。在回测模式下,建议使用 get_stock_status(code_list, 'HALT') 来判断是否停牌,或者通过 get_history 获取日线数据,判断成交量是否为 0。

Q3: get_cb_list 返回的代码包含退市的转债吗?
A3: get_cb_list 返回的是当前市场上的代码表。如果转债已经完全退市(摘牌),通常不会出现在列表中。但如果处于退市整理期或刚停牌等待退市,可能会出现在列表中,因此必须结合 trade_status 进行过滤。