Skip to content
python.financial
Platform
Backtesting and machine-learning library
License
Apache-2.0 with Commons Clause (source-available)
Pricing
Source-available package with no separate service fee
Live trading
Not supported
Best for
Bar-based rule or supervised-learning research with chronological retraining

PyBroker combines bar-based backtesting, feature calculation, supervised model training, and chronological train/test windows. It also handles rule-based strategies, multiple symbols, ranking, rotation, and parameter optimization. It does not place live trades, and bar data cannot reproduce order-book queues, market impact, or intrabar event order.

The package name is lib-pybroker. Its newer API made breaking changes, so check the changelog before adapting an older example.

How PyBroker structures a backtest

A Strategy reads OHLCV bars from a pandas DataFrame or a historical data source. PyBroker calls an execution function for each selected symbol and completed bar. The function can inspect prices, indicators, model predictions, and portfolio state, then schedule orders for a later bar. NumPy arrays and Numba-compiled kernels accelerate internal calculations, but the user-facing strategy is still a stateful bar-by-bar callback.

The built-in data sources include Yahoo Finance and Alpaca. AKShare support needs a separate dependency, and custom data sources or DataFrames are supported. Caching data, indicators, and trained models can shorten repeated runs, but clear the cache when data adjustments, features, or model code change.

PyBroker also supports several time intervals, changing symbol lists, rotation, margin settings, slippage models, parallel calculations, and Optuna-based parameter search. These features widen what you can test, but they cannot fix future data leaks or replace a separate final test.

A deterministic PyBroker 2 example

The following synthetic example makes its execution costs visible. A signal on the first completed bar fills on the next bar because the default buy delay is one. The final position is closed on the last bar. Fixed five-basis-point adverse slippage and a one-unit fee apply to each order.

import pandas as pd
from pybroker import (
    FeeMode,
    FixedSlippageModel,
    Strategy,
    StrategyConfig,
    disable_logging,
)

disable_logging()
prices = [100, 101, 102, 103, 104, 105]
data = pd.DataFrame(
    {
        "symbol": "TEST",
        "date": pd.date_range("2026-01-05", periods=len(prices), freq="B"),
        "open": prices,
        "high": [price + 1 for price in prices],
        "low": [price - 1 for price in prices],
        "close": prices,
        "volume": 10_000,
    }
)


def buy_once(ctx):
    if not ctx.long_pos():
        ctx.buy_shares = 10


config = StrategyConfig(
    initial_cash=10_000,
    fee_mode=FeeMode.PER_ORDER,
    fee_amount=1,
    exit_on_last_bar=True,
)
strategy = Strategy(data, data.date.min(), data.date.max(), config=config)
strategy.add_execution(buy_once, "TEST")
strategy.set_slippage_model(FixedSlippageModel(bps=5))
result = strategy.backtest()

print(result.orders[["type", "shares", "fill_price", "fees"]].to_string(index=False))

Executed with PyBroker 2.0.1, the example produced a buy at 101.05 and a sell at 104.95, with a fee of 1 on each order. The rising synthetic series checks API behavior only. It is not evidence of a tradable strategy.

The execution context documentation states that a callback sees the latest completed bar and that its order executes on the future bar selected by buy_delay or sell_delay. This separation is useful for avoiding same-bar look-ahead, provided custom fill-price functions and features also use information available at the decision time.

Walk-forward analysis is explicit

Strategy.backtest() defaults to a single test run with train_size=0. Use Strategy.walkforward(windows=..., train_size=...) when models must be retrained across chronological windows. The walk-forward API excludes the configured lookahead bars between training and test data, including in the units of a compressed interval for interval-bound models.

That machinery prevents one specific leakage path. A credible ML test still needs controls outside the splitter:

Research decision What to verify
Features and labels Every feature is available at decision time, and the label horizon matches lookahead
Universe Membership is point-in-time rather than today's survivors
Corporate actions Prices, volume, dividends, and symbol changes use a consistent adjustment policy
Model selection Hyperparameters and feature choices do not use the final test windows
Costs Fees, spread, slippage, borrow, financing, and capacity match the intended market
Retraining Window length and schedule match what could run in production

Do not shuffle time-series training rows unless the estimator and research design justify destroying temporal order. Keep a final untouched period or forward paper-trading stage outside parameter selection. Parameter optimization makes it easier to search many configurations, which also increases the need to track the full search and account for multiple-testing bias.

Fills, costs, and statistical output

PyBroker supports market-style scheduled orders, limit prices, stops, holding periods, position ranking, and several fee models. Its slippage models can use fixed, volatility-based, or volume-based costs. The volume model can limit trade size and adjust prices, but bar volume does not reveal queue position or the order of trades within the bar.

Fees and slippage are disabled unless you add them. Financing also needs explicit settings. PyBroker supports leverage and interest, but you still need to model short availability, borrow fees, dividends, funding, exchange rules, and forced liquidation for the market you are testing.

Optional bootstrap output provides BCa confidence intervals for profit factor and Sharpe ratio plus drawdown estimates. PyBroker's bootstrap guide resamples per-bar returns. Treat these as sensitivity estimates under the resampling assumptions, not proof that returns are independent or that a strategy will repeat. Serial dependence and regime changes can make an ordinary return bootstrap too confident.

Limits and licensing

PyBroker is a research backtester rather than an end-to-end deployment system. It does not document a live execution engine, broker-state reconciliation, order monitoring, or restart recovery. Plan a separate paper and live implementation, then test the behavior gap explicitly.

The project is source-available under Apache 2.0 with the Commons Clause. The Commons Clause removes the right to sell a product or service whose value derives substantially from the software. PyPI summarizes the package as free for non-commercial use. This is not the same as an unmodified Apache-2.0 license, so obtain appropriate advice before offering a commercial service built around PyBroker.

Choose PyBroker when integrated model training, multi-symbol bar logic, and walk-forward analysis match the research question. Choose a simpler bar engine when those facilities add unnecessary structure, or an event and order-book simulator when the strategy depends on intrabar sequencing and liquidity mechanics.

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