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

为什么在 JoinQuant 研究中调用 create_backtest 后 get_status 总是返回异常或空值?

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

问题描述

为什么在研究中调用回测功能,总是输出异常呢?

导入多回测与调整参数的函数库
import params_analysis

根据策略编码创建一个回测对象
outalgorithmid = createbacktest('400c6464a525__','2022-01-11','2022-05-18', frequency='day',initial_cash=1000000,use_credit=False)
out_algorithm_id = '8ada32__0'
get_bt = get_backtest(out_algorithm_id)
print(get_bt)
get_bt.get_status() ### 获利回测状态

get_bt.get_params() ## 获取回测参数
get_bt.get_results()
get_bt.get_positions()
输出总是:'done' 没有输出 ’running'正在运行的字样,
此时,聚宽后台上显示,回测正在运行。
outalgorithmid = '8ada32__0'
这个回测ID是在浏览器地址中得到的策略回测ID值
如果把outalgorithmid = '8ada32__0'这一句删除。
使用outalgorithmid = createbacktest('400c6464a525__','2022-01-11','2022-05-18', frequency='day',initial_cash=1000000,use_credit=False)根据策略ID创建回测的返回值,也就是一个回测ID,那么后面的
get_status() 就会得到None空值。get_results(),get_positions()同样无任何结果,得到一个 [ ]空值

解决方案

您好!在 JoinQuant 研究环境中调用 create_backtestget_backtest 时遇到这些现象,主要是因为API拼写错误硬编码了历史ID以及未处理异步执行机制导致的。下面为您详细剖析原因并提供正确的代码写法。

现象原因分析

1. 为什么硬编码 ID 总是输出 'done'

当您手动指定 out_algorithm_id = '8ada32__0' 时,您实际上是在查询一个过去已经运行完毕的回测记录。既然它在历史上已经跑完了,get_status() 自然会永远返回 'done'。此时聚宽后台显示的“正在运行”的回测,其实是您刚刚通过 create_backtest 新创建的那个回测,它的 ID 并不是 '8ada32__0'

2. 为什么使用返回的 ID 会得到 None 和空列表 []

  • API 拼写错误:聚宽的官方 API 是 create_backtest,而不是您代码中写的 createbacktest。如果拼写错误,可能导致未成功创建回测,返回的 ID 无效。
  • 异步执行机制create_backtest 提交回测任务后,服务器是在后台异步运行的。代码执行到 get_status() 时,回测可能处于 'none'(未开始)或 'running'(正在运行)状态。在回测没有达到 'done' 状态之前,调用 get_results()get_positions() 自然获取不到数据,因此返回空列表 []

正确的解决方法

要正确获取回测结果,您需要使用 create_backtest 返回的真实 ID,并通过一个 while 循环(轮询)来等待回测状态变为 'done',然后再去获取结果。

以下是标准的参考代码:

import time
from jqdata import *

# 1. 正确调用 create_backtest 创建回测
# 注意:API 名称是 create_backtest,带有下划线
algorithm_id = '400c6464a525__' # 请替换为您真实的策略ID

print("正在提交回测任务...")
new_bt_id = create_backtest(
    algorithm_id=algorithm_id,
    start_date='2022-01-11',
    end_date='2022-05-18', 
    frequency='day',
    initial_cash=1000000,
    use_credit=False
)

print(f"回测任务提交成功,回测ID为: {new_bt_id}")

# 2. 获取回测对象
get_bt = get_backtest(new_bt_id)

# 3. 轮询等待回测完成
while True:
    status = get_bt.get_status()
    print(f"当前回测状态: {status}")
    
    if status == 'done':
        print("回测运行完成!")
        break
    elif status in ['failed', 'canceled', 'deleted']:
        print(f"回测异常终止,最终状态: {status}")
        break
        
    # 如果是 'none' 或 'running',等待几秒钟再次查询
    time.sleep(5) 

# 4. 只有在状态为 'done' 时,才去获取结果
if get_bt.get_status() == 'done':
    params = get_bt.get_params()
    results = get_bt.get_results()
    positions = get_bt.get_positions()
    
    print("获取到回测参数:", params)
    print(f"获取到收益记录条数: {len(results)}")
    print(f"获取到持仓记录条数: {len(positions)}")

核心总结

  1. 确保 API 拼写正确:create_backtest
  2. 不要硬编码浏览器里的旧 ID,必须使用 create_backtest 动态返回的 ID。
  3. 必须使用 time.sleep() 配合 while 循环等待 get_status() 变为 'done',然后再调用 get_results() 等获取数据的接口。