问题描述
导入多回测与调整参数的函数库
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_backtest 和 get_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)}")
核心总结
- 确保 API 拼写正确:
create_backtest。 - 不要硬编码浏览器里的旧 ID,必须使用
create_backtest动态返回的 ID。 - 必须使用
time.sleep()配合while循环等待get_status()变为'done',然后再调用get_results()等获取数据的接口。