🚀 AI 一键生成 joinquant 策略代码

在 JoinQuant 聚宽平台上获取股票日内涨停特征的完整指南

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

问题描述

请问如何获取某个股票在某一天内的涨停特征?

最近在做涨停相关研究,日内首次涨停时间/末次涨停时间/开板次数这几个是比较重要的特征,请问在聚宽有办法获取这些信息吗?

解决方案

在聚宽(JoinQuant)平台上,要精确获取股票日内的首次涨停时间末次涨停时间以及开板次数,最准确的方法是结合日线数据(获取当天的涨停价)和 Tick 数据(获取微观的盘口价格变化)来进行统计。

由于分钟线(1m)可能会掩盖一分钟内发生的瞬间开板和回封,因此强烈建议使用 get_ticks 接口来提取这些特征。

实现思路

  1. 获取涨停价:使用 get_price 获取目标股票在目标日期的 high_limit(涨停价)。
  2. 获取高频数据:使用 get_ticks 获取目标股票在目标日期的所有 Tick 数据。
  3. 状态机统计:遍历 Tick 数据,维护一个 is_limit_up(是否处于涨停状态)的布尔变量。
    • 当价格首次达到涨停价时,记录首次涨停时间,并将状态设为 True
    • 只要价格等于涨停价,就不断更新末次涨停时间
    • 当状态为 True 且最新价格跌破涨停价时,说明发生了开板,开板次数加 1,并将状态设为 False

Python 代码实现

您可以将以下代码直接复制到聚宽的**研究环境(Jupyter Notebook)**中运行和测试:

from jqdata import *
import pandas as pd

def get_limit_up_features(security, date):
    """
    获取指定股票在指定日期的涨停特征
    :param security: 股票代码,如 '000001.XSHE'
    :param date: 日期字符串,如 '2021-01-05'
    :return: dict 包含涨停特征,如果没有触及涨停则返回 None
    """
    # 1. 获取当天的涨停价
    df_day = get_price(security, start_date=date, end_date=date, frequency='daily', fields=['high_limit'], panel=False)
    if df_day.empty:
        return None
    high_limit = df_day['high_limit'].iloc[0]
    
    # 2. 获取当天的 Tick 数据
    start_dt = f"{date} 09:15:00"
    end_dt = f"{date} 15:00:00"
    # skip=False 保留所有盘口变化的 tick,确保不漏掉瞬间开板
    ticks = get_ticks(security, start_dt=start_dt, end_dt=end_dt, fields=['time', 'current'], skip=False, df=True)
    
    if ticks.empty:
        return None
        
    # 初始化特征变量
    first_limit_up_time = None
    last_limit_up_time = None
    open_board_count = 0
    is_limit_up = False
    
    # 3. 遍历 Tick 数据进行统计
    for index, row in ticks.iterrows():
        current_price = row['current']
        current_time = row['time']
        
        # 考虑到浮点数精度问题,使用 round 比较
        if round(current_price, 2) >= round(high_limit, 2):
            if not is_limit_up:
                is_limit_up = True
                if first_limit_up_time is None:
                    first_limit_up_time = current_time
            # 只要在涨停价,就更新末次涨停时间
            last_limit_up_time = current_time
        else:
            # 如果当前处于涨停状态,但价格掉下来了,说明开板
            if is_limit_up:
                is_limit_up = False
                open_board_count += 1
                
    # 如果全天未触及涨停,返回 None
    if first_limit_up_time is None:
        return {
            'security': security,
            'date': date,
            'is_limit_up_touched': False
        }
    
    # 格式化 Tick 的时间戳 (聚宽的 tick time 格式为 float: YYYYMMDDHHMMSS.0)
    def format_tick_time(t):
        if pd.isna(t) or t is None:
            return None
        return pd.to_datetime(str(int(t)), format='%Y%m%d%H%M%S')

    return {
        'security': security,
        'date': date,
        'high_limit': high_limit,
        'is_limit_up_touched': True,
        'first_limit_up_time': format_tick_time(first_limit_up_time),
        'last_limit_up_time': format_tick_time(last_limit_up_time),
        'open_board_count': open_board_count
    }

# ================= 测试用例 =================
# 假设我们要查询某只股票在某天的涨停情况
# 请替换为您已知当天涨停的股票代码和日期进行测试
features = get_limit_up_features('000001.XSHE', '2015-04-13') 
print(features)

注意事项与优化建议

  1. Tick 数据的获取限制get_ticks 接口每次获取的数据量较大。如果您需要大批量计算全市场所有股票的历史涨停特征,直接循环调用 get_ticks 可能会非常耗时。建议先通过日线数据(high == high_limit)筛选出当天触及过涨停的股票池,然后再针对这些股票请求 Tick 数据。
  2. 浮点数精度:在比较价格时,由于 Python 浮点数的特性,建议使用 round(price, 2) 来与 high_limit 进行比较,避免因为 9.999999910.00 的微小差异导致判断失败。
  3. 集合竞价get_ticks 包含了 09:15~09:25 的集合竞价数据。如果您只关心连续竞价期间(09:30 之后)的涨停和开板,可以在遍历前将 ticks 数据过滤,例如 ticks = ticks[ticks['time'] >= float(date.replace('-', '') + '093000')]
  4. 分钟线替代方案:如果您的研究对精度要求没有那么苛刻(允许忽略 1 分钟内的瞬间开板),可以使用 get_price(..., frequency='1m') 替代 get_ticks,这会大幅提升数据获取和计算的速度。