Skip to main content

fastbt-quant

Pandas-native backtesting library with backtest/live parity.

PyPI Python License: MIT

Distribution name on PyPI is fastbt-quant; the import name stays fastbt.

Install

pip install fastbt-quant                  # core
pip install "fastbt-quant[data]"          # + idata.fyi data fetching
pip install "fastbt-quant[report]"        # + HTML tearsheets via quantstats
pip install "fastbt-quant[signal]"        # + live signal server (aiohttp)
pip install "fastbt-quant[data,report,signal]"   # everything

Requires Python 3.11+.

Design principles

  • BYO data. Pandas DataFrame in, BacktestResult out. No data providers bundled.
  • One strategy class, two run modes. Same code for backtest and (eventually) live — the engine swaps, the strategy doesn't.
  • PaperBroker only in v0.0.1. Real broker adapters (Alpaca, CCXT, Kite) arrive in v0.2+.
  • Declarative JSON strategies coming in v0.0.2. The Python subclass API stays as the escape hatch.

Quick start

from fastbt import Strategy, backtest
from fastbt.indicators import sma

class SmaCross(Strategy):
    def on_bar(self, ctx):
        if len(ctx.history) < 30:
            return
        close = ctx.history["close"]
        fast = sma(close, 10).iloc[-1]
        slow = sma(close, 30).iloc[-1]
        prev_fast = sma(close, 10).iloc[-2]
        prev_slow = sma(close, 30).iloc[-2]

        if prev_fast <= prev_slow and fast > slow and ctx.position.is_flat:
            ctx.buy(qty=100)
        elif prev_fast >= prev_slow and fast < slow and ctx.position.is_long:
            ctx.close()

# `data` is any OHLCV DataFrame — bring your own source.
result = backtest(SmaCross(), data=data, initial_cash=100_000)
print(result)
# BacktestResult(trades=7, return=12.40%, max_dd=5.20%, sharpe=1.18, win_rate=57.1%)

JSON strategies (v0.4.0)

Single-symbol and portfolio strategies can be expressed entirely in JSON. One loader handles both:

import json
from fastbt import load_strategy, portfolio_backtest

with open("examples/momentum_portfolio.json") as f:
    strategy = load_strategy(json.load(f))

# `data` is a dict[str, pd.DataFrame] for portfolio mode.
result = portfolio_backtest(strategy, data=universe, initial_cash=1_000_000)

A portfolio JSON spec describes the same lifecycle (universe → rank → select → allocate → schedule) the Python PortfolioStrategy exposes. See examples/momentum_portfolio.json for a complete momentum-rotation example.

OHLCV schema contract

Your DataFrame must have:

  • Columns: open, high, low, close, volume (case-insensitive)
  • Index: pd.DatetimeIndex, monotonic increasing, no duplicates
  • No NaN values
  • high >= max(open, close), low <= min(open, close), volume >= 0

Call fastbt.validate_ohlcv(df) at your ingest boundary to fail fast.

Fill policy (important)

The single biggest source of "backtest was profitable but live loses money" is fill timing. fastbt makes this explicit:

  • fill_policy="next_open" (default, realistic) — order submitted on bar N fills at bar N+1's open. You only knew close after bar N ended.
  • fill_policy="current_close" (optimistic) — fills at bar N's close. Use only when your signal is known intra-bar.

Develop

git clone https://github.com/Vbhadala/fastbt
cd fastbt
uv sync --extra dev
uv run pytest
uv run python examples/sma_crossover.py

Portfolio strategies (v0.3.0)

Built-in allocators and risk controls so portfolio strategies don't hand-code these every time.

from fastbt import PortfolioStrategy, portfolio_backtest, RebalanceSchedule
from fastbt.allocators import (
    annualized_volatility, inverse_volatility, momentum_score,
)
from fastbt.indicators import roc

class MomentumTop3(PortfolioStrategy):
    def rank(self, ctx, universe):
        scored = []
        for sym in universe:
            close = ctx.history[sym]["close"]
            score = momentum_score(
                {"r90d": roc(close, 90).iloc[-1] if len(close) >= 90 else None},
                {"r90d": 1.0},
            )
            scored.append((sym, score))
        return sorted(scored, key=lambda x: x[1], reverse=True)

    def select(self, ctx, ranked):
        return [s for s, _ in ranked[:3]]

    def allocate(self, ctx, selected):
        vols = {s: annualized_volatility(ctx.history[s]["close"], 60) for s in selected}
        return inverse_volatility(selected, vols)

result = portfolio_backtest(
    MomentumTop3(), data,
    schedule=RebalanceSchedule.monthly(day=1),
    min_drift_pct=2.0,                  # skip trades under 2% drift
    vol_trailing_multiplier=2.0,        # vol-adaptive trailing stop
    vol_trailing_fallback_pct=10.0,
    risk_free_rate=6.0,                 # for Sharpe / Sortino
)

print(result.metrics.cagr, result.metrics.sortino)
print(len(result.stop_outs), "stop-outs recorded")

See examples/momentum_portfolio.py for a complete runnable walkthrough.

Roadmap

Version Scope
v0.0.1 Single-symbol backtest, PaperBroker, 6 indicators, OHLCV validator
v0.0.2 JSON declarative strategies, short positions, 15 more indicators
v0.1.0 Portfolio/universe strategies (rank + select), live mode via async feed
v0.2.0 Live signal engine + webhook server + idata.fyi data module
v0.3.0 Allocators, vol-trailing stops, drift-aware rebalancing, CAGR/Sortino metrics
v0.4.0 JSON portfolio strategy spec, vol_trailing in single-symbol JSON
v0.5.0 First PyPI release as fastbt-quant. Symbol-aware fills (breaking: Bar now requires symbol).
v0.6.0+ Real broker adapters (Alpaca/Kite), walk-forward validation, intrabar stop simulation

License

MIT

Metadata

Release files for fastbt-quant 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fastbt-quant 0.6.0
File Size Uploaded Provenance Actions
fastbt_quant-0.6.0.tar.gz 149.5 kB With provenance Details for fastbt_quant-0.6.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for fastbt-quant 0.6.0
File Interpreter ABI Platform Actions
fastbt_quant-0.6.0-py3-none-any.whl Python 3 none any Details for fastbt_quant-0.6.0-py3-none-any.whl

Total release size: 226.9 kB

Release files / fastbt_quant-0.6.0.tar.gz

Download URL fastbt_quant-0.6.0.tar.gz
Size 149.5 kB
Tags Source
SHA-256 checksum
How to use checksums
a6b130b780a186a13fdd3faadc17a4fe7e46e2af3ea1ad545679ba3a25ab5a64
BLAKE2b-256 checksum
How to use checksums
5d1e8a20309a5b8a67bf92dc7847004c4dedb94e1fbbd315ecbc4334d07a0f5f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 8, 2026.

Transparency log

Release files / fastbt_quant-0.6.0-py3-none-any.whl

Download URL fastbt_quant-0.6.0-py3-none-any.whl
Size 77.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8230de1b2cf20143a16f254fd07f078f548806c81f499e47c17df13fa13def21
BLAKE2b-256 checksum
How to use checksums
0c841f875caa87cdce0fd5727ea00371433913eaefef919fe3da7b6fcc85e6ce
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 8, 2026.

Transparency log

Security for fastbt-quant 0.6.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for fastbt_quant-0.6.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 8, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.6.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page