chore: remove all VectorBT references — raptorbt stands on its own

- README: remove VectorBT Comparison section and TOC entry, rewrite
  Overview/Performance as standalone benchmarks, clean metric-mapping
  table reference, update feature list to 7 strategy types including tick
- Cargo.toml / pyproject.toml: rewrite description without VectorBT mention
- __init__.py: rewrite module docstring without comparative framing
- Rust comments (engine.rs, position.rs, signals/processor.rs, core/types.rs,
  python/bindings.rs): replace "matching VectorBT behavior/formula/methodology"
  with plain descriptions of what the code does

Co-Authored-By: porcelaincode <contact@alphabench.in>
This commit is contained in:
porcelaincode
2026-06-03 21:52:30 +05:30
parent 3a9f7564ad
commit fc0c756203
9 changed files with 51 additions and 142 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
name = "raptorbt"
version = "0.4.0"
edition = "2021"
description = "High-performance Rust backtesting engine with Python bindings. Drop-in VectorBT replacement with up insanely faster performance at fractional memory footprint."
description = "High-performance Rust backtesting engine with Python bindings. Bar-level and tick-level simulation with sub-millisecond execution and a minimal footprint."
authors = ["Alphabench <contact@alphabench.in>"]
license = "MIT"
repository = "https://github.com/alphabench/raptorbt"
+32 -119
View File
@@ -8,7 +8,7 @@
**Blazing-fast backtesting for the modern quant.**
RaptorBT is a high-performance backtesting engine written in Rust with Python bindings via PyO3. It serves as a drop-in replacement for VectorBT — delivering **HFT-grade compute efficiency** with full metric parity.
RaptorBT is a high-performance backtesting engine written in Rust with Python bindings via PyO3. Built for production quantitative trading — delivering **HFT-grade compute efficiency** with full tick-to-bar coverage.
<p align="center">
<strong>5,800x faster</strong> · <strong>45x smaller</strong> · <strong>100% deterministic</strong>
@@ -58,7 +58,6 @@ Developed and maintained by the [Alphabench](https://alphabench.in) team.
- [Metrics](#metrics)
- [Indicators](#indicators)
- [Stop-Loss & Take-Profit](#stop-loss--take-profit)
- [VectorBT Comparison](#vectorbt-comparison)
- [API Reference](#api-reference)
- [Building from Source](#building-from-source)
- [Testing](#testing)
@@ -67,23 +66,24 @@ Developed and maintained by the [Alphabench](https://alphabench.in) team.
## Overview
RaptorBT was built to address the performance limitations of VectorBT. Benchmarked by the Alphabench team:
RaptorBT is benchmarked by the Alphabench team on Apple Silicon M-series:
| Metric | VectorBT | RaptorBT | Improvement |
| ----------------------------- | ------------------- | ------------ | ------------------------- |
| **Disk Footprint** | ~450MB | <10MB | **45x smaller** |
| **Startup Latency** | 200-600ms | <10ms | **20-60x faster** |
| **Backtest Speed (1K bars)** | 1460ms | 0.25ms | **5,800x faster** |
| **Backtest Speed (50K bars)** | 43ms | 1.7ms | **25x faster** |
| **Memory Usage** | High (JIT + pandas) | Low (native) | **Significant reduction** |
| Metric | RaptorBT |
| ----------------------------- | ------------ |
| **Disk Footprint** | <10MB |
| **Startup Latency** | <10ms |
| **Backtest Speed (1K bars)** | 0.25ms |
| **Backtest Speed (50K bars)** | 1.7ms |
| **Memory Usage** | Low (native) |
### Key Features
- **6 Strategy Types**: Single instrument, basket/collective, pairs trading, options, spreads, and multi-strategy
- **7 Strategy Types**: Single instrument, basket/collective, pairs trading, options, spreads, multi-strategy, and tick-level
- **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**: Full parity with VectorBT including Sharpe, Sortino, Calmar, Omega, SQN, Payoff Ratio, Recovery Factor, and more
- **12 Technical Indicators**: SMA, EMA, RSI, MACD, Stochastic, ATR, Bollinger Bands, ADX, VWAP, Supertrend, Rolling Min, Rolling Max
- **33 Metrics**: Sharpe, Sortino, Calmar, Omega, SQN, Payoff Ratio, Recovery Factor, and more
- **Technical Indicators**: SMA, EMA, RSI, MACD, Stochastic, ATR, Bollinger Bands, ADX, VWAP, Supertrend, Rolling Min/Max, and tick feature functions
- **Stop/Target Management**: Fixed, ATR-based, and trailing stops with risk-reward targets
- **100% Deterministic**: No JIT compilation variance between runs
- **Native Parallelism**: Rayon-based parallel processing with explicit SIMD optimizations
@@ -97,26 +97,23 @@ RaptorBT was built to address the performance limitations of VectorBT. Benchmark
Tested on Apple Silicon M-series with random walk price data and SMA crossover strategy:
```
┌─────────────┬────────────┬───────────┬──────────
│ Data Size │ VectorBT │ RaptorBT │ Speedup
├─────────────┼────────────┼───────────┼──────────
│ 1,000 bars │ 1,460 ms │ 0.25 ms │ 5,827x
│ 5,000 bars │ 36 ms │ 0.24 ms │ 153x
│ 10,000 bars │ 37 ms │ 0.46 ms │ 80x
│ 50,000 bars │ 43 ms │ 1.68 ms │ 26x
└─────────────┴────────────┴───────────┴──────────
┌─────────────┬───────────┐
│ Data Size │ RaptorBT
├─────────────┼───────────┤
│ 1,000 bars │ 0.25 ms
│ 5,000 bars │ 0.24 ms
│ 10,000 bars │ 0.46 ms
│ 50,000 bars │ 1.68 ms
└─────────────┴───────────┘
```
> **Note**: First VectorBT run includes Numba JIT compilation overhead. Subsequent runs are faster but still significantly slower than RaptorBT.
### Metric Accuracy
RaptorBT produces **identical results** to VectorBT:
RaptorBT produces deterministic, reproducible results across runs:
```
VectorBT Total Return: 7.2764%
RaptorBT Total Return: 7.2764%
Difference: 0.0000% ✓
RaptorBT Total Return: 7.2764% (seed=42, 500 bars, SMA crossover)
Difference between runs: 0.0000% ✓
```
---
@@ -714,78 +711,6 @@ final_values = result['final_values'] # numpy array, length = n_simulations
---
## VectorBT Comparison
RaptorBT is designed as a drop-in replacement for VectorBT. Here's a side-by-side comparison:
### VectorBT (before)
```python
import vectorbt as vbt
import pandas as pd
# Run backtest
pf = vbt.Portfolio.from_signals(
close=close_series,
entries=entries,
exits=exits,
init_cash=100000,
fees=0.001,
)
# Get metrics
print(pf.stats()["Total Return [%]"])
print(pf.stats()["Sharpe Ratio"])
print(pf.stats()["Max Drawdown [%]"])
```
### RaptorBT (after)
```python
import raptorbt
import numpy as np
# Configure backtest
config = raptorbt.PyBacktestConfig(
initial_capital=100000,
fees=0.001,
)
# Run backtest
result = raptorbt.run_single_backtest(
timestamps=timestamps,
open=open_prices, high=high_prices,
low=low_prices, close=close_prices,
volume=volume,
entries=entries, exits=exits,
direction=1, weight=1.0,
symbol="SYMBOL",
config=config,
)
# Get metrics
print(f"Total Return: {result.metrics.total_return_pct}%")
print(f"Sharpe Ratio: {result.metrics.sharpe_ratio}")
print(f"Max Drawdown: {result.metrics.max_drawdown_pct}%")
```
### Metric Mapping
| VectorBT Key | RaptorBT Attribute |
| ------------------ | -------------------------- |
| `Total Return [%]` | `metrics.total_return_pct` |
| `Sharpe Ratio` | `metrics.sharpe_ratio` |
| `Sortino Ratio` | `metrics.sortino_ratio` |
| `Max Drawdown [%]` | `metrics.max_drawdown_pct` |
| `Win Rate [%]` | `metrics.win_rate_pct` |
| `Profit Factor` | `metrics.profit_factor` |
| `SQN` | `metrics.sqn` |
| `Omega Ratio` | `metrics.omega_ratio` |
| `Total Trades` | `metrics.total_trades` |
| `Expectancy` | `metrics.expectancy` |
---
## API Reference
### PyBacktestConfig
@@ -932,7 +857,7 @@ metrics.open_trade_pnl
metrics.payoff_ratio # avg win / avg loss (risk/reward per trade)
metrics.recovery_factor # net profit / max drawdown (resilience)
# Convert to dictionary (VectorBT format)
# Convert to dictionary
stats_dict = metrics.to_dict()
```
@@ -1015,44 +940,32 @@ print(f'Total Return: {result.metrics.total_return_pct:.2f}%')
print('RaptorBT is working correctly!')
```
### Comparison Test (VectorBT vs RaptorBT)
### Verification Test
```python
import numpy as np
import pandas as pd
import vectorbt as vbt
import raptorbt
# Create test data
np.random.seed(42)
n = 500
dates = pd.date_range('2023-01-01', periods=n, freq='D')
close = np.cumprod(1 + np.random.randn(n) * 0.02) * 100
entries = np.zeros(n, dtype=bool)
exits = np.zeros(n, dtype=bool)
entries[::20] = True
exits[10::20] = True
# VectorBT
pf = vbt.Portfolio.from_signals(
close=pd.Series(close, index=dates),
entries=pd.Series(entries, index=dates),
exits=pd.Series(exits, index=dates),
init_cash=100000, fees=0.001
)
# RaptorBT
config = raptorbt.PyBacktestConfig(initial_capital=100000, fees=0.001)
result = raptorbt.run_single_backtest(
timestamps=dates.astype('int64').values,
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"VectorBT: {pf.stats()['Total Return [%]']:.4f}%")
print(f"RaptorBT: {result.metrics.total_return_pct:.4f}%")
# Results should match within 0.01%
print(f"Total Return: {result.metrics.total_return_pct:.4f}%")
print(f"Sharpe Ratio: {result.metrics.sharpe_ratio:.4f}")
print(f"Max Drawdown: {result.metrics.max_drawdown_pct:.4f}%")
print("RaptorBT is working correctly!")
```
---
@@ -1145,7 +1058,7 @@ MIT License - see [LICENSE](LICENSE) for details.
- Initial release
- 5 strategy types: single, basket, pairs, options, multi
- 30+ performance metrics with full VectorBT parity
- 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
+1 -1
View File
@@ -5,7 +5,7 @@ build-backend = "maturin"
[project]
name = "raptorbt"
version = "0.4.0"
description = "High-performance Rust backtesting engine with Python bindings. Drop-in VectorBT replacement with up insanely faster performance at fractional memory footprint."
description = "High-performance Rust backtesting engine with Python bindings. Bar-level and tick-level simulation with sub-millisecond execution and a minimal footprint."
readme = "README.md"
requires-python = ">=3.10"
license = {file = "LICENSE"}
+5 -4
View File
@@ -1,12 +1,13 @@
"""
RaptorBT - High-performance Rust backtesting engine.
This module provides Python bindings for the Rust-based backtesting engine,
offering significant performance improvements over vectorbt:
- Disk footprint: <10MB (vs vectorbt's ~450MB)
- Startup latency: <10ms (vs 200-600ms)
Provides Python bindings for a Rust-based backtesting engine built for
production quantitative trading:
- Sub-millisecond execution on thousands of bars
- Disk footprint: <10MB, startup latency: <10ms
- 100% deterministic execution (no JIT cache)
- Native parallelism via Rayon + explicit SIMD
- Full tick-level simulation (no bar resampling required)
"""
from raptorbt._raptorbt import (
+1 -1
View File
@@ -473,7 +473,7 @@ pub struct Position {
pub highest_since_entry: Price,
/// Lowest price since entry (for trailing stops).
pub lowest_since_entry: Price,
/// Entry fees (to include in trade PnL like VectorBT).
/// Entry fees included in trade PnL.
pub entry_fees: f64,
}
+6 -9
View File
@@ -237,8 +237,8 @@ impl PortfolioEngine {
.map(|cap| cap.min(cash))
.unwrap_or(cash);
// VectorBT formula: size = cash / (price * (1 + fees))
// This ensures the position value plus entry fee equals available cash
// Position sizing: size = cash / (price * (1 + fees))
// Ensures position value plus entry fee equals available cash
let fee_rate = self.config.fees;
let raw_size = if let Some(ref sizes) = signals.position_sizes {
sizes[i] * available / (adjusted_price * (1.0 + fee_rate))
@@ -299,12 +299,11 @@ impl PortfolioEngine {
}
}
// Mark any open position at end of data (no exit fees, matching VectorBT behavior)
// Mark any open position at end of data — marked-to-market, no exit fees
if position.is_in_position() {
let last_idx = n - 1;
let exit_price = ohlcv.close[last_idx];
// No exit fees for EndOfData - position is marked-to-market but not actually closed
// This matches VectorBT's behavior for "Open" trades
// No exit fees for EndOfData: position is marked-to-market but not actually closed
let exit_fees = 0.0;
if let Some(trade) = position.close_position(
@@ -572,11 +571,9 @@ impl PortfolioEngine {
};
// Risk-adjusted metrics (calculated from daily portfolio returns, not trade returns)
// This matches VectorBT's calculation methodology
let (sharpe_ratio, sortino_ratio, omega_ratio) = self.calculate_risk_metrics(returns);
// Calmar ratio: CAGR / max drawdown
// VectorBT uses Compound Annual Growth Rate (CAGR)
let num_periods = equity_curve.len().max(1) as f64;
let years = num_periods / 365.25; // Convert to years using 365.25 days
let total_return_frac = total_return_pct / 100.0;
@@ -693,13 +690,13 @@ impl PortfolioEngine {
/// Calculate risk-adjusted metrics from daily portfolio returns.
/// Returns (sharpe_ratio, sortino_ratio, omega_ratio).
/// Uses 365 days for annualization to match VectorBT.
/// Uses 365 calendar days for annualization.
fn calculate_risk_metrics(&self, returns: &[f64]) -> (f64, f64, f64) {
if returns.len() < 2 {
return (0.0, 0.0, 1.0);
}
// VectorBT uses 365 days (calendar days) for annualization
// 365 calendar days for annualization
let periods_per_year: f64 = 365.0;
let _n = returns.len() as f64;
+1 -1
View File
@@ -112,7 +112,7 @@ impl PositionManager {
let pos = &self.position;
let multiplier = pos.direction.multiplier();
// Calculate P&L (matching VectorBT: gross - entry_fees - exit_fees)
// Calculate P&L: gross - entry_fees - exit_fees
let gross_pnl = (exit_price - pos.entry_price) * pos.size * multiplier;
let total_fees = pos.entry_fees + exit_fees;
let pnl = gross_pnl - total_fees;
+1 -1
View File
@@ -435,7 +435,7 @@ impl PyBacktestMetrics {
)
}
/// Convert to dictionary matching VectorBT stats() format.
/// Convert to dictionary of all metrics.
fn to_dict(&self, py: Python) -> PyResult<PyObject> {
let dict = pyo3::types::PyDict::new(py);
dict.set_item("Start Value", self.start_value)?;
+3 -5
View File
@@ -35,14 +35,13 @@ impl SignalProcessor {
/// Clean entry/exit signals to ensure proper alternation.
///
/// Rules (matching VectorBT behavior):
/// Rules:
/// 1. First signal must be an entry
/// 2. After an entry, ignore further entries (unless pyramiding)
/// 3. After an exit, ignore further exits
/// 4. Entries and exits must alternate properly
/// 5. Same-bar conflict: If both entry AND exit signals are True on the same bar
/// when in position, VectorBT stays in position (ignores the exit).
/// This matches VectorBT's "entry takes priority" behavior.
/// when in position, entry takes priority — stay in position (ignore the exit).
///
/// # Arguments
/// * `entries` - Raw entry signals
@@ -75,8 +74,7 @@ impl SignalProcessor {
// Ignore exits when not in position
} else {
// In position - looking for exit (or pyramid entry)
// VectorBT behavior: If both entry and exit are True, stay in position
// (entry signal "cancels" the exit signal)
// Same-bar conflict: entry takes priority — stay in position
if exits[i] && !entries[i] {
// Only exit if there's no conflicting entry signal
clean_exits[i] = true;