Skip to main content

Lightweight backtesting library built on polars

Project description

PolarBT

PolarBT

A lightweight, high-performance backtesting library for trading strategy development and optimization. Built on Polars for fast vectorized data processing with an event-driven execution loop for flexible strategy logic.

Features

  • Hybrid architecture — vectorized preprocessing (Polars) + event-driven execution loop
  • 25+ built-in indicators — SMA, EMA, RSI, MACD, Bollinger Bands, ATR, SuperTrend, ADX, and more
  • Complete order system — market, limit, stop, stop-limit, bracket orders, day/GTC orders
  • Risk management — stop-loss, take-profit, trailing stops, position size limits, drawdown stops
  • Short selling — negative positions, borrow costs, position reversals
  • Margin & leverage — configurable leverage, margin tracking, margin calls
  • Commission models — percentage, fixed, maker/taker, volume-tiered, custom
  • Position sizing — fixed, percent, fixed-risk, Kelly, volatility-based
  • Weight-based backtesting — declarative portfolio allocation with backtest_weights(), rebalance scheduling, stop-loss/take-profit, next-actions output
  • Multi-asset — pass a dict of DataFrames for portfolio strategies
  • Parallel optimization — grid search, multi-objective Pareto, Bayesian optimization
  • Walk-forward analysis — rolling and anchored train/test splits
  • Advanced analysis — Monte Carlo simulation, look-ahead bias detection, permutation testing
  • Visualization — interactive Plotly charts (price, equity, drawdown, trade markers, heatmaps)
  • Data utilities — validation, cleaning, OHLCV resampling
  • Optional TA-Lib integration — wrap any TA-Lib function into Polars expressions

Installation

pip install polarbt

Or with optional extras:

pip install polarbt[plotting]   # Plotly charts
pip install polarbt[talib]      # TA-Lib integration

Install from source:

git clone git@github.com:nikkisora/PolarBT.git
cd PolarBT
pip install -e .

Quick Start

import polars as pl
import yfinance as yf
from polarbt import Engine, Strategy
from polarbt import indicators as ind
from polarbt.core import BacktestContext
from polarbt.plotting import plot_backtest


class SMACross(Strategy):
    def preprocess(self, df: pl.DataFrame) -> pl.DataFrame:
        return df.with_columns(
            ind.sma("close", 10).alias("sma_fast"),
            ind.sma("close", 30).alias("sma_slow"),
        ).with_columns(
            ind.crossover("sma_fast", "sma_slow").alias("buy"),
            ind.crossunder("sma_fast", "sma_slow").alias("sell"),
        )

    def next(self, ctx: BacktestContext) -> None:
        if ctx.row.get("buy"):
            ctx.portfolio.order_target_percent("asset", 1.0)
        elif ctx.row.get("sell"):
            ctx.portfolio.close_position("asset")


# Download data from Yahoo Finance
ticker = yf.download("AAPL", start="2016-01-01", end="2026-01-01", auto_adjust=True)
ticker = ticker.droplevel("Ticker", axis=1).reset_index()
data = pl.from_pandas(ticker)

# Run backtest
engine = Engine(SMACross(), data, commission=.005, initial_cash=100_000)
results = engine.run()

print(results)

# Interactive chart saved to HTML
fig = plot_backtest(engine, title="SMA Crossover — AAPL", indicators=["sma_fast", "sma_slow"])
fig.write_html("backtest.html")
Equity Final [$]                        366,236.83
Equity Peak [$]                         433,930.72
Return [%]                                  266.24
Buy & Hold Return [%]                      1044.52
Return (Ann.) [%]                            14.08
CAGR [%]                                     14.08
Volatility (Ann.) [%]                        19.78

Sharpe Ratio                                  0.76
Sortino Ratio                                 0.92
Calmar Ratio                                  0.44
Max. Drawdown [%]                           -32.16
Avg. Drawdown Duration [bars]                   38
Max. Drawdown Duration [bars]                  730

# Trades                                        42
Win Rate [%]                                 47.62
Best Trade [%]                               57.11
Worst Trade [%]                             -13.43
Avg. Trade [%]                                3.94
Max. Trade Duration [bars]                     128
Avg. Trade Duration [bars]                      39
Avg. Trade MDD [%]                           -8.78
Profit Factor                                 1.79
Expectancy [$]                             6338.97
SQN                                           1.27
Kelly Criterion                             0.2098

PolarBT

Weight-Based Backtesting

For portfolio allocation strategies, skip the event loop entirely — just supply target weights per (date, symbol):

import polars as pl
from polarbt import backtest_weights

# data: long-format DataFrame with columns date, symbol, close, weight
result = backtest_weights(
    data,
    resample="M",           # rebalance monthly
    resample_offset="2d",   # delay 2 trading days after month boundary
    fee_ratio=0.001,
    stop_loss=0.10,          # 10% per-position stop-loss
    position_limit=0.5,      # max 50% in any single name
    initial_capital=100_000,
)

print(result.metrics)        # standard BacktestMetrics
print(result.trades.head())  # per-trade log
print(result.next_actions)   # forward-looking rebalance actions

Examples

Example Description
example.py Basic SMA crossover
example_sma_crossover_stoploss.py SMA crossover with ATR stop-loss and trailing stop
example_rsi_bracket_orders.py RSI mean reversion with bracket orders
example_momentum_rotation.py Multi-asset momentum rotation
example_ml_strategy.py ML model integration
example_walk_forward.py Walk-forward analysis workflow
example_advanced_analysis.py Full workflow: optimization, heatmaps, Monte Carlo, permutation test
example_limit_orders.py Limit orders and stop-loss
example_trade_analysis.py Trade-level analysis
example_plotting.py Interactive chart generation
example_commission.py Commission model comparison
example_multi_asset.py Multi-asset dict input
example_weight_backtest.py Weight-based portfolio backtest

Documentation

License

MIT

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

polarbt-0.1.5.tar.gz (149.5 kB view details)

Uploaded Source

Built Distribution

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

polarbt-0.1.5-py3-none-any.whl (94.1 kB view details)

Uploaded Python 3

File details

Details for the file polarbt-0.1.5.tar.gz.

File metadata

  • Download URL: polarbt-0.1.5.tar.gz
  • Upload date:
  • Size: 149.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for polarbt-0.1.5.tar.gz
Algorithm Hash digest
SHA256 2ef461a2e43132d11e67fab191ebec10369628b6717aaa96c34ed5bde2aa61dd
MD5 3c6fd97f651cadfa88c5613b292653e2
BLAKE2b-256 2da6ed53f072912e45b63fe2f374f0df5a666d1e8a6b7c34efd71ac6d8debd80

See more details on using hashes here.

Provenance

The following attestation bundles were made for polarbt-0.1.5.tar.gz:

Publisher: publish.yml on nikkisora/PolarBT

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file polarbt-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: polarbt-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 94.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for polarbt-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 e131f666c17a990c0761eafb9cc88baf7c2c113eadfd8e23eec3b3009cbb5d7c
MD5 baa78e1e7753e5b22acc007cba1ca74f
BLAKE2b-256 66f73b7ab0711a0f596720d8ab801c25a3b6b628c5e1d3cf9d36c29da68bb25b

See more details on using hashes here.

Provenance

The following attestation bundles were made for polarbt-0.1.5-py3-none-any.whl:

Publisher: publish.yml on nikkisora/PolarBT

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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