🚀 AI 一键生成 ptrade 策略代码

PTrade 回测技巧:如何在获取历史行情时过滤掉停牌日期?

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

问题描述

获取历史行情时如何过滤掉停牌(成交量为0)的数据?

解决方案

在PTrade中,get_historyget_price 接口在获取历史行情时,默认不会跳过停牌日期。对于停牌期间的数据,系统会使用停牌前一交易日的收盘价进行填充,并将成交量(volume)设为0

因此,要过滤掉停牌数据,最直接有效的方法是对返回的 DataFrame 进行筛选,剔除 volume 为 0 的行。

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

代码实现

def initialize(context):
    g.security = '600570.SS'
    set_universe(g.security)

def handle_data(context, data):
    # 1. 获取历史行情数据(包含收盘价和成交量)
    # 注意:必须获取 'volume' 字段用于判断
    df = get_history(10, frequency='1d', field=['close', 'volume'], security_list=g.security)
    
    # 打印原始数据(包含停牌填充数据)
    log.info("原始数据:")
    log.info(df)
    
    # 2. 过滤停牌数据
    # 逻辑:保留成交量大于0的数据
    df_filtered = df[df['volume'] > 0]
    
    # 打印过滤后的数据
    log.info("过滤停牌后数据:")
    log.info(df_filtered)
    
    # 3. 进一步处理(示例:计算均线)
    if len(df_filtered) > 0:
        mean_price = df_filtered['close'].mean()
        log.info("有效交易日的平均收盘价: %s" % mean_price)

核心逻辑说明

  1. 获取字段:调用 get_historyget_price 时,field 参数必须包含 'volume',因为这是判断是否停牌的关键依据。
  2. Pandas筛选:利用 Pandas DataFrame 的布尔索引功能 df[df['volume'] > 0],直接筛选出成交量大于 0 的行。
  3. 多股处理:如果是同时获取多只股票的数据(返回 DataFrame 格式,包含 code 列),上述代码同样适用,它会移除所有股票中成交量为 0 的记录。

Q&A

Q: 为什么PTrade返回的历史数据包含停牌日?
A: PTrade 为了保持时间序列的连续性(例如在绘制K线图或进行矩阵计算时保持索引对齐),默认会对停牌日进行填充。填充规则是:价格沿用前一交易日收盘价,成交量为0。

Q: 除了判断成交量,还有其他方法判断停牌吗?
A: 可以使用 get_stock_status(stocks, 'HALT') 接口查询股票当前的停牌状态,或者使用 get_history 时获取 paused 字段(如果接口支持返回该字段,但在PTrade标准文档中,利用 volume 判断是最通用的做法)。

Q: 如果股票全天跌停或涨停导致没有成交量,会被误判为停牌吗?
A: 理论上极少出现全天成交量严格为0的情况(通常会有少量撮合)。但在极端流动性枯竭的情况下,如果成交量确实为0,该逻辑会将其过滤。对于绝大多数A股策略,volume > 0 是区分停牌与否的有效标准。