🚀 AI 一键生成 joinquant 策略代码
立即体验
👉 AI 生成代码 👈

解决JoinQuant自定义因子统计多日涨停板数据无效的问题

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

问题描述

自定义因子-统计90日内涨停板数 多日数据无效?

class ztx(Factor):

# 设置因子名称
name = 'ztx'
# 设置获取数据的时间窗口长度
max_window = 90
# 设置依赖的数据
dependencies = ['close']

# 计算因子的函数, 需要返回一个 pandas.Series, index 是股票代码,value 是因子值
def calc(self, data):
close = data['close'] # close is a df, column is stock code, index is datetime
temp = pd.Series(0,index = close.iloc[0,:].index) # 初始化为0的矩阵
for i in (0,88): # 循环1
zhangfu_series = close.iloc[i+1,:]/close.iloc[i,:] # 计算涨幅
temp += zhangfu_series
for j in range(len(zhangfu_series)):
if zhangfu_series[j] > 1.095: # 大于9.5% 记作涨停
temp[j] += 1
return temp
计算的是 90日内有N个涨停板,但是temp 这个series 无法计算超过2天的数据 (max_window=90)通过打印日志, 函数中循环1 只被执行了2次,不知道是哪里出了问题,求解。

解决方案

您好!导致循环只执行了2次的原因是 Python 的基础语法问题。

问题原因分析

在您的代码中,循环语句写成了:

for i in (0,88):

在 Python 中,(0, 88) 是一个包含两个元素(0 和 88)的元组(Tuple)。因此,这个 for 循环只会遍历这两个具体的数字,也就是 i=0 执行一次,i=88 执行一次,总共只执行了 2 次。

如果您想让 i 从 0 遍历到 88,应该使用 range() 函数:

for i in range(89): # range(89) 会生成 0 到 88 的整数序列

优化方案(强烈推荐)

虽然修改 range 可以解决您的 Bug,但在量化回测中,使用 for 循环遍历 DataFrame 的行和列是非常低效的。Pandas 提供了强大的向量化运算功能,可以一行代码完成您想要的功能,且运行速度会快几十倍甚至上百倍。

您可以直接使用 Pandas 的 pct_change() 来计算涨幅,并用条件判断和 sum() 来统计涨停次数。以下是优化后的完整因子代码:

import pandas as pd
from jqfactor import Factor

class ztx(Factor):
    # 设置因子名称
    name = 'ztx'
    # 设置获取数据的时间窗口长度
    max_window = 90
    # 设置依赖的数据
    dependencies = ['close']

    def calc(self, data):
        close = data['close']
        
        # 1. 计算每日涨幅 (今日收盘价 / 昨日收盘价 - 1)
        # pct_change() 会自动计算相邻两行的变化率
        pct_chg = close.pct_change()
        
        # 2. 判断涨幅是否大于 9.5% (0.095)
        # 这会返回一个由 True 和 False 组成的 DataFrame
        is_limit_up = pct_chg > 0.095
        
        # 3. 按列(即按股票)对 True 的个数进行求和
        # sum() 会将 True 视为 1,False 视为 0
        limit_up_counts = is_limit_up.sum()
        
        # 返回的 limit_up_counts 就是一个 pandas.Series,index 是股票代码,value 是涨停次数
        return limit_up_counts

优化代码的优势:

  1. 代码简洁:去掉了繁琐的嵌套 for 循环,逻辑更加清晰。
  2. 性能极高:底层调用 C 语言级别的向量化运算,在处理全市场几千只股票的 90 天数据时,耗时几乎可以忽略不计,能大幅缩短您的回测和因子分析时间。
  3. 避免越界:自动处理了第一天没有昨日收盘价(pct_change 第一行为 NaN)的问题,不会报错。