Skip to content
python.financial
Platform
Portfolio backtesting library
License
MIT
Pricing
Free and open source
Live trading
Not supported
Best for
Multi-asset allocation, rotation, and rebalancing research where portfolio weights matter more than order-level execution

bt is a good fit when you want to select assets, assign weights, and rebalance a portfolio on a schedule. It is less suitable when the result depends on limit orders, queue position, delays, or price movement within a bar. The project is actively maintained.

How bt models a portfolio

A bt strategy is a stack of small, reusable Algo objects. An Algo can decide when to run, select securities, calculate target weights, or rebalance. The official overview describes how those steps operate on a strategy tree, so a parent strategy can allocate capital among child strategies as well as individual securities.

This design makes portfolio rules easy to rearrange and compare. It does not create an exchange simulator. bt primarily turns price data and target weights into portfolio positions and an equity curve.

Research concern bt support What to verify
Scheduling Daily, weekly, monthly, yearly, and custom run rules Confirm which observation produces a signal and when the rebalance occurs
Selection and weights Reusable Algos for filters, ranking, equal weights, specified weights, and risk-based allocation Supply point-in-time inputs and prevent future data from entering the selection
Portfolio structure Securities and nested child strategies in a strategy tree Check how capital and fees flow through each level
Trading costs Commission callables, bid-offer data, holding costs, and nonlinear cost models Defaults do not supply realistic costs for a particular market
Corporate actions A CorporateActions interface is available in the 1.2 series Confirm that the data source and action timing match the tested universe
Results Equity curves, statistics, drawdowns, weights, and transactions Treat statistics as research output, not proof of a tradable edge

Minimal monthly rebalancing example

This complete example creates two deterministic synthetic price series, assigns equal weights at each monthly run, and charges 10 basis points on traded notional. Fractional positions are enabled so integer rounding does not obscure the allocation logic.

import numpy as np
import pandas as pd
import bt

index = pd.date_range("2025-01-02", periods=80, freq="B")
step = np.arange(len(index))
prices = pd.DataFrame(
    {
        "asset_a": 100 + 0.15 * step + 2 * np.sin(step / 6),
        "asset_b": 100 + 0.08 * step + 1.5 * np.cos(step / 5),
    },
    index=index,
)

strategy = bt.Strategy(
    "monthly_equal_weight",
    [
        bt.algos.RunMonthly(),
        bt.algos.SelectAll(),
        bt.algos.WeighEqually(),
        bt.algos.Rebalance(),
    ],
)
backtest = bt.Backtest(
    strategy,
    prices,
    initial_capital=100_000,
    commissions=lambda quantity, price: abs(quantity) * price * 0.001,
    integer_positions=False,
    progress_bar=False,
)
result = bt.run(backtest)
print(f"Final strategy index: {result.prices.iloc[-1, 0]:.2f}")

With bt 1.2.3, the example prints Final strategy index: 108.01. The synthetic upward paths were chosen to exercise the API. That output is not evidence of a viable strategy.

Costs and execution assumptions

The Backtest API accepts a commission function and optional bid-offer, coupon, holding-cost, volume, and volatility data. The current API also includes SqrtCostModel and AlmgrenChrissCostModel. Those nonlinear models require appropriate volume and volatility inputs. A cost model is only as credible as its calibration and data.

bt does not model an order book, exchange latency, queue priority, or partial fills. A portfolio test should therefore state its signal lag, rebalance timing, spread and slippage assumptions, liquidity limits, financing costs, and borrow availability. Setting integer_positions=True, the default, can also leave small portfolios away from their intended weights because share quantities are rounded.

Data risks remain the researcher's responsibility

bt accepts a price table rather than providing a point-in-time security master. A current constituent list applied to old dates creates survivorship bias. Fundamentals or rankings timestamped after they became public create look-ahead bias. Prepare the universe, features, prices, and corporate actions as they were knowable at each simulated decision time.

The library is also a research backtester, not a live broker integration. A production system needs separate order management, broker connectivity, reconciliation, monitoring, and failure recovery.

License and maintenance

bt is distributed under the MIT License and is actively maintained.

When to choose bt

Choose bt for transparent portfolio-allocation experiments built from scheduled selection, weighting, and rebalancing rules. Consider Zipline-Reloaded when daily equity universe selection and Pipeline factors are central. Consider pysystemtrade when the goal is an opinionated futures research-to-production stack. Use an execution-focused engine when order lifecycle and market microstructure determine the result.

Choose which optional services may run. You can change these settings at any time.