Skip to main content

bespoke

A Python library for backtesting, comparing, and building trading strategies. Bespoke provides a clean API for defining strategy logic, running historical simulations with realistic slippage modeling, and evaluating performance through standard financial metrics like Sharpe ratio, CAGR, max drawdown, and rolling-window composite scores.

Install

pip install bespoke

Quick Start

from bespoke import Backtester
from bespoke.strategies import get_strategy

strategy = get_strategy("spy_buy_and_hold")
bt = Backtester(strategy, start="2020-01-01", end="2025-12-31")
result = bt.run()
print(f"Return: {result['metrics']['total_return']:.2%}")
print(f"Sharpe: {result['metrics']['sharpe_ratio']:.2f}")

CLI

Bespoke includes a command-line interface for quick analysis.

# List all available strategies
bespoke list

# Show details for a strategy
bespoke info spy_buy_and_hold

# Run a backtest
bespoke backtest spy_buy_and_hold --start 2020-01-01 --end 2025-12-31

# Run on all 28 rolling windows (1Y-15Y x 4 end years)
bespoke backtest spy_buy_and_hold --windows

# Compare two strategies side by side
bespoke compare spy_buy_and_hold balanced_sixty_forty

# Save results to JSON
bespoke save spy_buy_and_hold --output results.json

Creating a Custom Strategy

Subclass BaseStrategy and implement generate_signals:

from bespoke.strategies.base import BaseStrategy, StrategyConfig

class MomentumStrategy(BaseStrategy):
    def __init__(self):
        super().__init__(StrategyConfig(
            name="momentum",
            description="Buy assets with positive 50-day momentum",
            universe=["SPY", "QQQ", "IWM"],
            rebalance_frequency="monthly",
            max_position_size=0.50,
        ))

    def generate_signals(self, date, prices, portfolio, data):
        signals = {}
        for sym in self.universe:
            if sym in data and date in data[sym].index:
                sma50 = data[sym].loc[:date, "SMA_50"].iloc[-1]
                if prices.get(sym, 0) > sma50:
                    signals[sym] = 1.0
        return signals

Then backtest it:

from bespoke import Backtester

bt = Backtester(MomentumStrategy(), start="2020-01-01")
result = bt.run()

Architecture

bespoke/
  core/
    backtester.py    Event-driven backtester with slippage + rebalancing
    portfolio.py     Position tracking, cash management, trade history
    metrics.py       Sharpe, Sortino, CAGR, drawdown, alpha/beta, composite
  data/
    fetcher.py       OHLCV via yfinance with parquet caching + indicators
  strategies/
    base.py          BaseStrategy + StrategyConfig dataclass
    registry.py      Auto-discovery and name-based lookup
    generic/         Baseline strategies (SPY, 60/40, three-fund)
  compat/
    loader.py        Bridge to load external strategy collections
  cli/
    main.py          Command-line interface (argparse)

Data flow:

  1. Backtester loads OHLCV data via fetch_ohlcv (cached locally)
  2. Technical indicators are added (SMA, RSI, MACD, Bollinger, ATR)
  3. On each trading day, Strategy.generate_signals() returns target weights
  4. Portfolio executes rebalancing trades with slippage
  5. compute_metrics() evaluates the resulting equity curve

Available Strategies

Three baseline strategies are included out of the box:

Name Description Universe
spy_buy_and_hold 100% S&P 500, never trade SPY
balanced_sixty_forty 60% stocks / 40% bonds, monthly rebalance SPY, AGG
three_fund_passive 50% SPY + 30% QQQ + 20% GLD SPY, QQQ, GLD

These baselines serve as the performance bar that any custom strategy must clear to justify its complexity.

The bespoke.compat module provides a bridge to load additional strategy collections. See bespoke/compat/loader.py for details.

Metrics

Every backtest produces:

  • Total Return and CAGR -- absolute and annualized performance
  • Sharpe Ratio -- risk-adjusted return (excess over risk-free rate)
  • Sortino Ratio -- penalizes only downside volatility
  • Max Drawdown -- worst peak-to-trough decline
  • Calmar Ratio -- CAGR / max drawdown
  • Win Rate -- fraction of positive trading days
  • Alpha / Beta -- vs benchmark (when benchmark data available)
  • Composite Score -- rolling-window consistency metric

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/my-strategy)
  3. Add your strategy in src/bespoke/strategies/
  4. Write tests in tests/
  5. Run pytest to verify
  6. Submit a pull request

License

MIT License. See LICENSE for details.

Release files for bespoke 0.2.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 bespoke 0.2.0
File Size Uploaded
bespoke-0.2.0.tar.gz 523.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bespoke 0.2.0
File Interpreter ABI Platform
bespoke-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 770.9 kB

Release files / bespoke-0.2.0.tar.gz

Download URL bespoke-0.2.0.tar.gz
Size 523.5 kB
Tags Source
SHA-256 checksum
How to use checksums
f71ea18356b5bb4ecbcb8cb9a6293dc80bc1a99b08a83a67e3b4c0e4b6791302
BLAKE2b-256 checksum
How to use checksums
627431f9c0b795f1e93cc15859ee1253f09638af3f71e54f82f0654ab58bb37f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-httpx/0.26.0

Release files / bespoke-0.2.0-py3-none-any.whl

Download URL bespoke-0.2.0-py3-none-any.whl
Size 247.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a9251c9974635296f2fde4ef774712e7be1d0d1f7c1ade407673e79b5f1ec11a
BLAKE2b-256 checksum
How to use checksums
04a9fa57d580c4ceb937428cec0045405f3ceadfd7d6c4848c636f105c4f3d6d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-httpx/0.26.0

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.1

1 release file

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