Backtesting.py / Features

Backtesting.py 能力与边界:优化器、热力图、可视化与限制

Backtesting.py 的功能面不宽,但每一块都能直接接到研究流程上:一个回测类加一个策略基类负责执行,内置优化器做参数搜索,热力图把扫描结果摊开成二维表,可视化让交易过程可复盘,统计结果以结构化对象返回。真正需要提前想清楚的是它的边界:它面向单标的 OHLC(V) 数据,不支持多资产组合与分数股;把这几点搞混,后面所有调参都是在错误的前提下做优化。本页按「能力对照 → 优化器 → 可视化 → 结果怎么用 → 什么场景别用它」逐层拆开。

优化器:基于 SAMBO可视化:bokeh结果:Series / DataFrame
optimize参数优化
heatmap热力图
plot交互图
stats统计结果
功能特性示意(优化器 / 热力图 / 可视化 / 交易结果),基于官方 README 声明;示意非真实运行结果。
Features

Backtesting.py 能力对照:官方支持到什么程度、你要自己补什么

官方 README 列的是 Backtesting.py「有什么」;实际用起来更关键的是「它只做到哪一步、剩下哪一截要自己补」。下表按这个角度逐项拆开,判断列写的就是你真正要投入的工作。

能力官方支持到什么程度你要自己补什么注意点
回测执行(Backtest + Strategy)提供回测类与策略基类,逐 bar 推进,策略在约定方法里写逻辑策略规则、指标计算、进出场与加减仓逻辑写法与调用时机以官方文档为准;逻辑写在错误的方法里会得到「不报错但结论错」的结果
内置优化器(基于 SAMBO)官方 README 声明内置优化器,用于参数搜索参数取值范围、优化目标、样本内外切分优化目标永远是历史区间的指标,不等于未来表现
参数网格 + 热力图支持多参数组合扫描,并把结果以二维表格(热力图)返回参数区间选择,以及对「参数邻域是否稳定」的判断只盯单点较大的值容易过拟合,要看邻域是否成片
指标库无关(BYO)官方声明不绑定指标库,可用第三方库或自己算指标实现、预热期处理、与价格序列的对齐第三方指标库需另外安装;预热期不足会让前段信号失真,具体安装与接口以该库官方文档为准
交互式可视化(bokeh)官方基于 bokeh 输出可交互图表保存、分享与归档方式图依赖浏览器渲染,是给人看的复盘工具,不是数据源
交易结果结构化回测与优化都以 pandas 对象返回(统计 Series、热力图 DataFrame)二次分析、导出与版本归档字段名以实际返回为准,跨版本可能不同,不要硬编码字段做长期脚本
数据输入官方声明支持任意 OHLC(V) 蜡烛数据,一次回测对应单条价格序列取数、列名统一、时间索引对齐与质量校验不支持多资产组合与分数股,喂宽表会被当成结构异常处理
读法:第三列才是决定「Backtesting.py 能不能帮你省时间」的地方。凡是落在第三列的工作(数据准备、样本切分、结果归档),官方都不会替你做;第二列与第三列之间的落差,正是「能跑通」与「能出结论」之间的距离,也是后面几页要展开的部分。
Optimizer

Backtesting.py 内置优化器与热力图:从一次基准到整片网格

Backtesting.py 的优化流程本身不长,难的是「扫完之后怎么判断」。下面四步是可直接照做的最小路径,每步都给出代码、说明与预期结果;把策略类与参数换成你自己的即可复用。

  1. 定义一个带可调参数的策略:把要扫的窗口写成类属性,后续才能被网格覆盖。

    class SmaCross(Strategy):
        n1 = 10
        n2 = 20
    
        def init(self):
            self.s1 = self.I(SMA, self.data.Close, self.n1)
            self.s2 = self.I(SMA, self.data.Close, self.n2)

    预期:策略类可正常导入;还没跑回测,所以此时不产生任何数字。

  2. 先跑一次基准回测,拿到「不扫参数」时的水平,作为后面比较的参照。

    bt = Backtest(GOOG, SmaCross, cash=10000, commission=.002, exclusive_orders=True)
    stats = bt.run()

    预期:得到一个统计对象(Series),包含整体收益、回撤、交易次数等字段;字段名以实际返回为准。

  3. 把参数写成取值序列,交给优化器一次扫完;指定优化目标,否则它会自己挑一个默认目标。

    stats, heatmap = bt.optimize(
        n1=range(5, 30, 5),
        n2=range(20, 80, 10),
        maximize='Equity Final [$]',
        return_heatmap=True)

    预期:返回两部分——按目标排序后的较优参数统计,以及一张参数组合的热力图 DataFrame(行列是参数取值)。参数名与可选目标以官方文档为准。

  4. 先看热力图的形状,再决定要不要相信那个「较优值」:邻域成片的区域通常比孤立的高点更稳。

    heatmap

    预期:得到二维表,可转置或切片查看;若目标值在参数平面上大起大落,说明结论对区间敏感。

环节作用怎么设适用场景注意点
参数取值范围决定搜索空间大小先用粗步长框出大致区间,再局部加密参数含义明确、单调性可预期区间给得太宽会引入大量无意义组合,也让过拟合更容易
优化目标决定「什么算好」按你的研究目的选,不要默认吃系统给的目标收益导向或风险调整导向目标换了,较优参数往往也换;比较结果前先确认目标一致
参数间约束排除不合理的组合用约束条件排除逻辑上非法的组合(如快线不小于慢线)参数之间存在大小或先后关系具体写法以官方文档为准;不加约束会扫出大量无效组合
样本切分把「调参」和「验证」分开用时间段切分,先在一段上扫,再在另一段上验任何准备落地的策略同一段数据既调参又验证,等于自己给自己打分
交易成本让结果更接近现实把手续费与滑点假设写进回测,而不是事后折算换手较高的策略成本假设缺失时,参数会向「交易更频繁」的方向漂移
交易次数判断结果是否具备统计意义看扫描结果里的交易笔数,样本太少时不做结论短区间或严格信号几笔交易撑起来的较优值,换个区间通常就没了
结果归档让结论可复述把数据区间、参数网格、成本假设与较优参数一起记下来所有正式结论只记一个较优参数,过两周自己都复现不出来
基准口径避免「自说自话」用同一区间、同一成本口径算一次买入持有做参照任何要下结论的对比优化目标与基准口径不一致时,两者不可比
过拟合提醒:优化器的输出是「在所给区间上表现较好的参数」,不是「未来会更好的参数」。判断顺序建议是:先看邻域是否成片 → 再看样本外表现 → 最后才看数值高低;任何回测指标都不构成收益保证或投资建议。
Visualization

Backtesting.py 交互式可视化:图能看出什么、看不出什么

可视化基于 bokeh 输出可交互图表,它的价值在复盘与沟通,而不是替你做判断。下面先看三张卡,再看一张「能判断 / 不能说明」的对照表。

价格与买卖点

图上把价格曲线与买卖点标记叠在一起,用来快速核对「信号出现在哪里、是追高还是抄底」。它只能验证信号位置是否符合你的预期,不能证明这套信号有正期望。

权益曲线与回撤

权益曲线回答的是「账户净值怎么走的」,配合回撤区间可以看清哪一段时间在亏、亏得有多深。曲线好看不等于策略稳健,它高度依赖你选的区间。

缩放与悬停

交互式缩放与悬停查看细节,适合逐段复盘某几笔交易,也方便把图导出分享给同事讨论。换区间重跑一次,同一个策略的图形往往会明显不同,所以看图要先确认区间。注意图表依赖浏览器渲染,不应当作数据源再拿去计算。

图里的对象能判断什么不能说明什么注意点
价格与买卖点信号出现的位置与节奏是否符合设计信号是否具备正期望只对照一小段容易产生错觉,要看整段区间的分布
权益曲线净值路径、连续亏损段与修复时间策略在其他区间或标的上是否有效曲线形态对区间与初始资金敏感,换区间会变
回撤区间最深的一段亏损发生在什么时候未来的回撤上限历史回撤只是样本内的极值,不是风险承诺
单笔交易分布盈亏是否集中在少数几笔上下一次交易的结果盈利高度集中时,去掉几笔结论可能就翻转
参数热力图参数邻域是否成片、是否存在平台区这组参数在样本外同样有效颜色读数依赖优化目标,换目标后深浅含义随之改变
图表导出便于归档与团队沟通替代结构化结果用于二次计算导出方式与依赖以官方文档为准;要分析请用返回的数据对象
一句话区分:图用来「看见」,表格与结构化结果用来「计算」。把两者混用(比如照着图估数值)是最常见的低级误差来源。
Results

Backtesting.py 结果对象怎么用:统计、交易记录与净值曲线

回测与优化返回的都是 pandas 对象,意味着「拿到结果」只是开始,真正影响结论的是你怎么读它。下表按「返回什么 → 含义 → 怎么判断 → 常见误读」整理。

返回内容含义怎么判断常见误读
整体统计(回测返回值)一次回测的汇总指标集合先确认区间与成本假设,再看数值把它当成策略的固有属性;换区间数值就变
收益类指标区间内的收益水平与其年化换算与基准、与买入持有放在一起比只看数值高低,不看同期基准
回撤类指标净值从高点到低点的回撤幅度问自己能不能承受这个幅度当成对未来回撤的预测
风险调整类指标单位风险对应的收益水平(如夏普类指标)比较不同策略时,先统一区间与频率跨区间、跨频率直接比大小
交易次数与胜率样本规模与盈利交易占比先看笔数是否足够,再看胜率与盈亏比高胜率等于好策略;低胜率高盈亏比同样可能有效
逐笔交易记录每一笔的进出时间、价格与盈亏查亏损集中的时段与异常单笔顺手用未来信息解释单笔结果
净值曲线(结构化)逐 bar 的权益序列,可用于计算衍生指标做回撤、波动与相关性分析与图上曲线形状不一致时先怀疑区间与对齐
热力图 DataFrame(优化返回值)各参数组合对应的目标值找平台区而非单点高点直接取较大值当最终参数
导出后的本地文件把统计与逐笔记录落盘,便于复盘与交接与数据区间、参数、成本假设一起归档只存结果不存前提,过一阵自己都复现不了
与基准放在一起的对照判断这套规则是否真的优于「什么都不做」统一区间、统一成本后对比拿不同区间的收益直接互比,结论没有意义
口径提醒:上表描述的是各类结果的用法,具体字段名、单位与年化换算方式以官方实现与实际返回为准;结果只代表所选历史区间的表现,不构成收益保证或投资建议。
Limitations

Backtesting.py 什么场景别用它:先把不合适的排掉

选型时先做减法。下面这些需求落在它的能力边界之外,硬套会得到「能跑但不可信」的结果。

场景为什么不合适更适合的方向注意点
多资产组合与再平衡一次回测对应单条价格序列,组合级资金分配与调仓不在其能力范围内支持组合与多资产的回测框架把多标的塞进宽表不会报错,但结果不可信
分数股或极小资金下单以整股为主,小额账户的仓位会被取整规则扭曲明确支持分数股或按金额下单的方案回测里的取整偏差在小资金上占比很大
需要精细撮合或盘口逐 bar 推进的模型不模拟订单簿与撮合细节事件驱动、可自定义撮合层的框架对成交假设敏感的策略,结论会随假设大幅摆动
分钟级与高频研究可以喂更细的 bar,但成交时点与滑点假设的敏感度会急剧上升面向日内与高频的专门工具先用日线验证逻辑,再考虑是否下沉到分钟级
需要直接实盘下单定位是回测与研究,不提供交易通道对接交易接口类框架或券商 API回测结论不能直接当作实盘依据
需要内置行情数据不自带行情源(示例数据仅用于跑通流程)数据接口库或数据服务数据来源、复权口径与授权以各数据源官方文档为准
大规模参数扫描或分布式优化器在单机内存中完成扫描,组合规模受资源限制面向批量与分布的参数搜索方案先粗后细、分批运行,比一次铺开更稳
  1. 先确认标的数量。研究对象是单只标的,还是需要组合与再平衡?如果是组合,这一步就该换方案,不要往下走。

    判断标准:这次回测能不能用「一条价格序列」表达。

  2. 再确认资金与下单粒度。账户是否小到需要分数股、下单是否按整股成交?两者冲突时,取整规则会主导结论。

    判断标准:仓位计算里是否出现明显的取整偏差。

  3. 再确认成交假设的敏感度。策略是否依赖盘口、撮合细节或极短持仓周期?如果需要,逐 bar 模型给不出可信答案。

    判断标准:换一个成交价假设,结论会不会翻转。

  4. 最后确认数据与切分是否就绪。能否取到连续可用的 OHLC(V) 数据、能否切出独立的样本外区间?这两件事没准备好,前面三步都白做。

    判断标准:能否用一句话复述「数据从哪来、区间怎么切、成本怎么设」。

它真正擅长的事

把「一个想法行不行」这件事在几分钟内问出来:单标的、日线级别、逻辑清晰、可复现的规则型策略,用 Backtesting.py 验证成本极低,改完参数直接重跑。

它不替你做的事

数据准备与口径校验、样本内外切分、成本假设、结果归档,全部由你负责。这些环节缺失时,框架跑得再快也只是把错误结论算得更快。

什么时候该换工具

当需求从「验证单标的规则」扩展到「组合与多资产」,或从研究扩展到实盘,就说明这套工具已经到了边界,继续加工作流只会让维护成本上升。

边界披露:Backtesting.py 与本机技能路线之间没有已证实的集成关系,两者是相互独立的选型方向;本页只描述框架自身能力与限制,所有结论以官方 README 与官方文档为准。
FAQ

功能特性常见问题

优化器是什么算法?

官方 README 说明内置优化器基于 SAMBO(sequential model-based optimization,顺序模型优化),并对给定参数网格做搜索。算法细节、可选目标与默认行为以官方 README 与官方文档为准;本页只说明怎么用与怎么判断结果。

热力图具体怎么看?

它是一张二维表:行与列是参数取值,单元格是你指定的优化目标值,配合颜色深浅做视觉比较。判断重点不是「哪一格颜色最深」,而是较优值周围是否形成一个连续平台——平台区通常比孤立高点更可能在新数据上保持稳定。颜色深浅的含义随优化目标变化,跨目标比较前先统一口径。

为什么不做多资产组合?

Backtesting.py 的执行模型是「一条价格序列 + 逐 bar 推进」,设计上聚焦单标的规则型策略;组合级的资金分配、再平衡与跨品种对冲不在能力范围内。多资产与分数股都不支持,把多只标的拼成宽表不会报错,但结果不可信。具体限制以官方 README 与官方文档为准。

可视化能导出吗?

图表基于 bokeh,属于网页端交互图,可导出保存用于归档与分享。导出方式与依赖以官方文档为准。需要提醒的是:图是给人看的,要参与计算请使用返回的结构化对象(统计 Series、逐笔交易记录与净值序列),不要照着图估数值。

内置了行情数据吗?

没有内置行情源,官方示例数据的作用是让你先把流程跑通。正式研究要自己准备 OHLC(V) 数据,统一列名、对齐时间索引并做质量校验;数据来源、复权口径、是否收费与是否需要 Token,一律以各数据源官方文档为准。

优化器与可视化的结果能直接当作选型依据吗?

不建议。它们回答的是「在你给的区间与参数网格里,什么组合看起来更好」,而不是「这套规则值不值得投入」。把它当依据至少要补三件事:样本外区间上的表现、参数邻域是否成片、成本假设变化后结论是否稳定。三件事都过了,才轮到比较数值高低;任何回测结果都不构成收益保证或投资建议。

这些能力能替代数据与切分这些准备工作吗?

不能。优化器、可视化与结构化结果解决的是「怎么算、怎么看、怎么归档」,而数据准备、样本内外切分与成本假设仍然由你完成。本机已核验的技能路线里也有覆盖行情数据与技术分析的方向,可以省掉一部分取数工作,但两者是相互独立的路线、没有已证实集成关系,拿到的数据同样需要你自己校验口径。

能力与边界都清楚了,接着往下走

先把策略骨架与参数扫描的写法看明白,再回到安装页确认环境依赖;需要横向比较选型时,导航里的「对比」页给了两条独立路线的分工。