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.1.3.tar.gz (506.6 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.1.3-py3-none-any.whl (232.7 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for bespoke-0.1.3.tar.gz
Algorithm Hash digest
SHA256 22b55b3c894d517f32382a2065cc3558d9452d56273c08641be93ad274fc21e2
MD5 d5ed35b6c44fd3ff4eb76b0900efc5e5
BLAKE2b-256 94851a9e589cdbafe13e8a343a5e24ced171f62f87cf5d3a0c7a103464dec421

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for bespoke-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 04514901ae5b99999529645601074f504f5a69a710e70cd7421da6045e58ee28
MD5 f7669980774d51195eddfe49465c296a
BLAKE2b-256 bbc4ae68db4a0e1105d6cd2e9b93da43fab526037b0a9435018610e65549a7ad

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