🚀 AI 一键生成 joinquant 策略代码

JoinQuant 数据教程:如何获取行情时自动过滤停牌股票?

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

问题描述

获取历史行情时如何跳过停牌的股票?

解决方案

在 JoinQuant(聚宽)平台中,获取历史行情时跳过停牌股票主要通过设置数据获取函数的 skip_paused 参数来实现。此外,在实盘或回测交易逻辑中,通常结合 get_current_data() 来判断当前是否停牌。

以下是具体的实现方法和代码示例:

1. 使用数据获取函数的 skip_paused 参数

大多数获取历史数据的 API(如 get_price, attribute_history, history)都包含 skip_paused 参数。

  • skip_paused=True: 跳过停牌日期(即只返回有实际交易的数据)。
  • skip_paused=False (默认): 不跳过。停牌期间的数据会用前一交易日的收盘价填充,成交量为0。

示例 A: 使用 get_price

# 获取平安银行 2023年1月1日 到 2023年2月1日 的数据
# 开启 skip_paused=True,停牌期间的行将被剔除
df = get_price('000001.XSHE', 
               start_date='2023-01-01', 
               end_date='2023-02-01', 
               frequency='daily', 
               fields=['open', 'close', 'volume'], 
               skip_paused=True) 
print(df)

示例 B: 使用 attribute_history (常用于策略中获取过去N天数据)

def handle_data(context, data):
    # 获取过去5个交易日的数据,跳过停牌
    # 如果某天停牌,这天的数据不会被计入 count,系统会继续向前寻找直到凑齐5条实际交易数据
    h = attribute_history('000001.XSHE', 5, '1d', ['close', 'volume'], skip_paused=True)
    log.info(h)

示例 C: 使用 history

def handle_data(context, data):
    # 获取股票池中所有股票过去5天的数据,跳过停牌
    # 注意:如果获取多只股票且 skip_paused=True,返回的 DataFrame 索引可能不再是统一的日期
    h = history(5, '1d', 'close', ['000001.XSHE', '600519.XSHG'], skip_paused=True)

2. 关于 get_bars 的特殊说明

get_bars 函数没有 skip_paused 选项。

  • get_bars 获取的数据本身就是不包含停牌数据的(即只返回有成交的 Bar)。
  • 如果请求 count=5,它会返回最近的5条有交易的记录。如果中间有停牌,它会自动跨过停牌期去取更早的数据,实际上等同于跳过了停牌。
# 获取最近5条数据,如果中间有停牌,会自动取更早的实际交易日数据
bars = get_bars('000001.XSHE', count=5, unit='1d', fields=['date', 'close'])

3. 在交易逻辑中手动过滤(推荐)

在编写策略(如 handle_databefore_trading_start)准备下单时,通常需要判断当前是否停牌,以避免无效下单或错误计算。这时应使用 get_current_data()

def handle_data(context, data):
    security = '000001.XSHE'
    
    # 获取当前数据快照
    current_data = get_current_data()
    
    # 判断是否停牌
    if current_data[security].paused:
        log.info(f"{security} 今日停牌,跳过交易")
        return
    
    # 如果未停牌,继续执行策略逻辑
    close_price = data[security].close
    # ... 下单逻辑 ...

总结

API 函数 默认行为 如何跳过停牌 备注
get_price 填充停牌数据 设置 skip_paused=True 获取指定时间段数据时常用
attribute_history 填充停牌数据 设置 skip_paused=True 策略中获取单只股票历史常用
history 填充停牌数据 设置 skip_paused=True 策略中获取多只股票历史常用
get_bars 自动跳过 无需设置 返回的数据不包含停牌时的填充数据
get_current_data N/A 检查 .paused 属性 用于判断当前时刻是否停牌

Q&A

Q: 如果我在 attribute_history 中设置了 skip_paused=True,获取 count=5 的数据,返回的行数一定是5吗?
A: 是的。系统会忽略停牌的日期,一直向前追溯,直到凑齐 5 个实际交易日的数据为止(除非该股票上市时间太短,总交易天数不足5天)。

Q: get_price 获取多只股票时,设置 skip_paused=True 会有什么影响?
A: 如果获取多只股票且设置了跳过停牌,由于不同股票的停牌日期不同,返回的 Panel 或 DataFrame 可能会出现对齐问题。在旧版 Pandas Panel 中,索引不再是统一的日期;在 DataFrame 模式下,可能会导致数据长度不一致或包含 NaN(取决于具体的 panel 参数设置)。建议对多只股票处理时,如果需要严格对齐日期,使用默认的 skip_paused=False(使用前值填充),或者分别获取后再进行数据清洗。

Q: 为什么 get_bars 没有 skip_paused 参数?
A: 因为 get_bars 的设计初衷是获取实际存在的 K 线(Bar)。停牌期间没有交易,自然没有 K 线生成,因此它返回的数据天然就是跳过停牌的。