解读 Bokeh 报告

Backtest.plot()(以及 TradingEnv.plot())渲染一份交互式 Bokeh 报告,包含净值、交易收益、按资产分的 OHLC 面板。本页解释每个面板展示什么、怎么读。

保存到文件

默认情况下 plot() 调用 bokeh.io.show() 在浏览器打开报告。如需保存为自包含 HTML 文件用于分享或存档:

from qtrade.utils.plot_bokeh import plot_with_bokeh
plot_with_bokeh(bt.broker, filename="report.html")

HTML 内联所有数据 —— 不需要 Bokeh 服务器、没有外部资源。可以邮件发送、提交进 git、放进 wiki。

单资产布局

三个 X 轴联动的纵向堆叠面板:

┌─────────────────────────────────────────────────┐
│ ▒▓▒  Equity vs. Buy & Hold (cumulative returns) │
│                                                 │
├─────────────────────────────────────────────────┤
│ ▲ ▼ ▲       Trade returns (long / short)        │
├─────────────────────────────────────────────────┤
│       OHLC + volume + win/lose trade boxes      │
│       + buy/sell markers                        │
│                                                 │
└─────────────────────────────────────────────────┘

顶部:净值面板

  • 蓝色实线:组合净值(累计收益,起点归一化为 1.0)。

  • 灰色虚线:同尺度下的 Buy & Hold 收益。

  • 紫色点:净值峰值点。

  • 蓝色点:最终净值点(图例显示最终百分比)。

  • 灰色点:最终 Buy & Hold 点。

  • 红色点:最大回撤的谷底。

  • 红色阴影区:回撤区域(净值与其滚动最大值的差距)。

  • 红色水平线段:最长回撤持续时间。

重点观察:

  • 蓝线是否在灰线之上?是的话你跑赢 Buy & Hold。

  • 蓝线 vs 灰线哪个更「平滑」?更平滑 = 波动率更低 = 风险调整后收益更好(即 Sharpe)。

  • 红色阴影区集中在某段时间还是分散?集中 = 策略在某个 regime 失效;分散 = 系统性拖累。

中部:交易收益

每笔已平仓交易绘制在其平仓时间点的散点图:

  • 绿色向上三角:多头交易。Y 轴是 (exit/entry 1)

  • 红色向下三角:空头交易。Y 轴是对应空头的等价表达式。

  • 标记大小:按仓位 size 缩放(越大 = 仓位越大)。

  • 0 处的水平虚线:盈亏平衡线。

重点观察:

  • 大多数标记是否在 0 线之上?这就是肉眼估算的胜率。

  • 是否有一簇深亏(远低于 0)?那里就是止损(或缺少止损)出问题的地方。

  • 大赢家和大输家围绕 0 是否对称?非对称才好 —— 小亏 + 大赚是趋势跟随的甜区。

底部:OHLC + 成交量 + 交易框

价格走势叠加多种标记:

  • 黑线:收盘价。

  • 底部柱状(淡绿 / 淡红):成交量(右 Y 轴),按 close ≥/< open 着色。

  • 半透明绿色矩形:盈利交易 —— 左右边是开仓 / 平仓时间,上下边是开仓 / 平仓价格。

  • 半透明红色矩形:亏损交易,约定相同。

  • 三角标记:订单成交。向上 = 买;向下 = 卖。大小按订单规模缩放。

重点观察:

  • 横跨很长水平区间的交易框 = 你扛过了噪声。短区间 = 快进快出。

  • 买点在局部高点 / 卖点在局部低点 = 时机不好,可能是信号生成滞后。

  • 交易框密集堆叠 = 高换手。注意 show_stats() 中的 Total Commission Cost 指标。

多资产布局

报告为每个资产添加一个 OHLC 面板,全部堆叠并共享同一 X 轴:

┌─────────────────────────────────────────────────┐
│  Portfolio equity vs equal-weighted Buy & Hold  │
├─────────────────────────────────────────────────┤
│  Trade returns scatter (all assets combined)    │
├─────────────────────────────────────────────────┤
│  OHLC — AAPL                                    │
├─────────────────────────────────────────────────┤
│  OHLC — MSFT                                    │
├─────────────────────────────────────────────────┤
│  OHLC — NVDA                                    │
└─────────────────────────────────────────────────┘

每个资产的 OHLC 面板只显示该资产的交易和订单,所以你能精确看到策略在每个标的上的动作。顶部净值面板是组合级别的(一条曲线,跨资产汇总)。

Buy & Hold 基准是各资产首尾收益的等权平均 —— 一个公平的「朴素组合」对照。

交互特性

  • 在任意面板拖动 X 轴平移;滚轮缩放。

  • 点击图例项切换该系列显示 / 隐藏。

  • 悬停显示 tooltip:日期、价格、收益、单笔盈亏。

  • 自动缩放:缩放 X 轴会触发 JS 回调,只对可见范围重新缩放 Y 轴(单资产布局下)。

常见困惑

  • 交易收益散点图是空的:策略还没平仓。SL/TP 未触发 + 没有信号平仓 = 没有平仓交易。

  • OHLC 末端有一段没有买卖标记close_all_positions() 在结束时的统一清仓使用最后一根 bar 的 close 价记录退出,可能在右边缘产生一堆密集标记。

  • 没有成交量:你的输入数据没有 Volume 列。加一列(或接受没有成交量条)。

  • 净值线骤降但看不到对应交易:你扛了一笔很大的浮亏但没平仓。检查策略逻辑里的 unrealized_pnl