Skip to main content

Bespoke trading strategy library — backtest, compare, and build custom strategies

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bespoke-0.2.0.tar.gz (523.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bespoke-0.2.0-py3-none-any.whl (247.4 kB view details)

Uploaded Python 3

File details

Details for the file bespoke-0.2.0.tar.gz.

File metadata

  • Download URL: bespoke-0.2.0.tar.gz
  • Upload date:
  • Size: 523.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.26.0

File hashes

Hashes for bespoke-0.2.0.tar.gz
Algorithm Hash digest
SHA256 f71ea18356b5bb4ecbcb8cb9a6293dc80bc1a99b08a83a67e3b4c0e4b6791302
MD5 ff8fa1bf29d17e6912455d0efd06ec94
BLAKE2b-256 627431f9c0b795f1e93cc15859ee1253f09638af3f71e54f82f0654ab58bb37f

See more details on using hashes here.

File details

Details for the file bespoke-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: bespoke-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 247.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.26.0

File hashes

Hashes for bespoke-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a9251c9974635296f2fde4ef774712e7be1d0d1f7c1ade407673e79b5f1ec11a
MD5 ee5422c07d10d27795b1078478f49536
BLAKE2b-256 04a9fa57d580c4ceb937428cec0045405f3ceadfd7d6c4848c636f105c4f3d6d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page