🚀 AI 一键生成 joinquant 策略代码

JoinQuant 策略报错?常见错误(如 NameError, SecurityNotExist)调试与解决方法汇总

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

问题描述

我的策略总是报错,比如 'NameError' 和 '找不到标的',该怎么调试?

解决方案

在聚宽(JoinQuant)平台上进行策略开发时,NameErrorSecurityNotExist(找不到标的)是最常见的两类错误。以下是针对这两个问题的详细调试方法和解决方案。

1. 解决 NameError

错误原因:
通常是因为使用了未定义的变量。在聚宽的策略框架中,最常见的情况是变量作用域问题。

  • 局部变量:在一个函数内定义的变量无法在另一个函数中直接使用。
  • 拼写错误:变量名拼写不一致。

解决方案:使用全局对象 g
聚宽提供了一个全局对象 g,用于在不同的函数(如 initializehandle_data)之间传递变量。

错误示例:

def initialize(context):
    # 错误:security 是局部变量,只能在 initialize 中访问
    security = '000001.XSHE' 

def handle_data(context, data):
    # 报错:NameError: global name 'security' is not defined
    order(security, 100) 

正确示例:

def initialize(context):
    # 正确:使用 g.security,将其存储在全局对象中
    g.security = '000001.XSHE'

def handle_data(context, data):
    # 正确:通过 g.security 调用
    order(g.security, 100)

2. 解决 “找不到标的” (SecurityNotExist)

错误原因:

  • 代码格式错误:聚宽要求股票代码必须包含后缀。上海证券交易所后缀为 .XSHG,深圳证券交易所后缀为 .XSHE
  • 标的已退市或未上市:在回测的时间段内,该股票不存在。
  • 拼写错误:代码数字写错。

解决方案:

  1. 检查后缀:确保代码格式如 '000001.XSHE' (平安银行) 或 '600519.XSHG' (贵州茅台)。
  2. 使用 normalize_code:如果不确定后缀,可以使用此函数自动补全。

错误示例:

# 错误:缺少后缀
order('000001', 100) 
# 报错:Exception: 找不到标的000001

正确示例:

# 方法1:手动补全后缀
order('000001.XSHE', 100)

# 方法2:使用 normalize_code 自动转换
code = normalize_code('000001')
order(code, 100)

3. 通用调试技巧

当遇到报错时,请按照以下步骤进行排查:

A. 利用日志输出 (log.infoprint)

在关键代码行之前打印变量的值,确认程序是否按预期执行。

def handle_data(context, data):
    # 打印当前时间和变量值,方便在日志中追踪
    log.info("当前时间: %s" % context.current_dt)
    log.info("尝试交易: %s" % g.security)
    
    # 检查数据是否存在
    if g.security not in data:
        log.warn("数据缺失: %s" % g.security)
        return

    order(g.security, 100)

B. 定位报错行号

在回测界面的“日志”面板中,报错信息通常会指出具体的行号(Line X)。

  1. 找到报错的行。
  2. 检查该行使用的所有变量是否已定义(是否需要加 g.)。
  3. 检查该行调用的 API 参数是否正确。

C. 检查标的是否存在

如果不确定某个标的在当前日期是否可交易,可以使用 get_security_infoget_all_securities 查询。

# 检查标的信息
info = get_security_info('000001.XSHE')
if info:
    log.info("上市日期: %s" % info.start_date)
else:
    log.error("标的不存在或代码错误")

Q&A

Q: 为什么我在 initialize 里定义了变量,在 handle_data 里还是报错说没定义?
A: 因为 Python 函数中的变量默认是局部的。在聚宽中,必须将变量赋值给 g 对象(例如 g.my_var = 1),才能在其他函数中通过 g.my_var 访问,或者该变量确实是拼写错误。

Q: 我输入的股票代码是 600000,为什么提示找不到?
A: 聚宽的股票代码需要包含交易所后缀。上海股票需加 .XSHG(如 600000.XSHG),深圳股票需加 .XSHE。您可以使用 normalize_code('600000') 来自动获取正确的代码格式。

Q: 如何查看我的策略运行到了哪一步?
A: 使用 log.info('这里是步骤1')print('这里是步骤1')。这些信息会显示在回测页面的“日志”或“输出”栏中,帮助您判断代码执行流程。