问题描述
解决方案
在 PTrade 中,确实有一个非常简单且直接的内置函数可以用来过滤 ST 股、停牌股以及退市股票,那就是 filter_stock_by_status。
这个函数通常在 before_trading_start 阶段调用,用于在每日交易开始前清洗股票池。
以下是该函数的详细用法和代码示例:
核心函数:filter_stock_by_status
该函数会自动剔除列表中符合指定状态(如 ST、停牌、退市)的股票,并返回清洗后的股票列表。
函数原型:
filter_stock_by_status(stocks, filter_type=["ST", "HALT", "DELISTING"], query_date=None)
参数说明:
- stocks: 股票代码列表(必填)。
- filter_type: 需要过滤掉的类型列表(选填)。默认值为
["ST", "HALT", "DELISTING"],即默认同时过滤 ST、停牌和退市股票。'ST': 过滤 ST 股票。'HALT': 过滤停牌股票。'DELISTING': 过滤退市股票。
- query_date: 查询日期(选填),回测中默认取当前回测日期。
策略代码示例
下面是一个完整的策略示例,展示如何在盘前阶段获取沪深300成分股,并使用该函数一键过滤掉 ST 和停牌的股票。
def initialize(context):
# 初始化时设置一个初始股票池,例如沪深300
# 注意:get_index_stocks 建议在 before_trading_start 中调用以获取动态成分股
# 这里仅作演示,先初始化为空或固定列表
g.security = []
set_universe(g.security)
def before_trading_start(context, data):
# 1. 获取当天的沪深300成分股
# 注意:get_index_stocks 获取的是当天的成分股
raw_stocks = get_index_stocks('000300.SS')
if not raw_stocks:
log.info("今日无成分股数据")
return
# 2. 使用 filter_stock_by_status 过滤 ST 和 停牌 股票
# filter_type 默认包含 ST, HALT, DELISTING,也可以手动指定
# 这里我们显式指定过滤 ST 和 停牌(HALT)
clean_stocks = filter_stock_by_status(raw_stocks, filter_type=['ST', 'HALT'])
# 3. 更新全局变量 g.security 为过滤后的股票列表
g.security = clean_stocks
# 4. 更新系统的股票池(可选,取决于策略逻辑是否依赖 universe)
set_universe(g.security)
# 打印日志对比数量
log.info("原始股票数量: %d, 过滤后股票数量: %d" % (len(raw_stocks), len(clean_stocks)))
# log.info("过滤后的股票列表: %s" % clean_stocks)
def handle_data(context, data):
# 在这里执行交易逻辑,此时 g.security 已经是过滤后的干净列表
# 示例:简单的买入逻辑
if len(g.security) > 0:
# 买入列表中的第一只股票
stock_to_buy = g.security[0]
order(stock_to_buy, 100)
注意事项
- 调用位置限制:根据 PTrade 文档说明,
filter_stock_by_status仅支持在before_trading_start模块调用。如果在handle_data中调用可能会报错或不生效。 - 默认行为:如果你不传递
filter_type参数,它会默认过滤掉 ST、停牌和退市这三类股票,这通常是最安全的做法。 - 手动替代方案:如果你需要在
handle_data中过滤(虽然不推荐),或者需要更复杂的逻辑,可以使用get_stock_status函数手动判断,但代码量会大很多。
总结
使用 filter_stock_by_status(stock_list) 是最简单的方法,一行代码即可完成 ST 和停牌股的剔除。
Q&A
Q: filter_stock_by_status 可以过滤掉退市整理期的股票吗?
A: 可以。在 filter_type 参数中包含 'DELISTING' 即可过滤退市股票。此外,还有一个专门的类型 'DELISTING_SORTING' 可以专门查询是否处于退市整理期(只过滤交易当日数据)。
Q: 如果我只想过滤停牌,不想过滤 ST 怎么办?
A: 你可以通过 filter_type 参数自定义过滤条件。例如:filter_stock_by_status(stocks, filter_type=['HALT']),这样就只会剔除停牌股,保留 ST 股。
Q: 这个函数在回测和实盘中表现一致吗?
A: 是的。在回测中,它会根据回测当天的历史状态进行过滤;在实盘交易中,它会根据当天的实时状态(通常是交易所发布的公告信息)进行过滤。
Q: 为什么建议在 before_trading_start 中调用而不是 initialize?
A: 因为股票的状态(是否停牌、是否戴帽ST)是随日期变化的。initialize 只在策略启动时运行一次,而 before_trading_start 每天开盘前都会运行。在 before_trading_start 中调用可以确保你每天使用的都是当天最新的状态信息,避免买入突然停牌或突然变 ST 的股票。