问题描述
解决方案
在PTrade中,最快速且推荐的方法是使用内置函数 filter_stock_by_status。该函数专门用于根据指定的状态(如ST、停牌、退市)来过滤股票列表。
以下是具体的实现方法和代码示例:
方法一:使用 filter_stock_by_status (推荐)
这是最简洁的方法,一行代码即可完成过滤。
def initialize(context):
# 假设这是你的初始股票池
g.security = ['600570.SS', '000001.SZ', '600000.SS']
set_universe(g.security)
def before_trading_start(context, data):
# 使用 filter_stock_by_status 过滤股票
# filter_type 参数指定要剔除的类型:
# 'ST': 剔除ST股票
# 'HALT': 剔除停牌股票
# 'DELISTING': 剔除退市股票
clean_stock_list = filter_stock_by_status(g.security, filter_type=['ST', 'HALT'])
# 打印过滤后的股票列表
log.info("过滤后的股票列表: %s" % clean_stock_list)
# 更新当天的股票池(可选,视策略逻辑而定)
# set_universe(clean_stock_list)
def handle_data(context, data):
pass
方法二:使用 get_stock_status (手动过滤)
如果你需要更复杂的逻辑(例如只想知道哪些是ST,但不一定剔除,或者需要分别处理),可以使用 get_stock_status 获取状态字典后自行筛选。
def initialize(context):
g.security = ['600570.SS', '000001.SZ', '600000.SS']
set_universe(g.security)
def before_trading_start(context, data):
stock_list = g.security
target_list = []
# 获取ST状态字典,Key为股票代码,Value为True(是ST)或False(非ST)
st_status = get_stock_status(stock_list, query_type='ST')
# 获取停牌状态字典
halt_status = get_stock_status(stock_list, query_type='HALT')
for stock in stock_list:
# 如果既不是ST,也没有停牌,则保留
# 注意:get_stock_status返回None表示查询失败,通常视为不满足条件或需特殊处理,这里假设返回True/False
is_st = st_status.get(stock, False)
is_halt = halt_status.get(stock, False)
if not is_st and not is_halt:
target_list.append(stock)
log.info("手动过滤后的股票列表: %s" % target_list)
def handle_data(context, data):
pass
核心API说明
-
filter_stock_by_status(stocks, filter_type=["ST", "HALT", "DELISTING"], query_date=None)- stocks: 股票代码列表。
- filter_type: 需要剔除的类型列表。默认包含ST、停牌和退市。如果只想剔除ST和停牌,传入
['ST', 'HALT']即可。 - query_date: 查询日期,回测中默认取当前回测日期,实盘取当日。
-
get_stock_status(stocks, query_type='ST', query_date=None)- query_type: 支持
'ST'(是否ST),'HALT'(是否停牌),'DELISTING'(是否退市)。 - 返回值: 返回一个字典,键为股票代码,值为布尔值(True表示符合该状态,例如是ST股)。
- query_type: 支持
建议
在实盘或回测中,建议将此逻辑放在 before_trading_start 函数中执行。因为停牌和ST状态通常在开盘前就已经确定,盘前处理可以避免盘中下单失败。
Q&A
Q: filter_stock_by_status 会剔除退市整理期的股票吗?
A: 默认的 filter_type 包含 'DELISTING',这通常指已退市。如果需要过滤退市整理期的股票,可以在 filter_type 中加入 'DELISTING_SORTING'(注意:该参数通常只过滤交易当日数据)。
Q: 如果我在回测中不剔除停牌股票会怎样?
A: 在PTrade回测中,如果对停牌股票下单(order系列函数),系统会产生废单,并在日志中提示委托失败。虽然不会导致策略崩溃,但会占用资金计算逻辑或导致持仓与预期不符,因此建议剔除。
Q: get_stock_status 返回 None 是什么意思?
A: 如果输入了不存在的股票代码或数据查询异常,对应的值可能为 None。在编写手动过滤逻辑时,建议使用 dict.get(key, False) 的方式来防止代码报错。