# bt

Python backtesting for allocation and rebalancing rules, not entries and exits.

*https://stockmarketstack.com/tools/bt · Backtesting Frameworks & Algo Trading Libraries*

## Facts

### At a glance

| Field | Value |
| --- | --- |
| Vendor | Philippe Morissette |
| Category | Backtesting Frameworks & Algo Trading Libraries |
| Job | backtesting |
| Website | https://github.com/pmorissette/bt |
| Pricing model | open-source |
| Free tier | true |
| Open source | true |
| Licence | MIT |
| Self-hosted | true |
| Tested hands-on | false |
| Last updated | 2026-09-13 |

### Coverage

| Field | Value |
| --- | --- |
| Asset classes | stocks, etf, bonds, futures |
| Markets | global |
| Works outside the US | true |
| Data latency | none |
| Platforms | library |
| AI features | none |

### Interfaces

| Field | Value |
| --- | --- |
| API | false |
| Webhooks | false |
| Scripting | Python |
| Python | true |
| Spreadsheet add-in | false |
| MCP server | false |
| Export | csv |

### Capabilities

Yes: backtesting

No: charting, screening, scanning, automation, live_trading, paper_trading, portfolio_tracking, broker_import, tax_reporting, alerts, news, options_analysis

*Verified: pricing 2026-09-13; capabilities 2026-09-13; coverage 2026-09-13.*

## What it is

bt takes a pandas DataFrame of prices and a `Strategy` built from an ordered list of algos —
`RunMonthly()`, `SelectAll()`, `WeighEqually()`, `Rebalance()` is the canonical four-liner — and
walks the index one row at a time, tracking positions, transactions and costs.

The distinction that decides whether this is your tool: bt tests allocation rules, not entries
and exits. The fifty-odd algos that ship are scheduling (`RunDaily` through `RunYearly`,
`RunIfOutOfBounds`), selection (`SelectMomentum`, `SelectWhere`) and weighting (`WeighInvVol`,
`WeighERC`, `WeighMeanVar`, `TargetVol`). Nothing addresses a stop, a limit order or a trade
lifecycle. If the question is whether a momentum tilt beats 60/40 after costs, bt is built for
it; if it is whether a five-minute breakout fills, it is the wrong library.

Strategies nest: a child is priced by running it on a notional $1,000,000 and handing its price
series to the parent, so a portfolio of strategies is the same object as a portfolio of
securities.

## Pricing

Free, MIT-licensed, nothing to buy: no pro build, no hosted tier, no data bundle.
`pip install bt` is the entire product.

## Data & coverage

bt ships no market data. The only bundled fetcher is `bt.get`, re-exported from ffn, which pulls
Yahoo Finance adjusted close via yfinance; everything else you load yourself, from a CSV or a
[market data API](https://stockmarketstack.com/categories/market-data-apis). Instrument modelling is specific rather than
generic: `Security` for equities and ETFs, `CouponPayingSecurity` and `FixedIncomeStrategy` for bonds,
per-security multipliers and a `Margin` algo for futures. Markets are whatever your price series
covers.

## Integrations

ffn is the companion library by the same author, and the coupling is tight: bt depends on
`ffn>=1.1.2`, `bt.Result` subclasses `ffn.GroupStats`, and the stats table, the plots and
`to_csv` come from there. Python 3.9 or newer, with `core.py` cythonized and shipped as platform
wheels. Repository state on 13 September 2026: release v1.2.3 on 11 September, last commit to
master on 12 September, not archived, 13 open issues.

## Limitations

- No live trading and no broker. Nothing in the source routes an order.
- One price per row: a fill happens at the bar's price, with no intrabar sequencing. A bid/offer
  spread is modelled only if you hand the backtest a `bidoffer` frame alongside the prices, in
  which case half the spread is charged on each trade; otherwise slippage is whatever cost model
  you supply.
- No options — no pricing model, no greeks, no chain handling.
- Positions are integers by default, which quietly skips allocations a small account could not
  fill; fractional shares need `integer_positions=False`.
- PyPI still classifies it Development Status :: 4 - Beta after twelve years.

## Alternatives

backtrader and [Backtesting.py](https://stockmarketstack.com/tools/backtesting-py) for event-driven, signal-level testing; vectorbt where speed over
large parameter sweeps matters more than portfolio structure. For the statistics without the
simulation, ffn alone is the smaller dependency.

## FAQ

### Is bt still maintained?

Yes, and unusually actively for a twelve-year-old library. Version 1.2.3 shipped on 11 September 2026, the last commit to master landed 12 September 2026, and the repository is not archived. The 1.2.1 release alone merged a dozen pull requests from seven first-time contributors, so issues are being answered by more than one person.

### Can bt trade live or connect to a broker?

No. There is no broker integration, no order routing and no live loop anywhere in the source — the words broker and live trading do not appear in it. The internal paper-trade flag is not a broker paper account; it is how a nested child strategy is priced, by running it on a notional one million dollars.

### What data does bt need, and does it come with any?

It needs a pandas DataFrame of prices indexed by date. The only bundled fetcher is bt.get, an alias for ffn.get, which downloads Yahoo Finance adjusted close through yfinance. Any other source you load yourself, and the framework does not care which.

### How is bt different from backtrader or Backtesting.py?

Those model a trade lifecycle — signal, order, fill, stop. bt models a weight vector — which securities to hold, at what weights, rebalanced on what schedule. If your strategy is expressed as a target allocation rather than an entry and an exit, bt fits it directly and the others make you simulate it.

## Also from Philippe Morissette

- [ffn](https://stockmarketstack.com/tools/ffn.md)

## Also worth comparing

- [Backtesting.py](https://stockmarketstack.com/tools/backtesting-py.md) — A single-instrument Python backtester — one OHLC series, one strategy, no live trading.
- [Backtrader](https://stockmarketstack.com/tools/backtrader.md) — An event-driven Python backtester with 122 indicators, frozen since April 2023.
- [fastquant](https://stockmarketstack.com/tools/fastquant.md) — A one-call wrapper over Backtrader, dormant since 2023 and broken on PyPI.
- [QSTrader](https://stockmarketstack.com/tools/qstrader.md) — An institutional-shaped Python backtester whose last commit to master was June 2024.
- [Zipline-reloaded](https://stockmarketstack.com/tools/zipline-reloaded.md) — The maintained fork of Quantopian's Zipline. Bring your own data — it ships almost none.
- [AmiBroker](https://stockmarketstack.com/tools/amibroker.md) — Windows portfolio backtester scripted in AFL, sold as a perpetual licence.

## Named as a replacement for

- [Portfolio Visualizer](https://stockmarketstack.com/alternatives/portfolio-visualizer.md)
