🚀 AI 一键生成 qmt 策略代码
立即体验

QMT平台如何利用get_open_date计算上市天数并过滤次新股?(附Python源码)

qmt | 发布时间: 2026/8/6
以下内容由 EasyQuant 生成。

问题描述

qmt 过滤次新股:利用 get_open_date 计算股票上市天数
qmt如何计算股票已经上市了多少天并过滤掉次新股?

解决方案

QMT平台过滤次新股:利用 get_open_date 计算股票上市天数

在量化投资中,新股和次新股(通常指上市未满一年的股票)由于上市初期波动剧烈、历史数据较少、估值溢价较高,往往不符合大多数稳健型选股策略的要求。因此,在策略初始化或选股阶段过滤掉次新股是一个非常常见的需求。

QMT(迅投极速量化交易系统)提供了 ContextInfo.get_open_date() 接口,可以非常方便地获取个股的上市日期。结合当前 K 线的时间戳,我们就可以动态计算出股票的已上市天数,从而实现次新股的精准过滤。


1. 核心 API 介绍

(1)获取上市日期:ContextInfo.get_open_date()

  • 用法ContextInfo.get_open_date(stockcode)
  • 参数stockcode 为股票代码,如 '000001.SZ'
  • 返回:返回一个 number 类型的上市日期,格式通常为 YYYYMMDD(例如 19910403)。

(2)获取当前 K 线时间戳:ContextInfo.get_bar_timetag()

  • 用法ContextInfo.get_bar_timetag(index)
  • 参数index 为 K 线索引号,通常传入当前索引 ContextInfo.barpos
  • 返回:毫秒级时间戳。

(3)时间戳转日期字符串:timetag_to_datetime()

  • 用法timetag_to_datetime(timetag, format)
  • 返回:格式化后的日期字符串。

2. 过滤次新股的实现逻辑

  1. 获取股票的上市日期:使用 ContextInfo.get_open_date(stock) 得到 YYYYMMDD 格式的数字,并将其转换为 Python 的 datetime 对象。
  2. 获取当前回测/交易日期的当前时间:通过当前 Bar 的时间戳转换为 datetime 对象。
  3. 计算天数差:将“当前日期”减去“上市日期”,得到两者的天数差(days)。
  4. 设定阈值过滤:若天数差小于设定的阈值(如 365 天),则判定为次新股并予以剔除。

3. Python 策略源码示例

以下是一个完整的 QMT 选股过滤示例,展示了如何在 handlebar 中动态过滤掉上市不满 365 天的次新股:

#coding:gbk
import datetime

def init(ContextInfo):
    # 1. 设定初始股票池(包含老股和次新股作为对比)
    # 300919.SZ 属于较新的股票,000001.SZ 为老股
    ContextInfo.set_universe(['000001.SZ', '300919.SZ', '600000.SH'])
    
    # 2. 设定过滤阈值:上市天数必须大于 365 天(即过滤掉上市一年内的次新股)
    ContextInfo.min_listed_days = 365
    print("初始化完成,次新股过滤阈值设定为:", ContextInfo.min_listed_days, "天")

def handlebar(ContextInfo):
    # 获取当前 Bar 的时间戳并转换为 datetime 对象
    bar_time = ContextInfo.get_bar_timetag(ContextInfo.barpos)
    bar_date_str = timetag_to_datetime(bar_time, '%Y%m%d')
    current_date = datetime.datetime.strptime(bar_date_str, '%Y%m%d')

    # 获取当前股票池
    stock_list = ContextInfo.get_universe()
    filtered_list = []

    for stock in stock_list:
        # 获取上市日期(返回如 19910403.0 或 19910403)
        open_date_num = ContextInfo.get_open_date(stock)
        if open_date_num <= 0:
            continue
        
        # 将浮点数或整数安全转换为 YYYYMMDD 字符串
        open_date_str = str(int(open_date_num))
        
        try:
            open_date = datetime.datetime.strptime(open_date_str, '%Y%m%d')
            # 计算当前 K 线日期与上市日期的天数差
            listed_days = (current_date - open_date).days
            
            # 判断是否满足上市天数要求
            if listed_days >= ContextInfo.min_listed_days:
                filtered_list.append(stock)
                print(f"【保留】股票: {stock}, 上市日期: {open_date_str}, 已上市: {listed_days} 天")
            else:
                print(f"【过滤】股票: {stock}, 上市日期: {open_date_str}, 已上市: {listed_days} 天 (属于次新股)")
        except Exception as e:
            print(f"解析股票 {stock} 上市日期 {open_date_str} 失败: {e}")

    # 输出过滤后的股票池,后续交易逻辑可基于 filtered_list 进行
    print(f"当前交易日 {bar_date_str} 过滤后的有效股票池: {filtered_list}")
    print("-" * 50)

4. 注意事项

  1. 数据补充:在使用此策略前,请确保通过 QMT 客户端的【数据管理】功能补充了相关股票的历史行情数据基础属性数据,否则 get_open_date 可能会返回默认值或 0
  2. 回测与实盘通用:该方法在历史回测和实盘运行中均完全适用。在回测中,它会根据回测当时的历史时间动态计算上市天数,避免了“未来函数”的发生。