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.2.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.2-py3-none-any.whl (232.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: bespoke-0.1.2.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.2.tar.gz
Algorithm Hash digest
SHA256 10ec32040fa6627170925e9abba60bd0cf6babf7d605d9adaa4b0b95dd614dff
MD5 7dc7946a0045bcbe284d726c79a18bfc
BLAKE2b-256 3852f505bc7817ecae3779e94057425f0e3e70b6dfdc848922d0240162c681e7

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bespoke-0.1.2-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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0a1f4dbf3d7dfb215f1dd284041d1f416a0485cca6a472e36f8b26f6bbfb4a29
MD5 3c4ef10e743dde4a5b73b29b6a32616a
BLAKE2b-256 eaae2d3b5c05b7483d6dd39930479faa6a6933a9b98852e5927b0b2b98e17018

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