3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在聚宽(JoinQuant)平台上进行策略开发时,NameError 和 SecurityNotExist(找不到标的)是最常见的两类错误。以下是针对这两个问题的详细调试方法和解决方案。
NameError错误原因:
通常是因为使用了未定义的变量。在聚宽的策略框架中,最常见的情况是变量作用域问题。
解决方案:使用全局对象 g
聚宽提供了一个全局对象 g,用于在不同的函数(如 initialize 和 handle_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)
错误原因:
.XSHG,深圳证券交易所后缀为 .XSHE。解决方案:
'000001.XSHE' (平安银行) 或 '600519.XSHG' (贵州茅台)。normalize_code:如果不确定后缀,可以使用此函数自动补全。错误示例:
# 错误:缺少后缀
order('000001', 100)
# 报错:Exception: 找不到标的000001
正确示例:
# 方法1:手动补全后缀
order('000001.XSHE', 100)
# 方法2:使用 normalize_code 自动转换
code = normalize_code('000001')
order(code, 100)
当遇到报错时,请按照以下步骤进行排查:
log.info 或 print)在关键代码行之前打印变量的值,确认程序是否按预期执行。
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)
在回测界面的“日志”面板中,报错信息通常会指出具体的行号(Line X)。
g.)。如果不确定某个标的在当前日期是否可交易,可以使用 get_security_info 或 get_all_securities 查询。
# 检查标的信息
info = get_security_info('000001.XSHE')
if info:
log.info("上市日期: %s" % info.start_date)
else:
log.error("标的不存在或代码错误")
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')。这些信息会显示在回测页面的“日志”或“输出”栏中,帮助您判断代码执行流程。