问题描述
解决方案
在JoinQuant(聚宽)量化平台上,过滤ST股(包括*ST)和停牌股票是构建稳健量化策略的基础步骤。通常,我们会在策略的选股阶段(如 before_trading_start 或 handle_data 中)进行这一操作。
最常用且高效的方法是使用聚宽提供的 get_current_data() API。该函数可以获取当前单位时间(当天/当前分钟)的标的状态信息。
核心API介绍
get_current_data() 返回一个字典,其中 key 是股票代码,value 是包含股票状态的对象。该对象包含以下两个关键属性:
is_st: 布尔值,判断股票当天是否是 ST 或 *ST。paused: 布尔值,判断股票当天是否停牌、未上市或者退市。
Python 代码示例
下面是一个通用的过滤函数,你可以将其直接复制到你的策略代码中调用:
# 导入聚宽函数库
import jqdata
def filter_st_paused_stocks(stock_list):
"""
过滤股票列表中的ST股和停牌股票
:param stock_list: 原始股票代码列表
:return: 过滤后的股票代码列表
"""
# 获取当前时刻的股票状态数据
current_data = get_current_data()
# 列表推导式进行过滤
# 条件1:not current_data[stock].is_st (不是ST股)
# 条件2:not current_data[stock].paused (没有停牌)
filtered_list = [stock for stock in stock_list
if not current_data[stock].is_st
and not current_data[stock].paused]
return filtered_list
在策略中的实际应用
以下是一个完整的策略框架示例,展示了如何在每天开盘前获取沪深300成分股,并剔除其中的ST和停牌股票:
import jqdata
def initialize(context):
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 每天开盘前运行选股逻辑
run_daily(before_market_open, time='09:00', reference_security='000300.XSHG')
def before_market_open(context):
# 1. 获取初始股票池(例如:沪深300成分股)
initial_stocks = get_index_stocks('000300.XSHG')
# 2. 调用过滤函数,去除ST和停牌股
g.buy_list = filter_st_paused_stocks(initial_stocks)
log.info(f"初始股票数量: {len(initial_stocks)},过滤后可用股票数量: {len(g.buy_list)}")
def filter_st_paused_stocks(stock_list):
current_data = get_current_data()
return [stock for stock in stock_list
if not current_data[stock].is_st
and not current_data[stock].paused]
def handle_data(context, data):
# 在这里使用过滤后的 g.buy_list 进行交易逻辑
pass
注意事项
- 调用时机:
get_current_data()必须在交易时段或before_trading_start(09:00) 中调用,如果在initialize中调用可能会获取不到准确的当日状态。 - 性能优化:
get_current_data()返回的字典是按需获取的(Lazy Load),即只有当你访问current_data[stock]时才会去底层取数据,因此在列表推导式中使用是非常高效的。 - 退市股票:
paused属性不仅包含停牌,如果股票未上市或已退市,它也会返回True,因此该过滤逻辑同时也能剔除退市股票。