问题描述
解决方案
在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股票。
策略代码示例
下面的代码展示了两种方式:
- 方式一:获取具体的退市日期并打印。
- 方式二:直接过滤掉退市股票(实盘常用)。
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)
关键点总结
- 未退市标识:PTrade 系统中,未退市股票的
de_listed_date字段值为'2900-01-01'。 - 日期比较:如果获取到的日期不是
'2900-01-01',则需要将其与当前回测/交易日期进行比较,以确定是否已经发生退市。 - 便捷过滤:在
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_status 和 get_stock_info 有什么区别?
A: get_stock_info 返回具体的基础信息(如上市日期、退市日期、股票名称);而 get_stock_status 返回布尔值状态(如是否ST、是否停牌、是否退市),用于快速逻辑判断,不返回具体日期。