价格与买卖点
图上把价格曲线与买卖点标记叠在一起,用来快速核对「信号出现在哪里、是追高还是抄底」。它只能验证信号位置是否符合你的预期,不能证明这套信号有正期望。
Backtesting.py / Features
Backtesting.py 的功能面不宽,但每一块都能直接接到研究流程上:一个回测类加一个策略基类负责执行,内置优化器做参数搜索,热力图把扫描结果摊开成二维表,可视化让交易过程可复盘,统计结果以结构化对象返回。真正需要提前想清楚的是它的边界:它面向单标的 OHLC(V) 数据,不支持多资产组合与分数股;把这几点搞混,后面所有调参都是在错误的前提下做优化。本页按「能力对照 → 优化器 → 可视化 → 结果怎么用 → 什么场景别用它」逐层拆开。
官方 README 列的是 Backtesting.py「有什么」;实际用起来更关键的是「它只做到哪一步、剩下哪一截要自己补」。下表按这个角度逐项拆开,判断列写的就是你真正要投入的工作。
| 能力 | 官方支持到什么程度 | 你要自己补什么 | 注意点 |
|---|---|---|---|
| 回测执行(Backtest + Strategy) | 提供回测类与策略基类,逐 bar 推进,策略在约定方法里写逻辑 | 策略规则、指标计算、进出场与加减仓逻辑 | 写法与调用时机以官方文档为准;逻辑写在错误的方法里会得到「不报错但结论错」的结果 |
| 内置优化器(基于 SAMBO) | 官方 README 声明内置优化器,用于参数搜索 | 参数取值范围、优化目标、样本内外切分 | 优化目标永远是历史区间的指标,不等于未来表现 |
| 参数网格 + 热力图 | 支持多参数组合扫描,并把结果以二维表格(热力图)返回 | 参数区间选择,以及对「参数邻域是否稳定」的判断 | 只盯单点较大的值容易过拟合,要看邻域是否成片 |
| 指标库无关(BYO) | 官方声明不绑定指标库,可用第三方库或自己算 | 指标实现、预热期处理、与价格序列的对齐 | 第三方指标库需另外安装;预热期不足会让前段信号失真,具体安装与接口以该库官方文档为准 |
| 交互式可视化(bokeh) | 官方基于 bokeh 输出可交互图表 | 保存、分享与归档方式 | 图依赖浏览器渲染,是给人看的复盘工具,不是数据源 |
| 交易结果结构化 | 回测与优化都以 pandas 对象返回(统计 Series、热力图 DataFrame) | 二次分析、导出与版本归档 | 字段名以实际返回为准,跨版本可能不同,不要硬编码字段做长期脚本 |
| 数据输入 | 官方声明支持任意 OHLC(V) 蜡烛数据,一次回测对应单条价格序列 | 取数、列名统一、时间索引对齐与质量校验 | 不支持多资产组合与分数股,喂宽表会被当成结构异常处理 |
Backtesting.py 的优化流程本身不长,难的是「扫完之后怎么判断」。下面四步是可直接照做的最小路径,每步都给出代码、说明与预期结果;把策略类与参数换成你自己的即可复用。
定义一个带可调参数的策略:把要扫的窗口写成类属性,后续才能被网格覆盖。
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)
预期:策略类可正常导入;还没跑回测,所以此时不产生任何数字。
先跑一次基准回测,拿到「不扫参数」时的水平,作为后面比较的参照。
bt = Backtest(GOOG, SmaCross, cash=10000, commission=.002, exclusive_orders=True) stats = bt.run()
预期:得到一个统计对象(Series),包含整体收益、回撤、交易次数等字段;字段名以实际返回为准。
把参数写成取值序列,交给优化器一次扫完;指定优化目标,否则它会自己挑一个默认目标。
stats, heatmap = bt.optimize(
n1=range(5, 30, 5),
n2=range(20, 80, 10),
maximize='Equity Final [$]',
return_heatmap=True)
预期:返回两部分——按目标排序后的较优参数统计,以及一张参数组合的热力图 DataFrame(行列是参数取值)。参数名与可选目标以官方文档为准。
先看热力图的形状,再决定要不要相信那个「较优值」:邻域成片的区域通常比孤立的高点更稳。
heatmap
预期:得到二维表,可转置或切片查看;若目标值在参数平面上大起大落,说明结论对区间敏感。
| 环节 | 作用 | 怎么设 | 适用场景 | 注意点 |
|---|---|---|---|---|
| 参数取值范围 | 决定搜索空间大小 | 先用粗步长框出大致区间,再局部加密 | 参数含义明确、单调性可预期 | 区间给得太宽会引入大量无意义组合,也让过拟合更容易 |
| 优化目标 | 决定「什么算好」 | 按你的研究目的选,不要默认吃系统给的目标 | 收益导向或风险调整导向 | 目标换了,较优参数往往也换;比较结果前先确认目标一致 |
| 参数间约束 | 排除不合理的组合 | 用约束条件排除逻辑上非法的组合(如快线不小于慢线) | 参数之间存在大小或先后关系 | 具体写法以官方文档为准;不加约束会扫出大量无效组合 |
| 样本切分 | 把「调参」和「验证」分开 | 用时间段切分,先在一段上扫,再在另一段上验 | 任何准备落地的策略 | 同一段数据既调参又验证,等于自己给自己打分 |
| 交易成本 | 让结果更接近现实 | 把手续费与滑点假设写进回测,而不是事后折算 | 换手较高的策略 | 成本假设缺失时,参数会向「交易更频繁」的方向漂移 |
| 交易次数 | 判断结果是否具备统计意义 | 看扫描结果里的交易笔数,样本太少时不做结论 | 短区间或严格信号 | 几笔交易撑起来的较优值,换个区间通常就没了 |
| 结果归档 | 让结论可复述 | 把数据区间、参数网格、成本假设与较优参数一起记下来 | 所有正式结论 | 只记一个较优参数,过两周自己都复现不出来 |
| 基准口径 | 避免「自说自话」 | 用同一区间、同一成本口径算一次买入持有做参照 | 任何要下结论的对比 | 优化目标与基准口径不一致时,两者不可比 |
可视化基于 bokeh 输出可交互图表,它的价值在复盘与沟通,而不是替你做判断。下面先看三张卡,再看一张「能判断 / 不能说明」的对照表。
图上把价格曲线与买卖点标记叠在一起,用来快速核对「信号出现在哪里、是追高还是抄底」。它只能验证信号位置是否符合你的预期,不能证明这套信号有正期望。
权益曲线回答的是「账户净值怎么走的」,配合回撤区间可以看清哪一段时间在亏、亏得有多深。曲线好看不等于策略稳健,它高度依赖你选的区间。
交互式缩放与悬停查看细节,适合逐段复盘某几笔交易,也方便把图导出分享给同事讨论。换区间重跑一次,同一个策略的图形往往会明显不同,所以看图要先确认区间。注意图表依赖浏览器渲染,不应当作数据源再拿去计算。
| 图里的对象 | 能判断什么 | 不能说明什么 | 注意点 |
|---|---|---|---|
| 价格与买卖点 | 信号出现的位置与节奏是否符合设计 | 信号是否具备正期望 | 只对照一小段容易产生错觉,要看整段区间的分布 |
| 权益曲线 | 净值路径、连续亏损段与修复时间 | 策略在其他区间或标的上是否有效 | 曲线形态对区间与初始资金敏感,换区间会变 |
| 回撤区间 | 最深的一段亏损发生在什么时候 | 未来的回撤上限 | 历史回撤只是样本内的极值,不是风险承诺 |
| 单笔交易分布 | 盈亏是否集中在少数几笔上 | 下一次交易的结果 | 盈利高度集中时,去掉几笔结论可能就翻转 |
| 参数热力图 | 参数邻域是否成片、是否存在平台区 | 这组参数在样本外同样有效 | 颜色读数依赖优化目标,换目标后深浅含义随之改变 |
| 图表导出 | 便于归档与团队沟通 | 替代结构化结果用于二次计算 | 导出方式与依赖以官方文档为准;要分析请用返回的数据对象 |
回测与优化返回的都是 pandas 对象,意味着「拿到结果」只是开始,真正影响结论的是你怎么读它。下表按「返回什么 → 含义 → 怎么判断 → 常见误读」整理。
| 返回内容 | 含义 | 怎么判断 | 常见误读 |
|---|---|---|---|
| 整体统计(回测返回值) | 一次回测的汇总指标集合 | 先确认区间与成本假设,再看数值 | 把它当成策略的固有属性;换区间数值就变 |
| 收益类指标 | 区间内的收益水平与其年化换算 | 与基准、与买入持有放在一起比 | 只看数值高低,不看同期基准 |
| 回撤类指标 | 净值从高点到低点的回撤幅度 | 问自己能不能承受这个幅度 | 当成对未来回撤的预测 |
| 风险调整类指标 | 单位风险对应的收益水平(如夏普类指标) | 比较不同策略时,先统一区间与频率 | 跨区间、跨频率直接比大小 |
| 交易次数与胜率 | 样本规模与盈利交易占比 | 先看笔数是否足够,再看胜率与盈亏比 | 高胜率等于好策略;低胜率高盈亏比同样可能有效 |
| 逐笔交易记录 | 每一笔的进出时间、价格与盈亏 | 查亏损集中的时段与异常单笔 | 顺手用未来信息解释单笔结果 |
| 净值曲线(结构化) | 逐 bar 的权益序列,可用于计算衍生指标 | 做回撤、波动与相关性分析 | 与图上曲线形状不一致时先怀疑区间与对齐 |
| 热力图 DataFrame(优化返回值) | 各参数组合对应的目标值 | 找平台区而非单点高点 | 直接取较大值当最终参数 |
| 导出后的本地文件 | 把统计与逐笔记录落盘,便于复盘与交接 | 与数据区间、参数、成本假设一起归档 | 只存结果不存前提,过一阵自己都复现不了 |
| 与基准放在一起的对照 | 判断这套规则是否真的优于「什么都不做」 | 统一区间、统一成本后对比 | 拿不同区间的收益直接互比,结论没有意义 |
选型时先做减法。下面这些需求落在它的能力边界之外,硬套会得到「能跑但不可信」的结果。
| 场景 | 为什么不合适 | 更适合的方向 | 注意点 |
|---|---|---|---|
| 多资产组合与再平衡 | 一次回测对应单条价格序列,组合级资金分配与调仓不在其能力范围内 | 支持组合与多资产的回测框架 | 把多标的塞进宽表不会报错,但结果不可信 |
| 分数股或极小资金 | 下单以整股为主,小额账户的仓位会被取整规则扭曲 | 明确支持分数股或按金额下单的方案 | 回测里的取整偏差在小资金上占比很大 |
| 需要精细撮合或盘口 | 逐 bar 推进的模型不模拟订单簿与撮合细节 | 事件驱动、可自定义撮合层的框架 | 对成交假设敏感的策略,结论会随假设大幅摆动 |
| 分钟级与高频研究 | 可以喂更细的 bar,但成交时点与滑点假设的敏感度会急剧上升 | 面向日内与高频的专门工具 | 先用日线验证逻辑,再考虑是否下沉到分钟级 |
| 需要直接实盘下单 | 定位是回测与研究,不提供交易通道对接 | 交易接口类框架或券商 API | 回测结论不能直接当作实盘依据 |
| 需要内置行情数据 | 不自带行情源(示例数据仅用于跑通流程) | 数据接口库或数据服务 | 数据来源、复权口径与授权以各数据源官方文档为准 |
| 大规模参数扫描或分布式 | 优化器在单机内存中完成扫描,组合规模受资源限制 | 面向批量与分布的参数搜索方案 | 先粗后细、分批运行,比一次铺开更稳 |
先确认标的数量。研究对象是单只标的,还是需要组合与再平衡?如果是组合,这一步就该换方案,不要往下走。
判断标准:这次回测能不能用「一条价格序列」表达。
再确认资金与下单粒度。账户是否小到需要分数股、下单是否按整股成交?两者冲突时,取整规则会主导结论。
判断标准:仓位计算里是否出现明显的取整偏差。
再确认成交假设的敏感度。策略是否依赖盘口、撮合细节或极短持仓周期?如果需要,逐 bar 模型给不出可信答案。
判断标准:换一个成交价假设,结论会不会翻转。
最后确认数据与切分是否就绪。能否取到连续可用的 OHLC(V) 数据、能否切出独立的样本外区间?这两件事没准备好,前面三步都白做。
判断标准:能否用一句话复述「数据从哪来、区间怎么切、成本怎么设」。
把「一个想法行不行」这件事在几分钟内问出来:单标的、日线级别、逻辑清晰、可复现的规则型策略,用 Backtesting.py 验证成本极低,改完参数直接重跑。
数据准备与口径校验、样本内外切分、成本假设、结果归档,全部由你负责。这些环节缺失时,框架跑得再快也只是把错误结论算得更快。
当需求从「验证单标的规则」扩展到「组合与多资产」,或从研究扩展到实盘,就说明这套工具已经到了边界,继续加工作流只会让维护成本上升。
官方 README 说明内置优化器基于 SAMBO(sequential model-based optimization,顺序模型优化),并对给定参数网格做搜索。算法细节、可选目标与默认行为以官方 README 与官方文档为准;本页只说明怎么用与怎么判断结果。
它是一张二维表:行与列是参数取值,单元格是你指定的优化目标值,配合颜色深浅做视觉比较。判断重点不是「哪一格颜色最深」,而是较优值周围是否形成一个连续平台——平台区通常比孤立高点更可能在新数据上保持稳定。颜色深浅的含义随优化目标变化,跨目标比较前先统一口径。
Backtesting.py 的执行模型是「一条价格序列 + 逐 bar 推进」,设计上聚焦单标的规则型策略;组合级的资金分配、再平衡与跨品种对冲不在能力范围内。多资产与分数股都不支持,把多只标的拼成宽表不会报错,但结果不可信。具体限制以官方 README 与官方文档为准。
图表基于 bokeh,属于网页端交互图,可导出保存用于归档与分享。导出方式与依赖以官方文档为准。需要提醒的是:图是给人看的,要参与计算请使用返回的结构化对象(统计 Series、逐笔交易记录与净值序列),不要照着图估数值。
没有内置行情源,官方示例数据的作用是让你先把流程跑通。正式研究要自己准备 OHLC(V) 数据,统一列名、对齐时间索引并做质量校验;数据来源、复权口径、是否收费与是否需要 Token,一律以各数据源官方文档为准。
不建议。它们回答的是「在你给的区间与参数网格里,什么组合看起来更好」,而不是「这套规则值不值得投入」。把它当依据至少要补三件事:样本外区间上的表现、参数邻域是否成片、成本假设变化后结论是否稳定。三件事都过了,才轮到比较数值高低;任何回测结果都不构成收益保证或投资建议。
不能。优化器、可视化与结构化结果解决的是「怎么算、怎么看、怎么归档」,而数据准备、样本内外切分与成本假设仍然由你完成。本机已核验的技能路线里也有覆盖行情数据与技术分析的方向,可以省掉一部分取数工作,但两者是相互独立的路线、没有已证实集成关系,拿到的数据同样需要你自己校验口径。