pmorissette/bt · MIT · v1.2.3

bt 回测库:用算法树搭多资产组合回测

bt(pmorissette/bt)是一个 2014 年起持续维护的 Python 回测库。它把一次回测拆成四类可复用算法——什么时候调仓、选哪些券、怎么分权重、怎么成交——按顺序串成一棵策略树,再喂进「日期 × 资产」的价格矩阵,输出组合收益、权重、交易与回撤统计;绩效统计与图表由 ffn 提供。它更像「组合研究框架」而不是单标的快速试算工具。

用途:多资产组合回测与策略树组合核心:Algo + AlgoStack + Strategy基于官方 README / PyPI 包实测证据

项目来源

项目页面显示约 3.0k Star / 501 fork;该数字会随社区活动变化,采集日期为 2026-09-20。

pmorissette/bt GitHub 仓库页面截图:About 描述与文件列表(约 3.0k stars / 501 forks) 查看源码与 release
老牌回测库MIT,2014 年创建,GitHub 约 3.0k stars
算法树组合调度 / 选券 / 权重 / 再平衡四类算法串成策略
最新版 v1.2.3核心迁移到 numpy 数组(2026-09-11 发布)
官方证据仓库 README / PyPI 包实测(2026-09-20 核验)
What it solves

bt 能解决什么问题?

官方 README 把它的价值写成四条:组合策略逻辑、把策略建成组合树、给交易成本建模、对比结果。翻译成研究场景就是下面四件事。

把策略拆成可复用算法

调度、选券、权重、再平衡各自是独立对象,同一套选券算法可以配上不同的权重与再平衡算法,改一个环节就能做对照实验,不必重写整个策略代码。

把多个策略装进一棵树

策略与证券可以嵌在同一棵树里,因此「先分子策略、再合并成组合」可以写成一个整体回测,而不是自己写循环拼接结果。

给交易成本建模

库内提供成本模型抽象(CostModel、SqrtCostModel、AlmgrenChrissCostModel)与佣金配置,用来观察换手与成本对绩效的影响,而不是默认「无摩擦成交」。

一次拿到多组结果

回测结果对象里同时有收益、权重、交易记录与回撤等统计(统计与图表由 ffn 提供),便于横向对比不同参数与不同组合结构。

How it works

一次回测怎么跑通?五步流程

前两步用官方 README 的合成价格示例,不需要下载任何行情数据就能验证环境是否装好;后三步才是真实研究要做的替换工作。命令与类名以官方 README 与 PyPI 包(1.2.3)为准。

RunMonthly
什么时候动手
SelectAll
动哪些标的
WeighEqually
各分多少
Rebalance
怎么成交
bt 的策略 = 算法按顺序串成的一条链:每个算法只改「当前目标权重」,Rebalance 负责把目标权重变成交易。
  1. 装环境并确认版本

    命令:pip install bt,随后 python -c "import bt; print(bt.__version__)"。预期输出:1.2.3。若报缺少 pandas,见安装页的依赖边界说明。

  2. 用合成价格跑通最小回测

    代码:README 示例——bt.Strategy("equal_weight", [RunMonthly(), SelectAll(), WeighEqually(), Rebalance()])bt.run(bt.Backtest(strategy, prices))。预期输出:result.display() 打印统计表与净值曲线。合成价格用 np.linspace 生成,无需联网取数。

  3. 换成自己的价格矩阵

    prices 换成 pd.DataFrame,行索引是 DatetimeIndex,每列一个标的的收盘价。预期:列名即标的代码,缺失日期会按索引对齐,空值会参与计算,先查数据再跑。

  4. 按研究问题组合算法

    把选券换成 SelectMomentum、权重换成 WeighInvVolWeighERC、再平衡换成 RebalanceOverTime,即可得到不同的组合行为。预期:result.stats 指标随算法组合改变。

  5. 读结果并做对照

    result.statsresult.pricesresult.weightsresult.transactions,或用 benchmark_random 做随机基准对照。预期:能回答「超额来自选券还是来自权重」这类问题。

Core concepts

bt 的四个核心概念是什么?

下面四个名字在官方 README 与包结构里都能核到(bt/__init__.py 公开导出),理解它们就理解了 bt 的写法。

概念它负责什么适用场景注意点
Algo最小动作单元,被调用时返回 True/False,用返回值决定后续算法是否继续执行想复用某段判断逻辑(如「只在月末动手」)单个算法不产生交易,只改状态或目标权重
AlgoStack把多个算法按顺序串成一个整体,前一个返回 False 就短路需要「条件不满足就跳过本次调仓」顺序写反会得到完全不同的行为,先调度后选券
Strategy一棵策略树:持有算法栈与证券/子策略,运行时按数据时间轴推进定义单个策略或嵌套子策略只写选券不写 Rebalance 不会产生交易
Backtest把策略与价格数据绑定,作为一次回测任务一个策略 × 一段数据 × 一组成本假设数据是「日期 × 标的」的收盘价矩阵
bt.run执行一个或多个 Backtest 并汇总成结果对象多策略并行对比传多个 Backtest 得到组合结果,统计口径会合并
Result结果对象:stats / prices / weights / transactions 等读指标、查交易明细、画图统计与图表由 ffn 提供,字段口径以 ffn 文档为准
Algo library

内置算法库有哪些类?

bt 1.2.3 的 bt.algos 里共 59 个算法类,按用途可以分成八组。下表每组给出代表类名与搭配方式,逐类清单见「算法库」页。

分组代表类名典型搭配注意点
调度(什么时候动手)RunOnce / RunDaily / RunWeekly / RunMonthly / RunQuarterly / RunYearly / RunPeriod放在算法链最前没有调度算法时回测不会按预期频率调仓
日历与条件触发RunOnDate / RunAfterDate / RunAfterDays / RunEveryNPeriods / RunIfOutOfBounds配合调度类使用边界条件写错会整段不调仓,建议用小样本先验证
选券(动哪些标的)SelectAll / SelectN / SelectMomentum / SelectWhere / SelectRegex / SelectHasData接在调度之后选完标的集合变了,仍需权重算法分配资金
权重(各分多少)WeighEqually / WeighSpecified / WeighTarget / WeighInvVol / WeighERC / WeighMeanVar接在选券之后权重之和与杠杆上限以库的实现为准,先看是否需要用 ScaleWeights
限额与风控LimitWeights / LimitDeltas / TargetVol放在权重之后、再平衡之前限额会改变目标权重,别和回测假设混着讲
再平衡与成交Rebalance / RebalanceOverTime / PTE_Rebalance / CapitalFlow / SetNotional算法链收尾不写再平衡算法就不会成交
逻辑与统计Require / Not / Or / SetStat / StatTotalReturn / StatMultiPeriodReturn做条件分支或记录自定义统计量统计量只在结果对象里可读,不是绩效指标本身
交易与公司行为CorporateActions / CloseDead / ClosePositionsAfterDates / RollPositionsAfterDates / ReplayTransactions需要模拟现金流与到期处理时这类算法偏进阶,先确认数据里是否有对应字段
风险与保证金UpdateRisk / PrintRisk / HedgeRisks / Margin / SimulateRFQTransactions做对冲或保证金场景v1.2.3 修复了保证金维持追缴与证券乘数相关问题,注意版本
读表方式:类名与数量取自 PyPI 包 bt 1.2.3bt/algos.py(2026-09-20 核验,共 59 个类);每个类的参数与默认值以官方文档 algos 章节为准。
Setup and route

自建 bt 回测,还是先用本机技能路线?

同一个研究问题,两条路线的准备成本差别很大:一条是把环境、数据与代码都握在自己手里,另一条是先拿到结论再决定是否值得自建。

自建 bt 回测管道

  • Python 3.9+ 环境与 pip install bt(含编译核心,轮子与 Python 版本绑定)
  • 自己准备「日期 × 标的」价格矩阵,自己处理缺失与复权
  • 自己把研究问题翻译成算法链,并解释统计口径
  • 好处:可复现、可回归测试、可写进版本管理

本机技能路线(免部署)

  • 用自然语言描述研究问题,直接拿结构化结论
  • 数据获取与出图可由本机技能完成,不必先装 Python 环境
  • 适合先判断「这个问题值不值得做成回测」
  • 边界:本机 29 个技能里没有等价于 bt 算法树 + 组合回测引擎的能力
你的当前状态建议先做理由
只有「某只标的最近怎么样」这类问题技能路线取数与指标摘要即可回答,不值得搭环境
要比较多套权重/再平衡方案自建 bt算法链正好是为「换一个环节做对照」设计的
要做多资产组合而不是单标的自建 bt价格矩阵天然是多列结构
只想验证一个想法是否值得深挖先技能路线,再自建先用一句话确认现象,再决定要不要写代码
结论要进报告或对外发布自建 bt需要可复现的代码与数据版本
没有 Python 环境也不想装技能路线本机技能免部署;但组合回测仍需自建环境
Skill demo

本机技能路线用起来怎么样?

下面两张截图来自本机对话的真实使用(左右翻页查看),用于对照自建路线「装环境 + 备数据 + 写算法链」的准备成本;它们演示的是技能路线,不是 bt 的运行结果。

bt 工作流里的环节本机技能路线能否覆盖前置条件
取历史行情(价格矩阵的原料)可以:财经数据类技能可取行情安装客户端;部分数据源需 Token 或账号
看单标的指标状态可以:技术分析类技能给指标状态覆盖范围以技能说明为准,部分仅覆盖 A 股
组合统计与图表部分:可出收益、回撤等摘要与图口径与你自建回测未必一致,比较前先对齐
算法链与再平衡执行不能替代:本机无等价引擎需要 Rebalance/WeighX 这类逐日推进的引擎
可复现与回归测试不能替代:结论需固化成代码版本管理、数据版本、成本假设都要自建
交易成本建模不能替代:成本模型属于回测引擎能力自建时用 CostModel 系列配置
怎么用这条路线:把它当研究的前半程——先用一两句话确认标的与指标的行为,再决定是否投入时间自建算法链;需要可复现结论时回到自建路线。本机技能清单与逐项边界见导航「对比」页,技能能力以各自官方说明为准。
Fit check

什么时候适合用 bt、什么时候不适合?

bt 的定位是「组合与算法复用」,不是「任何回测需求都套」。下面六条对应最常见的匹配与错配。

场景适不适合原因
多资产组合、按权重定期再平衡适合价格矩阵与权重/再平衡算法正是为这类问题准备的
想比较多套权重或再平衡规则适合换一个算法对象即可做对照实验
要模拟交易成本与换手影响适合库内提供成本模型抽象与佣金配置
单标的日内高频、逐笔撮合不适合bt 按数据行推进,不是逐笔撮合引擎
要接实盘下单不适合bt 是回测库,不提供实盘通道
只想快速看一只股票的技术指标不必用指标计算与看图有更轻的做法,自建成本更高
Troubleshooting

跑不通时先查什么?

下面六种现象覆盖了初次使用 bt 最容易卡住的地方,按「处理方式」逐条试;报错原文、依赖约束与版本差异以官方 README、文档与本地终端提示为准。

现象常见原因处理方式
No matching distribution found for btPython 版本或平台没有对应轮子确认 Python ≥3.9(官方 classifier 覆盖 3.9–3.13),或改用源码安装并准备编译工具链
ModuleNotFoundError: No module named 'pandas'bt 的运行时依赖里没有直接写 pandas显式安装 pandas / numpy(它们经 ffn 进入依赖链,环境不完整时会缺)
回测跑完没有任何交易算法链里没写再平衡算法在链尾补 Rebalance()(或用 RebalanceOverTime 分步成交)
结果与预期差很远算法顺序写反,或权重算法没接在选券之后按「调度 → 选券 → 权重 → 再平衡」顺序检查,必要时先插 Debug / PrintInfo 看中间状态
净值曲线有异常跳变价格矩阵有空值、重复索引或货币不一致先检查 DataFrame 索引是否 DatetimeIndex、是否有 NaN 与重复日期
统计口径与自己的算法对不上绩效统计由 ffn 计算,口径与自算不同以 ffn 文档为准,或自行用 prices 序列复算并注明口径
FAQ

bt 常见问题

bt 是免费的吗?可以商用吗?

bt 采用 MIT 许可(PyPI 包元数据与仓库 LICENSE 均标注 MIT),可自由使用与修改;具体使用仍以仓库 LICENSE 原文为准。使用时请自行确认第三方数据源的授权范围。

bt 支持哪些 Python 版本?

包元数据 Requires-Python >=3.9,分类器覆盖 3.9 / 3.10 / 3.11 / 3.12 / 3.13。实测下载到的是与解释器和平台绑定的编译轮子(如 cp311-win_amd64),装到没有轮子的环境会走源码构建分支,需自备编译工具链。

能回测 A 股 / 港股 / 美股吗?

bt 本身不提供行情,只要你能把数据整理成「日期 × 标的」的收盘价矩阵,市场不受限制。数据来源与复权口径需自己解决;本机技能路线里的财经数据类技能可以取到部分市场行情,但覆盖面以各技能说明为准。

bt 能实盘交易吗?

不能。bt 是回测库,不包含实盘通道与风控执行;它输出的是回测结果统计。若目标是实盘,需要另外接入交易接口,并自行承担全部风险。

bt 和 backtesting.py 有什么区别?

两者的抽象方向不同:backtesting.py 面向单标的策略,用 Strategy.init/next 两个方法描述逐根 K 线的行为;bt 面向多资产组合,把「调度 / 选券 / 权重 / 再平衡」拆成可复用算法串成策略树。选哪个取决于你要做单标的研究还是组合研究,具体能力以各自官方文档为准。

回测结果能当作收益预期吗?

不能。官方 README 明确写了「回测结果依赖数据质量与建模假设,不预测未来表现」。本站所有示例都只用于说明用法,不构成投资建议。

下一步:你的研究目标是什么?

要自建可复现的 Python 回测管道,从安装与首次运行开始;想先用一句话问清研究问题、再决定是否自建,可参考本站的技能路线。