🚀 AI 一键生成 ptrade 策略代码

PTrade 策略风控:利用 get_stock_info 查询股票退市日期 (de_listed_date)

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

问题描述

如何查询股票的退市日期以避免交易已退市的标的?

解决方案

在PTrade中,查询股票退市日期主要使用 get_stock_info 接口。为了避免交易已退市的标的,您既可以通过获取具体日期进行判断,也可以直接使用 filter_stock_by_status 接口进行批量过滤。

以下是详细的解决方案和代码示例。

核心方法:使用 get_stock_info

该接口可以获取股票的基础信息,通过指定 field=['de_listed_date'] 可以获取退市日期。

  • 接口: get_stock_info(stocks, field=['de_listed_date'])
  • 返回值: 返回一个字典。如果股票未退市de_listed_date 通常返回 '2900-01-01';如果已退市,则返回具体的退市日期字符串(格式通常为 'YYYY-MM-DD')。

辅助方法:使用 filter_stock_by_status (推荐)

如果您仅仅是为了避免交易已退市股票,而不是必须知道具体日期,使用 filter_stock_by_status 是最高效的方法。它可以直接从股票池中剔除退市(DELISTING)、停牌(HALT)或ST股票。


策略代码示例

下面的代码展示了两种方式:

  1. 方式一:获取具体的退市日期并打印。
  2. 方式二:直接过滤掉退市股票(实盘常用)。
def initialize(context):
    # 初始化一个包含正常股票和可能已退市股票的列表用于测试
    # 注意:实际回测中,如果股票在当前日期已退市,set_universe可能无法将其加入,
    # 但在研究模式或处理历史数据列表时,此逻辑非常有用。
    g.security_list = ['600570.SS', '000001.SZ'] 
    set_universe(g.security_list)

def before_trading_start(context, data):
    log.info("=== 开始检查退市状态 ===")
    
    # --- 方式一:查询具体退市日期 ---
    # 获取股票的退市日期信息
    info_dict = get_stock_info(g.security_list, field=['stock_name', 'de_listed_date'])
    
    valid_stocks_by_date = []
    
    for stock in g.security_list:
        if stock in info_dict:
            stock_name = info_dict[stock]['stock_name']
            delist_date = info_dict[stock]['de_listed_date']
            
            # 判断逻辑:如果日期是 2900-01-01,说明未退市
            if delist_date == '2900-01-01':
                log.info("股票 %s (%s) 状态正常,退市日期显示为: %s" % (stock, stock_name, delist_date))
                valid_stocks_by_date.append(stock)
            else:
                # 比较当前日期和退市日期
                # 注意:context.blotter.current_dt 是 datetime 对象,delist_date 是字符串
                current_date_str = context.blotter.current_dt.strftime('%Y-%m-%d')
                
                if current_date_str >= delist_date:
                    log.info("警告:股票 %s (%s) 已于 %s 退市,剔除。" % (stock, stock_name, delist_date))
                else:
                    log.info("股票 %s (%s) 将于 %s 退市,目前仍在上市中。" % (stock, stock_name, delist_date))
                    valid_stocks_by_date.append(stock)
    
    log.info("通过日期判断保留的股票: %s" % valid_stocks_by_date)

    # --- 方式二:使用内置函数直接过滤 (推荐用于交易) ---
    # filter_stock_by_status 可以直接过滤 ST, HALT(停牌), DELISTING(退市)
    # 这里演示只过滤 DELISTING (退市)
    filtered_list = filter_stock_by_status(g.security_list, filter_type=['DELISTING'])
    
    log.info("通过 filter_stock_by_status 过滤后的股票: %s" % filtered_list)
    
    # 更新当天的股票池
    set_universe(filtered_list)

def handle_data(context, data):
    # 这里的 universe 已经是过滤后的安全列表
    for stock in context.universe:
        # 简单的买入逻辑示例
        order(stock, 100)

关键点总结

  1. 未退市标识:PTrade 系统中,未退市股票的 de_listed_date 字段值为 '2900-01-01'
  2. 日期比较:如果获取到的日期不是 '2900-01-01',则需要将其与当前回测/交易日期进行比较,以确定是否已经发生退市。
  3. 便捷过滤:在 before_trading_start 中调用 filter_stock_by_status(stocks, filter_type=['DELISTING']) 是最简单且不易出错的方法,它会自动处理退市状态的判断。

Q&A

Q: get_stock_info 如果不传 field 参数会返回什么?
A: 如果不传 field 参数,默认只返回 stock_name(股票名称)。要获取退市日期,必须显式指定 field=['de_listed_date'] 或包含该字段的列表。

Q: filter_stock_by_status 能过滤处于“退市整理期”的股票吗?
A: 可以。该函数支持 filter_type=['DELISTING_SORTING'] 参数,专门用于查询和过滤处于退市整理期的股票(注意:此选项通常只过滤交易当日的数据)。

Q: 为什么查询到的退市日期是 "2900-01-01"?
A: 这是 PTrade 系统的默认占位符,表示该股票当前处于正常上市状态,没有确定的退市日期。

Q: get_stock_statusget_stock_info 有什么区别?
A: get_stock_info 返回具体的基础信息(如上市日期、退市日期、股票名称);而 get_stock_status 返回布尔值状态(如是否ST、是否停牌、是否退市),用于快速逻辑判断,不返回具体日期。