问题描述
解决方案
在聚宽(JoinQuant)平台中,要获取和分析一个已经完成的回测的详细数据,主要使用 get_backtest 函数。
注意: 此函数只能在 研究环境(Notebook) 中运行,不支持在策略回测或模拟交易的运行过程中调用。
以下是详细的代码示例和分析步骤:
1. 获取回测 ID (Backtest ID)
首先,你需要找到你想要分析的回测的 ID。
- 打开回测详情页面。
- 查看浏览器地址栏的 URL,例如:
https://www.joinquant.com/algorithm/backtest/detail?backtestId=1234567890 backtestId后面的数字/字符串即为回测 ID。
2. 代码实现:获取与分析数据
请在聚宽的 研究环境 中新建一个 Notebook,并运行以下代码:
# -*- coding: utf-8 -*-
import pandas as pd
from jqdata import *
# 1. 设置回测ID (请替换为你实际的回测ID)
backtest_id = '这里填写你的回测ID'
# 2. 获取回测对象
gt = get_backtest(backtest_id)
# --- 获取基础信息 ---
# 获取回测状态 (none, running, done, failed, canceled, paused, deleted)
status = gt.get_status()
print(f"回测状态: {status}")
# 获取回测参数 (策略ID, 起止日期, 初始资金等)
params = gt.get_params()
print(f"回测参数: {params}")
# --- 获取详细数据并转换为 DataFrame 以便分析 ---
# 3. 获取总风险指标 (Sharpe, Max Drawdown, Alpha, Beta 等)
risk_data = gt.get_risk()
if risk_data:
df_risk = pd.DataFrame([risk_data])
print("\n--- 总风险指标 ---")
print(df_risk.T) # 转置显示更清晰
# 4. 获取每日收益曲线 (时间, 策略收益, 基准收益)
results = gt.get_results()
if results:
df_results = pd.DataFrame(results)
# 设置时间为索引
df_results['time'] = pd.to_datetime(df_results['time'])
df_results.set_index('time', inplace=True)
print("\n--- 每日收益数据 (前5行) ---")
print(df_results.head())
# 5. 获取每日持仓详情 (持仓数量, 成本, 每日盈亏等)
positions = gt.get_positions()
if positions:
df_positions = pd.DataFrame(positions)
print("\n--- 持仓详情 (前5行) ---")
print(df_positions.head())
# 简单分析:查看某只股票的持仓变化
# stock_code = '000001.XSHE'
# print(df_positions[df_positions['security'] == stock_code])
# 6. 获取交易详情 (成交时间, 价格, 数量, 手续费等)
orders = gt.get_orders()
if orders:
df_orders = pd.DataFrame(orders)
print("\n--- 交易记录 (前5行) ---")
print(df_orders.head())
# 简单分析:计算总手续费
# total_commission = df_orders['commission'].sum()
# print(f"总手续费: {total_commission}")
# 7. 获取每日账户资产 (总资产, 可用资金等)
balances = gt.get_balances()
if balances:
df_balances = pd.DataFrame(balances)
print("\n--- 每日资产 (前5行) ---")
print(df_balances.head())
# 8. 获取分月风险指标
period_risks = gt.get_period_risks()
if period_risks:
# period_risks 是一个字典,键是指标名,值是 DataFrame
print("\n--- 分月收益率 (前5行) ---")
# 例如查看分月收益率
if 'algorithm_return' in period_risks:
print(period_risks['algorithm_return'].head())
3. 数据对象详解
通过 get_backtest 获取的对象(代码中的 gt),主要包含以下方法:
| 方法名 | 描述 | 返回数据关键字段 |
|---|---|---|
gt.get_risk() |
总风险指标 | algorithm_return(策略收益), alpha, beta, sharpe, max_drawdown(最大回撤), information(信息比率) 等 |
gt.get_results() |
收益曲线 | time, returns(策略累计收益), benchmark_returns(基准累计收益) |
gt.get_positions() |
持仓详情 | time, security, amount(持仓量), avg_cost(开仓均价), price(当前价), daily_gains(当日盈亏), margin(保证金) |
gt.get_orders() |
交易记录 | time, security, action(open/close), amount, price, commission(手续费), status(Filled等) |
gt.get_balances() |
每日市值 | time, cash(可用资金), total_asset(总资产) |
gt.get_records() |
自定义记录 | 获取在策略中使用 record() 函数记录的数据 |
4. 常见分析场景
获取到 DataFrame 后,你可以利用 Pandas 进行深入分析:
- 分析胜率:通过
df_orders筛选出卖出(close)操作,计算盈利次数占比。 - 持仓分布:通过
df_positions分析特定时间点的持仓集中度。 - 成本分析:统计
df_orders['commission']查看交易成本对收益的影响。 - 特定时期表现:截取
df_results中特定市场大跌的时间段,观察策略的回撤情况。
Q&A
Q: get_backtest 可以在策略代码的 initialize 或 handle_data 中使用吗?
A: 不可以。 get_backtest 是研究环境(Research)专用的 API。在策略运行过程中,你应该使用 context.portfolio 获取当前账户信息,或使用 get_trades() / get_orders() 获取当天的交易信息。
Q: 为什么 gt.get_orders() 返回的是空列表?
A: 这通常意味着该回测在运行期间没有产生任何交易,或者回测 ID 对应的策略运行失败了。请先检查 gt.get_status() 确认回测状态是否为 "done"。
Q: 如何获取模拟交易的数据?
A: get_backtest 同样适用于模拟交易。只需将模拟交易 URL 中的 backtestId 传入该函数即可获取模拟交易的历史数据。
Q: 获取的数据有延迟吗?
A: 在研究环境中获取已完成的回测数据通常没有延迟。如果是正在运行的模拟交易,数据通常是准实时的,但取决于系统同步状态。