功能

交互式图表

通过 Plotly 绘制回测、蜡烛、指标、信号和参数热图

如何看清策略实际做了什么?VBT 在 Python 中将回测、价格、指标、信号和参数结果绘制为交互式 Plotly 图表:放大查看单笔交易,悬停读取准确数值,并将任意图表组合在一张图中。

Plot a backtest with orders, trade P&L, a custom RSI panel, and drawdowns
data = vbt.YFData.pull("BTC-USD", start="2023-01-01", end="2024-01-01")
rsi = data.run("rsi", window=14).rsi
pf = vbt.PF.from_signals(data, rsi.vbt.crossed_below(30), rsi.vbt.crossed_above(70))

def plot_rsi(pf, rsi, add_trace_kwargs=None, fig=None):  
    rsi.rename("RSI").vbt.plot(add_trace_kwargs=add_trace_kwargs, fig=fig)

pf.plot(
    subplots=[
        "orders",
        "trade_pnl",
        ("rsi", dict(title="RSI", plot_func=plot_rsi, rsi=rsi)),
        "drawdowns",
    ],
    settings=dict(bm_returns=False),
).show()
2023 年比特币 RSI 策略图,包含买卖订单、交易盈亏、RSI 指标和回撤 图表数据(JSON)

投资组合与交易图表

pf.plot() 根据具名子图绘制仪表盘。内置子图包括 orders、trades、trade_pnl、trade_signals、cumulative_returns、drawdowns、underwater、gross_exposure、allocations、cash、assets 和 value,每个都可通过 subplot_settings 配置。每个子图也有独立方法,例如 pf.plot_cumulative_returns()、pf.plot_underwater(),以及展示多资产权重随时间变化的 pf.plot_allocations()。

记录也能自行绘图:pf.trades.plot() 显示每笔交易从入场到退出的过程及其利润,pf.drawdowns.plot(top_n=5) 则突出显示最大回撤。对于收益,一行代码就能绘制月收益日历热图:pf.returns_acc.resample("M").ts_heatmap()。

价格、指标和信号图表

数据对象可绘制带成交量的蜡烛图或 OHLC 图。通过传入 fig,可将指标和信号添加到同一张图中:

Overlay moving averages and crossover signals on candlesticks
sub = data.loc["2023-04-01":"2023-08-31"]
fast = sub.close.rolling(10).mean()
slow = sub.close.rolling(30).mean()
entries = fast.vbt.crossed_above(slow)
exits = fast.vbt.crossed_below(slow)

fig = sub.plot(plot_volume=False)
fast.rename("SMA 10").vbt.plot(fig=fig)
slow.rename("SMA 30").vbt.plot(fig=fig)
entries.vbt.signals.plot_as_entries(fast, fig=fig)  
exits.vbt.signals.plot_as_exits(fast, fig=fig)
fig.show()
2023 年 4 至 8 月比特币蜡烛图,包含 10 天和 30 天均线,以及交叉入场和退出标记 图表数据(JSON)

使用 VBT 构建的指标具有默认设置合理的 plot 方法,TA-Lib 指标则根据输出类型绘图,例如折线图或直方图。

热图及其他通用图表

任意 Series 或 DataFrame 都能通过访问器获得绘图方法:折线、散点、柱状、直方、箱线、热图和三维体积图。三个参数组成的参数网格可以转换为热图,并用滑块控制第三个参数:

Explore three RSI strategy parameters with a heatmap and a slider
btc = vbt.YFData.pull("BTC-USD", start="2020-01-01", end="2025-01-01")
rsi = btc.run("rsi", window=14).rsi

@vbt.parameterized(merge_func="concat")  
def sharpe(lower, upper, sl_stop):
    pf = vbt.PF.from_signals(
        btc,
        rsi.vbt.crossed_below(lower),
        rsi.vbt.crossed_above(upper),
        sl_stop=sl_stop,
    )
    return pf.sharpe_ratio

sharpes = sharpe(
    vbt.Param([20, 25, 30, 35, 40]),
    vbt.Param([60, 65, 70, 75, 80]),
    vbt.Param([0.05, 0.1, 0.2]),
)
sharpes.vbt.heatmap(x_level="lower", y_level="upper", slider_level="sl_stop").show()
RSI 入场和退出阈值的夏普比率热图,使用滑块控制止损水平 图表数据(JSON)

如果 Plotly Express 中有您需要的图表,可从访问器调用,例如 df.vbt.px.parallel_coordinates()。交叉验证切分也有自己的图表,展示每次切分的训练和测试区间。

自定义

每种绘图方法都接受用于轨迹的 trace_kwargs、用于将轨迹放入子图的 add_trace_kwargs,以及图形布局关键词。例如,slow.vbt.plot(trace_kwargs=dict(line=dict(color="orange", dash="dash")), fig=fig) 绘制一条橙色虚线。vbt.make_subplots 创建多面板图形;由于结果是标准 Plotly 图形,之后仍可使用 Plotly 的全部功能。

主题和默认设置位于 vbt.settings.plotting,例如使用 vbt.settings.set_theme("dark") 创建深色图表。对于夜间或周末休市的市场,fig.auto_rangebreaks(freq="1D") 会为缺失时间添加 Plotly 范围断点,让蜡烛相邻排列,而非留出空隙。

随新数据更新的图表

您可以在保留布局和样式的同时,更新现有 Plotly 轨迹中的数据。将更新连接到 DataUpdater,即可在新 K 线到来时刷新蜡烛图,或在 notebook 小部件中更新价格和指标曲线。这适合持续观察序列最新部分,无需每次创建新图。

数据流水线介绍定时数据更新,实时模拟介绍如何在新 K 线上继续运行投资组合。还可使用 imageio 将连续图表图像保存为 GIF 帧,回放图表的变化过程。

大数据与输出

跨越数年的分钟图包含数百万个数据点,浏览器绘制较慢。安装 plotly-resampler 后,设置 vbt.settings.plotting["use_resampler"] = True,图表将加载降采样视图,并随缩放逐步细化。也可以先选择较短区间再绘图,或先对投资组合重采样:pf.resample("1D") 返回总收益相同的日频投资组合,其图表每天绘制一个点。

分享交互式图表与导出图像

使用 fig.show() 在 notebook 和浏览器中交互显示图形,使用 fig.show_png() 或 fig.show_svg() 显示静态图像,并通过 fig.write_image() 或 fig.write_html() 保存文件。静态图像由 Plotly 的 kaleido 包渲染,因此请先安装;如果导出卡住,请更新它。渲染器既可为单张图设置,也可全局设置。

HTML 导出保留缩放、悬停标签和图例控制,让其他人无需安装 Python 或 VBT,也能在浏览器中探索结果。默认情况下,Plotly 会将图表数据及其 JavaScript 库包含在文件中。如何保存图形或将多张图组合在一个页面,请参阅 Plotly HTML 导出指南。报告或演示需要固定图像时,请使用 PNG 或 SVG。

版权所有 © 2021–2026 Oleg Polakow。保留所有权利。

本站内容与文档供使用和评估 VectorBT PRO 以及教育用途。任何其他用途,包括开发或支持竞争产品或服务,均须事先取得书面同意。