🚀 AI 一键生成 joinquant 策略代码

JoinQuant聚宽平台如何解决 limit(n) 限制返回条数的问题?

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

问题描述

如何解决limit(n)限制返回条数

由于返回限制,只能调取4000家上市公司数据
此问题如何解决?

filter(finance.STK_EMPLOYEE_INFO.code==code):指定筛选条件,通过finance.STK_EMPLOYEE_INFO.code==code可以指定你想要查询的股票代码;除此之外,还可以对表中其他字段指定筛选条件,如finance.STK_EMPLOYEE_INFO.pub_date>=’2015-01-01’,表示公告日期大于2015年1月1日上市公司公布的员工信息;多个筛选条件用英文逗号分隔。
limit(n):限制返回的数据条数,n指定返回条数。
返回结果:

返回一个 dataframe, 每一行对应数据表中的一条数据, 列索引是你所查询的字段名称
注意:

为了防止返回数据量过大, 我们每次最多返回3000行
不能进行连表查询,即同时查询多张表的数据

解决方案

在 JoinQuant (聚宽) 平台中,为了防止单次查询占用过多内存和服务器资源,finance.run_queryget_fundamentals 等 API 确实对单次返回的数据行数做了限制(通常为 3000、4000 或 5000 行)。

要突破这个限制获取全量数据,核心思路是分批查询(循环获取)然后将结果拼接。以下为您提供三种最常用的解决方案:

方法一:使用 offset() 进行分页查询(最通用)

SQLAlchemy 的 query 对象支持 .offset(n) 方法,它可以跳过前 n 条数据。我们可以结合 limit()offset() 写一个 while 循环,直到取不到数据为止。

import pandas as pd
from jqdata import *

def get_all_employee_info():
    all_data = pd.DataFrame()
    limit_size = 3000  # 每次最大获取条数
    offset_size = 0    # 初始偏移量
    
    while True:
        # 构造查询,每次向后偏移 offset_size
        q = query(finance.STK_EMPLOYEE_INFO).limit(limit_size).offset(offset_size)
        df = finance.run_query(q)
        
        # 如果返回的数据为空,说明已经取完,退出循环
        if df.empty:
            break
            
        # 将本次获取的数据拼接到总表中
        all_data = pd.concat([all_data, df], ignore_index=True)
        
        # 增加偏移量,准备下一次查询
        offset_size += limit_size
        
    return all_data

# 调用函数获取全量数据
full_df = get_all_employee_info()
print("总共获取到数据条数:", len(full_df))

方法二:按股票代码分批查询(推荐用于横截面数据)

如果您只需要查询当前所有上市公司的某项数据,可以将全市场的股票代码列表切分成多个小块(例如每次查 500 只股票),然后循环查询。

import pandas as pd
from jqdata import *

def get_info_by_code_batches():
    # 获取所有股票代码
    all_stocks = list(get_all_securities(['stock']).index)
    all_data = pd.DataFrame()
    step = 500  # 每次查询500只股票,确保不会超过3000条限制
    
    for i in range(0, len(all_stocks), step):
        # 切片获取当前批次的股票代码
        codes_batch = all_stocks[i : i+step]
        
        # 使用 in_() 筛选当前批次的股票
        q = query(finance.STK_EMPLOYEE_INFO).filter(
            finance.STK_EMPLOYEE_INFO.code.in_(codes_batch)
        )
        df = finance.run_query(q)
        
        all_data = pd.concat([all_data, df], ignore_index=True)
        
    return all_data

方法三:按时间段分批查询(推荐用于历史时间序列数据)

如果您要获取的是多年的历史数据(例如每天的龙虎榜、多年的财务报表),按股票代码分批可能依然会超限,此时可以按时间(如按月、按季度)进行循环。

import pandas as pd
from jqdata import *

def get_info_by_date_batches():
    all_data = pd.DataFrame()
    # 生成按年或按月的日期范围
    date_ranges = pd.date_range(start='2015-01-01', end='2023-01-01', freq='Y')
    
    for i in range(len(date_ranges)-1):
        start_dt = date_ranges[i].strftime('%Y-%m-%d')
        end_dt = date_ranges[i+1].strftime('%Y-%m-%d')
        
        q = query(finance.STK_EMPLOYEE_INFO).filter(
            finance.STK_EMPLOYEE_INFO.pub_date >= start_dt,
            finance.STK_EMPLOYEE_INFO.pub_date < end_dt
        )
        df = finance.run_query(q)
        all_data = pd.concat([all_data, df], ignore_index=True)
        
    return all_data

总结与建议

  1. 无特定筛选条件时:首选 方法一 (offset),代码最简单,逻辑最清晰。
  2. 需要特定股票池时:首选 方法二 (按代码分批),效率较高。
  3. 注意内存:如果获取的数据量极大(如几十万条),请注意研究环境的内存限制,建议将获取到的 DataFrame 及时通过 write_file 保存为 CSV 文件,避免内存溢出。