Skip to main content

High-performance Rust backtesting engine with Python bindings. Bar-level and tick-level simulation with sub-millisecond execution and a minimal footprint.

Project description

RaptorBT

License: MIT PyPI version Python 3.10+ Rust PyPI Downloads

Blazing-fast backtesting for the modern quant.

RaptorBT is a high-performance backtesting engine written in Rust with Python bindings via PyO3. It runs single-instrument, basket, pairs, options, spread, multi-strategy, and tick-level backtests over any OHLCV or tick arrays — from any broker, market, or asset class — and returns a full performance report in sub-millisecond time.

Sub-millisecond backtests · <1 MB compiled engine · Bit-for-bit deterministic


Quick Install

pip install raptorbt

30-Second Example

import numpy as np
import raptorbt

# Configure
config = raptorbt.PyBacktestConfig(initial_capital=100000, fees=0.001)

# Run backtest
result = raptorbt.run_single_backtest(
    timestamps=timestamps,
    open=open,
    high=high,
    low=low,
    close=close,
    volume=volume,
    entries=entries,
    exits=exits,
    direction=1,
    weight=1.0,
    symbol="AAPL",
    config=config,
)

# Results
print(f"Return: {result.metrics.total_return_pct:.2f}%")
print(f"Sharpe: {result.metrics.sharpe_ratio:.2f}")

RaptorBT is open source (MIT) and developed by the Alphabench team.


Table of Contents


Overview

RaptorBT compiles to a single native extension and runs entirely in Rust, so a full backtest with all 33 metrics finishes in well under a millisecond on typical bar counts. Measured on an Apple M4 (raptorbt 0.4.0):

Metric RaptorBT
Compiled engine size <1 MB
Backtest speed (1K bars) ~0.03 ms
Backtest speed (10K bars) ~0.25 ms
Backtest speed (50K bars) ~1.4 ms
Memory usage Low (native)

See Performance for the full method and how to reproduce these numbers on your own hardware.

Key Features

  • 7 Strategy Types: Single instrument, basket/collective, pairs trading, options, spreads, multi-strategy, and tick-level
  • Asset- and broker-agnostic: Pass NumPy OHLCV or tick arrays from any source — equities, futures, FX, crypto, options — RaptorBT never assumes a market or data vendor
  • Tick-Level Simulation: Full tick resolution for intraday options momentum, scalping, and microstructure strategies
  • Batch Spread Backtesting: Run multiple spread backtests in parallel via Rayon with GIL released
  • Monte Carlo Simulation: Correlated multi-asset forward projection via GBM + Cholesky decomposition
  • 33 Metrics: Sharpe, Sortino, Calmar, Omega, SQN, Payoff Ratio, Recovery Factor, and more
  • 20 Indicator & Tick Functions: 12 classic technical indicators (SMA, EMA, RSI, MACD, Stochastic, ATR, Bollinger Bands, ADX, VWAP, Supertrend, Rolling Min/Max) plus 8 tick microstructure/feature functions
  • Stop/Target Management: Fixed, ATR-based, and trailing stops with risk-reward targets
  • Deterministic: Identical inputs produce bit-for-bit identical results across runs — no JIT compilation variance
  • Native Parallelism: Rayon-based parallel processing with explicit SIMD optimizations

Performance

Benchmark Results

Measured on an Apple M4 (raptorbt 0.4.0, Python 3.11) with random-walk price data and an SMA-crossover strategy. Each figure is the fastest of several hundred repetitions of run_single_backtest (so it reflects engine time, not scheduler noise):

┌─────────────┬───────────┐
│ Data Size   │ RaptorBT  │
├─────────────┼───────────┤
│ 1,000 bars  │ 0.03 ms   │
│ 5,000 bars  │ 0.13 ms   │
│ 10,000 bars │ 0.25 ms   │
│ 50,000 bars │ 1.37 ms   │
└─────────────┴───────────┘

Timings scale roughly linearly with bar count and will vary with your CPU, data, and signal density. Reproduce them with the Verification Test below, swapping in your own array sizes.

Determinism

RaptorBT is fully deterministic: the same inputs produce bit-for-bit identical results across runs (no JIT warmup, no nondeterministic reductions). Running the Verification Test five times in a row on this machine produced the same total return every time, to the last decimal:

Total return:           -30.6192%  (seed=42, 500 bars, periodic entries/exits)
Max difference across 5 runs: 0.0000000000%

(The exact return depends on your data and signals — the point is that it does not change between runs.)


Strategy Types

All strategy entrypoints take NumPy arrays directly. Signals (entries / exits) are boolean arrays you compute however you like — pandas, the built-in indicators, or your own model. The engine is asset- and broker-agnostic: timestamps are int64 (nanoseconds for tick data; any monotonic int for bars), prices are float64.

1. Single Instrument

Long or short on one instrument. This is the canonical example — the other strategy types follow the same shape.

import numpy as np
import pandas as pd
import raptorbt

df = pd.read_csv("your_data.csv", index_col=0, parse_dates=True)

# Signals (SMA crossover) — any boolean arrays work here
sma_fast = df["close"].rolling(10).mean()
sma_slow = df["close"].rolling(20).mean()
entries = (sma_fast > sma_slow) & (sma_fast.shift(1) <= sma_slow.shift(1))
exits = (sma_fast < sma_slow) & (sma_fast.shift(1) >= sma_slow.shift(1))

config = raptorbt.PyBacktestConfig(initial_capital=100000, fees=0.001, slippage=0.0005)
config.set_fixed_stop(0.02)    # optional 2% stop-loss
config.set_fixed_target(0.04)  # optional 4% take-profit

result = raptorbt.run_single_backtest(
    timestamps=df.index.astype("int64").values,
    open=df["open"].values,
    high=df["high"].values,
    low=df["low"].values,
    close=df["close"].values,
    volume=df["volume"].values,
    entries=entries.values,
    exits=exits.values,
    direction=1,   # 1 = long, -1 = short
    weight=1.0,
    symbol="AAPL",
    config=config,
    instrument_config=raptorbt.PyInstrumentConfig(lot_size=1.0),  # optional: lot rounding, capital cap
)

print(f"Return {result.metrics.total_return_pct:.2f}%  "
      f"Sharpe {result.metrics.sharpe_ratio:.2f}  "
      f"MaxDD {result.metrics.max_drawdown_pct:.2f}%  "
      f"Trades {result.metrics.total_trades}")

equity = result.equity_curve()  # np.ndarray
trades = result.trades()        # list[PyTrade]

2. Basket/Collective

Trade multiple instruments with synchronized signals.

instruments = [
    (timestamps, open1, high1, low1, close1, volume1, entries1, exits1, 1, 0.33, "AAPL"),
    (timestamps, open2, high2, low2, close2, volume2, entries2, exits2, 1, 0.33, "GOOGL"),
    (timestamps, open3, high3, low3, close3, volume3, entries3, exits3, 1, 0.34, "MSFT"),
]

# Optional: Per-instrument configs for lot_size and capital allocation
instrument_configs = {
    "AAPL": raptorbt.PyInstrumentConfig(lot_size=1.0, alloted_capital=33000),
    "GOOGL": raptorbt.PyInstrumentConfig(lot_size=1.0, alloted_capital=33000),
    "MSFT": raptorbt.PyInstrumentConfig(lot_size=1.0, alloted_capital=34000),
}

result = raptorbt.run_basket_backtest(
    instruments=instruments,
    config=config,
    sync_mode="all",  # "all", "any", "majority", "master"
    instrument_configs=instrument_configs,  # Optional
)

Sync Modes:

  • all: Enter only when ALL instruments signal
  • any: Enter when ANY instrument signals
  • majority: Enter when >50% of instruments signal
  • master: Follow the first instrument's signals

3. Pairs Trading

Long one instrument, short another with optional hedge ratio.

result = raptorbt.run_pairs_backtest(
    # Long leg
    leg1_timestamps=timestamps,
    leg1_open=long_open,
    leg1_high=long_high,
    leg1_low=long_low,
    leg1_close=long_close,
    leg1_volume=long_volume,
    # Short leg
    leg2_timestamps=timestamps,
    leg2_open=short_open,
    leg2_high=short_high,
    leg2_low=short_low,
    leg2_close=short_close,
    leg2_volume=short_volume,
    # Signals
    entries=entries,
    exits=exits,
    direction=1,
    symbol="TCS_INFY",
    config=config,
    hedge_ratio=1.5,      # Short 1.5x the long position
    dynamic_hedge=False,  # Use rolling hedge ratio
)

4. Options

Backtest options strategies with strike selection.

result = raptorbt.run_options_backtest(
    timestamps=timestamps,
    open=underlying_open,
    high=underlying_high,
    low=underlying_low,
    close=underlying_close,
    volume=volume,
    option_prices=option_prices,  # Option premium series
    entries=entries,
    exits=exits,
    direction=1,
    symbol="NIFTY_CE",
    config=config,
    option_type="call",           # "call" or "put"
    strike_selection="atm",       # "atm", "otm1", "otm2", "itm1", "itm2"
    size_type="percent",          # "percent", "contracts", "notional", "risk"
    size_value=0.1,               # 10% of capital
    lot_size=50,                  # Options lot size
    strike_interval=50.0,         # Strike interval (e.g., 50 for NIFTY)
)

5. Multi-Strategy

Combine multiple strategies on the same instrument.

strategies = [
    (entries_sma, exits_sma, 1, 0.4, "SMA_Crossover"),    # 40% weight
    (entries_rsi, exits_rsi, 1, 0.35, "RSI_MeanRev"),     # 35% weight
    (entries_bb, exits_bb, 1, 0.25, "BB_Breakout"),       # 25% weight
]

result = raptorbt.run_multi_backtest(
    timestamps=timestamps,
    open=open_prices,
    high=high_prices,
    low=low_prices,
    close=close_prices,
    volume=volume,
    strategies=strategies,
    config=config,
    combine_mode="any",  # "any", "all", "majority", "weighted", "independent"
)

Combine Modes:

  • any: Enter when any strategy signals
  • all: Enter only when all strategies signal
  • majority: Enter when >50% of strategies signal
  • weighted: Weight signals by strategy weight
  • independent: Run strategies independently (aggregate PnL)

6. Batch Spread Backtest

Run multiple spread backtests in parallel. Shared data (timestamps, underlying close) is converted once, then each item is backtested on its own Rayon thread with the GIL released for maximum throughput.

import numpy as np
import raptorbt

config = raptorbt.PyBacktestConfig(initial_capital=100000, fees=0.001)

# Create batch items — one per strategy variation
items = [
    raptorbt.PyBatchSpreadItem(
        strategy_id="straddle_24000",
        legs_premiums=[call_24000_premiums, put_24000_premiums],
        leg_configs=[("CE", 24000.0, -1, 50), ("PE", 24000.0, -1, 50)],
        entries=entries,
        exits=exits,
        spread_type="straddle",
        max_loss=5000.0,
        target_profit=3000.0,
    ),
    raptorbt.PyBatchSpreadItem(
        strategy_id="strangle_23500_24500",
        legs_premiums=[call_24500_premiums, put_23500_premiums],
        leg_configs=[("CE", 24500.0, -1, 50), ("PE", 23500.0, -1, 50)],
        entries=entries,
        exits=exits,
        spread_type="strangle",
    ),
]

# Run all in parallel — returns list of (strategy_id, result) tuples
results = raptorbt.batch_spread_backtest(
    timestamps=timestamps,
    underlying_close=underlying_close,
    items=items,
    config=config,
)

for strategy_id, result in results:
    print(f"{strategy_id}: {result.metrics.total_return_pct:.2f}%")

7. Tick-Level Backtest

Simulate intraday strategies at full tick resolution — no bar resampling, no intra-bar path approximation. Designed for options momentum, scalping, and any setup where the exact fill tick matters.

import numpy as np
import raptorbt

# Raw tick arrays (one element per tick, same length N)
# buy_qty_delta / sell_qty_delta must be per-tick deltas, NOT Zerodha cumulative sums
result = raptorbt.run_tick_backtest(
    timestamps=timestamps_ns,       # int64 nanoseconds-since-epoch
    ltp=ltp_arr,                    # last traded price
    bid=bid_arr,
    ask=ask_arr,
    buy_qty_delta=buy_delta,        # pre-converted from cumulative: np.diff(buy_cum).clip(0)
    sell_qty_delta=sell_delta,
    oi=oi_arr,
    entries=entry_signals,          # bool array — True where entry is allowed
    exits=exit_signals,             # bool array — True where position should exit
    symbol="NIFTY26APR24600PE",
    initial_capital=100_000.0,
    fees=0.001,
    slippage=0.0005,
    stop_loss_pct=5.0,
    take_profit_pct=10.0,
    max_hold_seconds=1800,          # 30-minute maximum hold
    entry_cooldown_ticks=10,        # minimum ticks between entries
    max_trades=50,
)

print(f"trades: {result.metrics.total_trades}")
print(f"profit_factor: {result.metrics.profit_factor:.2f}")
print(f"win_rate: {result.metrics.win_rate_pct:.1f}%")

Tick Signal & Feature Helpers

Precompute entry/exit signal arrays and tick microstructure features before calling run_tick_backtest:

# Signal arrays
entries = raptorbt.compute_tick_entry_signals(
    spread_pct=raptorbt.tick_spread_pct(bid, ask),
    bsi_delta=raptorbt.buy_sell_imbalance_delta(buy_cum, sell_cum),  # pass raw cumulative
    return_1m=raptorbt.return_window(timestamps_ns, ltp, window_seconds=60.0),
    spread_pct_max=3.0,
    bsi_min=0.55,           # minimum buy-side delta fraction
    return_1m_min_abs=0.3,  # minimum 1-min return % (abs)
    return_direction=1,     # +1 long, -1 short
    cooldown_ticks=10,
)
exits = raptorbt.compute_tick_exit_signals(
    timestamps_ns=timestamps_ns,
    eod_exit_time_ns=eod_ns,   # force exit at/after this timestamp; 0 = disabled
)

# Feature arrays (all return Vec<f64> of same length as input)
spread   = raptorbt.tick_spread_pct(bid, ask)               # (ask-bid)/mid * 100
bsi      = raptorbt.buy_sell_imbalance_delta(buy_cum, sell_cum)  # delta BSI per tick
ret_1m   = raptorbt.return_window(ts_ns, ltp, 60.0)         # 1-min lookback return %
vol      = raptorbt.realized_vol_rolling(ts_ns, ltp, 300.0)  # 5-min realized vol %
oi_pos   = raptorbt.oi_position_pct(oi, oi_day_high, oi_day_low)  # [0, 100]
velocity = raptorbt.tick_velocity(ts_ns, 60.0)              # ticks/min over last 60s

Important for Zerodha data: total_buy_qty and total_sell_qty from KiteTicker are cumulative session running sums, not per-tick values. Pass them as-is to buy_sell_imbalance_delta (it computes deltas internally). For run_tick_backtest, convert first: buy_delta = np.diff(buy_cum, prepend=0).clip(min=0).


Metrics

Every backtest returns a PyBacktestMetrics object exposing 33 metric fields (listed in full under PyBacktestMetrics). metrics.to_dict() returns a subset of 24 of them under human-readable labels (e.g. "Sharpe Ratio", "Total Return [%]") for quick display; read fields directly off the object to access all 33. The most useful are grouped below.

Core Performance

Metric Description
total_return_pct Total return as percentage
sharpe_ratio Risk-adjusted return (annualized)
sortino_ratio Downside risk-adjusted return
calmar_ratio Return / Max Drawdown
omega_ratio Probability-weighted gains/losses

Drawdown

Metric Description
max_drawdown_pct Maximum peak-to-trough decline
max_drawdown_duration Longest drawdown period (bars)

Trade Statistics

Metric Description
total_trades Total number of trades
total_closed_trades Number of closed trades
total_open_trades Number of open positions
winning_trades Number of profitable trades
losing_trades Number of losing trades
win_rate_pct Percentage of winning trades

Trade Performance

Metric Description
profit_factor Gross profit / Gross loss
expectancy Average expected profit per trade
sqn System Quality Number
avg_trade_return_pct Average trade return
avg_win_pct Average winning trade return
avg_loss_pct Average losing trade return
best_trade_pct Best single trade return
worst_trade_pct Worst single trade return

Duration

Metric Description
avg_holding_period Average trade duration (bars)
avg_winning_duration Average winning trade duration
avg_losing_duration Average losing trade duration

Streaks

Metric Description
max_consecutive_wins Longest winning streak
max_consecutive_losses Longest losing streak

Other

Metric Description
start_value Initial portfolio value
end_value Final portfolio value
total_fees_paid Total transaction costs
open_trade_pnl Unrealized PnL from open positions
exposure_pct Percentage of time in market

Indicators

RaptorBT exports 12 classic technical indicators, computed in native Rust and operating on (and returning) NumPy arrays:

import raptorbt

# Trend indicators
sma = raptorbt.sma(close, period=20)
ema = raptorbt.ema(close, period=20)
supertrend, direction = raptorbt.supertrend(high, low, close, period=10, multiplier=3.0)

# Momentum indicators
rsi = raptorbt.rsi(close, period=14)
macd_line, signal_line, histogram = raptorbt.macd(close, 12, 26, 9)  # fast, slow, signal (positional)
stoch_k, stoch_d = raptorbt.stochastic(high, low, close, k_period=14, d_period=3)

# Volatility indicators
atr = raptorbt.atr(high, low, close, period=14)
upper, middle, lower = raptorbt.bollinger_bands(close, period=20, std_dev=2.0)

# Strength indicators
adx = raptorbt.adx(high, low, close, period=14)

# Volume indicators
vwap = raptorbt.vwap(high, low, close, volume)

# Rolling indicators (LLV / HHV)
rolling_low = raptorbt.rolling_min(low, period=20)    # Lowest Low Value
rolling_high = raptorbt.rolling_max(high, period=20)  # Highest High Value

In addition, 8 tick microstructure / feature functions are available for tick-level work (tick_spread_pct, buy_sell_imbalance_delta, return_window, realized_vol_rolling, oi_position_pct, tick_velocity, compute_tick_entry_signals, compute_tick_exit_signals) — see Tick-Level Backtest.


Stop-Loss & Take-Profit

Fixed Percentage

config = raptorbt.PyBacktestConfig(initial_capital=100000, fees=0.001)
config.set_fixed_stop(0.02)    # 2% stop-loss
config.set_fixed_target(0.04)  # 4% take-profit

ATR-Based

config.set_atr_stop(multiplier=2.0, period=14)    # 2x ATR stop
config.set_atr_target(multiplier=3.0, period=14)  # 3x ATR target

Trailing Stop

config.set_trailing_stop(0.02)  # 2% trailing stop

Risk-Reward Target

config.set_risk_reward_target(ratio=2.0)  # 2:1 risk-reward ratio

Monte Carlo Portfolio Simulation

RaptorBT includes a high-performance Monte Carlo forward simulation engine for portfolio risk analysis. It uses Geometric Brownian Motion (GBM) with Cholesky decomposition for correlated multi-asset simulation, parallelized via Rayon.

import numpy as np
import raptorbt

# Historical daily returns per strategy/asset (numpy arrays)
returns = [
    np.array([0.001, -0.002, 0.003, ...]),  # Strategy 1 returns
    np.array([0.002, 0.001, -0.001, ...]),   # Strategy 2 returns
]

# Portfolio weights (must sum to 1.0)
weights = np.array([0.6, 0.4])

# Correlation matrix (N x N)
correlation_matrix = [
    np.array([1.0, 0.3]),
    np.array([0.3, 1.0]),
]

# Run simulation
result = raptorbt.simulate_portfolio_mc(
    returns=returns,
    weights=weights,
    correlation_matrix=correlation_matrix,
    initial_value=100000.0,
    n_simulations=10000,   # Number of Monte Carlo paths (default: 10,000)
    horizon_days=252,      # Forward projection horizon (default: 252)
    seed=42,               # Random seed for reproducibility (default: 42)
)

# Results
print(f"Expected Return: {result['expected_return']:.2f}%")
print(f"Probability of Loss: {result['probability_of_loss']:.2%}")
print(f"VaR (95%): {result['var_95']:.2f}%")
print(f"CVaR (95%): {result['cvar_95']:.2f}%")

# Percentile paths: list of (percentile, path_values)
# Percentiles: 5th, 25th, 50th, 75th, 95th
for pct, path in result['percentile_paths']:
    print(f"  P{pct:.0f} final value: {path[-1]:.2f}")

# Final values: numpy array of terminal values for all simulations
final_values = result['final_values']  # numpy array, length = n_simulations

Result Fields

Field Type Description
expected_return float Expected return as percentage over the horizon
probability_of_loss float Probability that final value < initial value (0.0 to 1.0)
var_95 float Value at Risk at 95% confidence (percentage)
cvar_95 float Conditional VaR at 95% confidence (percentage)
percentile_paths List[Tuple[float, List]] Portfolio paths at 5th, 25th, 50th, 75th, 95th percentiles
final_values numpy.ndarray Terminal portfolio values for all simulations

API Reference

PyBacktestConfig

config = raptorbt.PyBacktestConfig(
    initial_capital: float = 100000.0,
    fees: float = 0.001,
    slippage: float = 0.0,
    upon_bar_close: bool = True,
)

# Stop methods
config.set_fixed_stop(percent: float)
config.set_atr_stop(multiplier: float, period: int)
config.set_trailing_stop(percent: float)

# Target methods
config.set_fixed_target(percent: float)
config.set_atr_target(multiplier: float, period: int)
config.set_risk_reward_target(ratio: float)

PyInstrumentConfig

Per-instrument configuration for position sizing and risk management.

inst_config = raptorbt.PyInstrumentConfig(
    lot_size=1.0,              # Min tradeable quantity (1 for equity, 50 for NIFTY F&O)
    alloted_capital=50000.0,   # Capital allocated to this instrument (optional)
    existing_qty=None,         # Existing position quantity (future use)
    avg_price=None,            # Existing position avg price (future use)
)

# Optional: per-instrument stop/target overrides
inst_config.set_fixed_stop(0.02)
inst_config.set_trailing_stop(0.03)
inst_config.set_fixed_target(0.05)

Fields:

  • lot_size - Minimum tradeable quantity. Position sizes are rounded down to nearest lot_size multiple. Use 1.0 for equities, 50.0 for NIFTY F&O, 0.01 for forex.
  • alloted_capital - Per-instrument capital cap (capped at available cash).
  • existing_qty / avg_price - Reserved for future live-to-backtest transitions.

PyBatchSpreadItem

item = raptorbt.PyBatchSpreadItem(
    strategy_id: str,                    # Unique identifier for this backtest
    legs_premiums: List[np.ndarray],     # Premium series per leg
    leg_configs: List[Tuple[str, float, int, int]],  # (option_type, strike, quantity, lot_size)
    entries: np.ndarray,                 # bool entry signals
    exits: np.ndarray,                   # bool exit signals
    spread_type: str = "custom",         # Spread type string
    max_loss: float = None,              # Optional max loss exit
    target_profit: float = None,         # Optional target profit exit
)

batch_spread_backtest

results = raptorbt.batch_spread_backtest(
    timestamps: np.ndarray,              # int64 nanosecond timestamps (shared)
    underlying_close: np.ndarray,        # Underlying close prices (shared)
    items: List[PyBatchSpreadItem],      # List of spread backtest items
    config: PyBacktestConfig = None,     # Optional shared config
) -> List[Tuple[str, PyBacktestResult]]  # (strategy_id, result) pairs

Runs all spread backtests in parallel via Rayon. Timestamps and underlying close are shared across all items and converted once. The GIL is released during execution for maximum Python concurrency.

simulate_portfolio_mc

result = raptorbt.simulate_portfolio_mc(
    returns: List[np.ndarray],               # Per-asset daily returns (N arrays)
    weights: np.ndarray,                     # Portfolio weights (length N, sum to 1)
    correlation_matrix: List[np.ndarray],    # N x N correlation matrix
    initial_value: float,                    # Starting portfolio value
    n_simulations: int = 10000,              # Number of Monte Carlo paths
    horizon_days: int = 252,                 # Forward projection horizon in days
    seed: int = 42,                          # Random seed for reproducibility
) -> dict

Returns a dictionary with keys: expected_return, probability_of_loss, var_95, cvar_95, percentile_paths, final_values.

PyBacktestResult

result = raptorbt.run_single_backtest(...)

# Attributes
result.metrics        # PyBacktestMetrics object

# Methods
result.equity_curve()    # numpy.ndarray
result.drawdown_curve()  # numpy.ndarray
result.returns()         # numpy.ndarray
result.trades()          # List[PyTrade]

PyBacktestMetrics

33 read-only fields — see the Metrics section for the full table with descriptions. metrics.to_dict() returns 24 of them under human-readable labels (e.g. "Sharpe Ratio") for quick display; read fields off the object directly for the complete set.

m = result.metrics
m.total_return_pct, m.sharpe_ratio, m.max_drawdown_pct   # etc. — 33 fields total
stats = m.to_dict()

PyTrade

for trade in result.trades():
    print(trade.id)           # Trade ID
    print(trade.symbol)       # Symbol
    print(trade.entry_idx)    # Entry bar index
    print(trade.exit_idx)     # Exit bar index
    print(trade.entry_price)  # Entry price
    print(trade.exit_price)   # Exit price
    print(trade.size)         # Position size
    print(trade.direction)    # 1=Long, -1=Short
    print(trade.pnl)          # Profit/Loss
    print(trade.return_pct)   # Return percentage
    print(trade.fees)         # Fees paid
    print(trade.exit_reason)  # "Signal", "StopLoss", "TakeProfit", "TrailingStop", "EndOfData", "Settlement", "TimeExit"

Building from Source

Most users should pip install raptorbt. To build the engine yourself you need Rust 1.70+, Python 3.10+, and maturin:

cd raptorbt
maturin develop --release   # editable install into the active venv
cargo test                  # run the Rust test suite

Verification Test

A seeded smoke test — run it twice and the result is identical to the last decimal (the determinism guarantee):

import numpy as np
import raptorbt

np.random.seed(42)
n = 500
close = np.cumprod(1 + np.random.randn(n) * 0.02) * 100
entries = np.zeros(n, dtype=bool); entries[::20] = True
exits = np.zeros(n, dtype=bool);  exits[10::20] = True

config = raptorbt.PyBacktestConfig(initial_capital=100000, fees=0.001)
result = raptorbt.run_single_backtest(
    timestamps=np.arange(n, dtype=np.int64),
    open=close,
    high=close,
    low=close,
    close=close,
    volume=np.ones(n),
    entries=entries,
    exits=exits,
    direction=1,
    weight=1.0,
    symbol="TEST",
    config=config,
)
print(f"Total Return: {result.metrics.total_return_pct:.4f}%")  # -30.6192%
print(f"Sharpe Ratio: {result.metrics.sharpe_ratio:.4f}")       # -0.9086

License

MIT License - see LICENSE for details.


Changelog

v0.4.0

Tick-level backtesting — full tick resolution, no bar resampling.

  • Add TickData struct — parallel arrays of timestamps, ltp, bid, ask, buy_qty_delta, sell_qty_delta, oi (one element per tick). Callers must pre-convert Zerodha cumulative session totals to per-tick deltas before passing.
  • Add ExitReason::TimeExit — max hold-time exceeded exit for tick strategies.
  • Add run_tick_backtest — tick-native simulation engine. Entry fills at ask+slippage; stop/target checked against ltp on every tick (not OHLC approximation); max-hold-seconds time exit; configurable cooldown between entries. Returns the same PyBacktestResult / PyBacktestMetrics (33 fields) as all other strategy types.
  • Add compute_tick_entry_signals — compute momentum entry bool array from precomputed feature arrays (spread gate, delta BSI gate, 1-min return gate, cooldown enforcement). O(N) single pass.
  • Add compute_tick_exit_signals — time-based (EOD) exit bool array from tick timestamps.
  • Add tick_spread_pct — per-tick bid/ask spread as percentage of mid price.
  • Add buy_sell_imbalance_delta — per-tick delta BSI from Zerodha cumulative running sums. Fixes the raw-cumulative BSI artefact (~0.95 all day regardless of order flow).
  • Add return_window — per-tick lookback return over a configurable time window using binary search (O(N log N)). Returns NaN where history is insufficient — correctly gates the entry filter rather than silently passing.
  • Add realized_vol_rolling — rolling realized volatility proxy (stddev of log-returns) over a time window.
  • Add oi_position_pct — OI position within the day's high/low range, per tick: [0, 100].
  • Add tick_velocity — rolling tick count per minute over a configurable time window.
  • Expose compute_backtest_metrics as a public free function in portfolio::engine — non-OHLCV strategy types can produce identical metrics without duplicating the calculation logic.

v0.3.4

  • Add single-leg option spread types: LongCall, LongPut, NakedCall, NakedPut to SpreadType enum
  • Add ExitReason::Settlement for option expiry settlement exits
  • Add leg_expiry_timestamps parameter to run_spread_backtest for per-leg expiry tracking
  • Positions are force-closed at settlement when any leg expires, with premiums replaced by intrinsic value
  • Prevent re-entry after all legs have expired

v0.3.3

  • Add batch_spread_backtest function for running multiple spread backtests in parallel via Rayon
  • Add PyBatchSpreadItem class for defining individual items in a batch spread backtest
  • Shared data (timestamps, underlying close) is converted once and reused across all items
  • GIL released during parallel execution for maximum Python concurrency
  • Each item carries its own strategy_id, leg configs, signals, spread type, and optional max loss / target profit
  • Returns a list of (strategy_id, PyBacktestResult) tuples preserving result-to-input mapping

v0.3.2

  • Add payoff_ratio metric to BacktestMetrics — average winning trade return divided by average losing trade return (absolute), measures risk/reward per trade
  • Add recovery_factor metric to BacktestMetrics — net profit divided by maximum drawdown in absolute terms, measures how many times over the strategy recovered from its worst drawdown
  • Both metrics computed in StreamingMetrics::finalize() (single-instrument backtest) and PortfolioEngine (multi-strategy aggregation)
  • Both metrics exposed via PyO3 as #[pyo3(get)] attributes on PyBacktestMetrics
  • Handles edge cases: returns f64::INFINITY when denominator is zero with positive numerator, 0.0 otherwise

v0.3.1

  • Add Monte Carlo portfolio simulation (simulate_portfolio_mc) for forward risk projection
  • Geometric Brownian Motion (GBM) with Cholesky decomposition for correlated multi-asset simulation
  • Rayon-parallelized simulation paths with deterministic seeding (xoshiro256**)
  • Returns percentile paths (P5/P25/P50/P75/P95), VaR, CVaR, expected return, and probability of loss
  • GIL released during simulation for maximum Python concurrency

v0.3.0

  • Per-instrument configuration via PyInstrumentConfig (lot_size, alloted_capital, stop/target overrides)
  • Position sizes now correctly rounded to lot_size multiples
  • Support for per-instrument capital allocation in basket backtests
  • Future-ready fields: existing_qty, avg_price for live-to-backtest transitions

v0.2.2

  • Export run_spread_backtest Python binding for multi-leg options spread strategies
  • Export rolling_min and rolling_max indicator functions to Python

v0.2.1

  • Add rolling_min and rolling_max indicators for LLV (Lowest Low Value) and HHV (Highest High Value) support
  • NaN handling for warmup period

v0.2.0

  • Add multi-leg spread backtesting (run_spread_backtest) supporting straddles, strangles, vertical spreads, iron condors, iron butterflies, butterfly spreads, calendar spreads, and diagonal spreads
  • Coordinated entry/exit across all legs with net premium P&L calculation
  • Max loss and target profit exit thresholds for spreads
  • Add SessionTracker for intraday session management: market hours detection, squareoff time enforcement, session high/low/open tracking
  • Pre-built session configs for NSE equity (9:15-15:30), MCX commodity (9:00-23:30), and CDS currency (9:00-17:00)
  • Extend StreamingMetrics with equity/drawdown tracking, trade recording, and finalize() method

v0.1.0

  • Initial release
  • 5 strategy types: single, basket, pairs, options, multi
  • 30+ performance metrics: Sharpe, Sortino, Calmar, Omega, SQN, profit factor, drawdown duration, and more
  • 10 technical indicators (SMA, EMA, RSI, MACD, Stochastic, ATR, Bollinger Bands, ADX, VWAP, Supertrend)
  • Stop-loss management: fixed, ATR-based, and trailing stops
  • Take-profit management: fixed, ATR-based, and risk-reward targets
  • PyO3 Python bindings for seamless Python integration

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

raptorbt-0.4.1.tar.gz (124.2 kB view details)

Uploaded Source

Built Distributions

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

raptorbt-0.4.1-cp312-cp312-win_amd64.whl (426.7 kB view details)

Uploaded CPython 3.12Windows x86-64

raptorbt-0.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (483.4 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

raptorbt-0.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (449.8 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

raptorbt-0.4.1-cp312-cp312-macosx_11_0_arm64.whl (430.6 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

raptorbt-0.4.1-cp312-cp312-macosx_10_12_x86_64.whl (455.2 kB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

raptorbt-0.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (485.2 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

raptorbt-0.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (451.7 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

raptorbt-0.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (485.1 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

raptorbt-0.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (451.8 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64

File details

Details for the file raptorbt-0.4.1.tar.gz.

File metadata

  • Download URL: raptorbt-0.4.1.tar.gz
  • Upload date:
  • Size: 124.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for raptorbt-0.4.1.tar.gz
Algorithm Hash digest
SHA256 a61d3af686f8856af930d20e634c40426df013b14470ba4e6ce9e3bae1a4bda8
MD5 57735848b0ed3e4686e89de598a49cab
BLAKE2b-256 ad92b7c05fcaa93880cf87f5d1bded95c47f72da32a5b706ea8173180b08695b

See more details on using hashes here.

Provenance

The following attestation bundles were made for raptorbt-0.4.1.tar.gz:

Publisher: release.yml on alphabench/raptorbt

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

File details

Details for the file raptorbt-0.4.1-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: raptorbt-0.4.1-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 426.7 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for raptorbt-0.4.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 75173e0aa41c4b8ced43fb177218411f7536dfd4681c671be0c69b003d44eb8e
MD5 c28bc5f588225081b2c73f3f62871427
BLAKE2b-256 cd11c1eca8193872e663a60d7373b3ed348f032e41302917fedf06cc3faab4d2

See more details on using hashes here.

Provenance

The following attestation bundles were made for raptorbt-0.4.1-cp312-cp312-win_amd64.whl:

Publisher: release.yml on alphabench/raptorbt

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

File details

Details for the file raptorbt-0.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for raptorbt-0.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 335ec3e38a80f51b90a83a82d3c6c7bbcdea3fa2c38efaa7d2209e18c64a562f
MD5 c07b3873c535ba195386da80fe3b4692
BLAKE2b-256 aaee5e9d3c65173b212d362336f0b5fb83873111148b876d24a9ded39d75b402

See more details on using hashes here.

Provenance

The following attestation bundles were made for raptorbt-0.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on alphabench/raptorbt

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

File details

Details for the file raptorbt-0.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for raptorbt-0.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 be31ad995c349c31290e3264d11981d2fcc4eb6904fc950cb09b70bf9e3ab34c
MD5 82e17dba4d4cb4720db830f82e863158
BLAKE2b-256 b0c95b97373c043848e80ce632653fbc21dd32b62ea3749fbf5e1bb869611dd2

See more details on using hashes here.

Provenance

The following attestation bundles were made for raptorbt-0.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on alphabench/raptorbt

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

File details

Details for the file raptorbt-0.4.1-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for raptorbt-0.4.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1be83aae7fd3f8f4053362ff933c64713b4600d571ec05607d6c6c2362113456
MD5 59ac378d0ee39e074f1cdd89e73bbaa1
BLAKE2b-256 bfd851a6eb085133d5132572b931a2dfedceb6d1124ab5d118bb51eeb4e2e7f0

See more details on using hashes here.

Provenance

The following attestation bundles were made for raptorbt-0.4.1-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on alphabench/raptorbt

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

File details

Details for the file raptorbt-0.4.1-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for raptorbt-0.4.1-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 816b3d87eec5db754c609a0076fbc6632f70c7aed4aa670aec9fcf72dfb5e698
MD5 4cf797d23309ef636e39a4faf6b5bd5e
BLAKE2b-256 1a1c62b13af87830b04075fbf293119f32f239ee869f32ff97d15ef0e425c522

See more details on using hashes here.

Provenance

The following attestation bundles were made for raptorbt-0.4.1-cp312-cp312-macosx_10_12_x86_64.whl:

Publisher: release.yml on alphabench/raptorbt

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

File details

Details for the file raptorbt-0.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for raptorbt-0.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5dc53b8cfc4dfc8adcaf314a15ce6e8af0ae7782b364f97a750d073424eafa0a
MD5 5ddd76204416345b43a4299d4f0e6393
BLAKE2b-256 cd336dfd1ce087aa289a4b9768e4bf1e34ed47d46905e8005fd9c9a198542b18

See more details on using hashes here.

Provenance

The following attestation bundles were made for raptorbt-0.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on alphabench/raptorbt

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

File details

Details for the file raptorbt-0.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for raptorbt-0.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e6e193f0aa4fb35bf520df202e1a0a7aa536ef8ec6e67516bb86dd181ba9571e
MD5 106fb49134a58cfffb8ab94939912542
BLAKE2b-256 0ae9ea31ffc3cfdf3b00c2244d49bfbf23bead3286e6755cc756f82313af735f

See more details on using hashes here.

Provenance

The following attestation bundles were made for raptorbt-0.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on alphabench/raptorbt

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

File details

Details for the file raptorbt-0.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for raptorbt-0.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6b7e3f533e008911c26b4d4835b1c7201424b8a6f259ae53b2da0a5244afd87d
MD5 75cf739bf5fc4d47c3454260f2b4f65f
BLAKE2b-256 704d41b73130a9e758d8b17ebcc8d147f693cb2ef06b360f54f91c5ffb71e26b

See more details on using hashes here.

Provenance

The following attestation bundles were made for raptorbt-0.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on alphabench/raptorbt

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

File details

Details for the file raptorbt-0.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for raptorbt-0.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 a1c3be81e30420c7512fbb5a4586f91434131377f09f070c706477d3fccd5a8c
MD5 9051aca43e5c255ae40aefa24e76273b
BLAKE2b-256 a19ba140aad386ac754be7b5ebf6803b68495c9135856652fd94c22073f987c4

See more details on using hashes here.

Provenance

The following attestation bundles were made for raptorbt-0.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on alphabench/raptorbt

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