Skip to main content

High-performance Python backtesting engine powered by Numba JIT, with indicators, optimization, walk-forward validation, and reporting

Project description

NeutrinoBT

CI Python 3.12+ License: MIT

A high-performance Python backtesting library powered by Numba JIT.

NeutrinoBT runs your trading strategies fast — the core engine is compiled to machine code via Numba so that even large parameter sweeps complete in seconds. The API is modeled after Pine Script, so moving from TradingView concepts to Python is straightforward.


Features

Core Engine

  • Numba JIT backtesting@njit(cache=True) compiled execution loop; orders, stops, and equity curves computed at native speed
  • Two signal modes — vectorized (NumPy arrays) for simple strategies; Pine Script-style order API (order(), exit(), cancel()) for complex logic
  • Multiple positions — FIFO, LIFO, or BY_ID close selection; configurable max_positions
  • Stops & exits — per-trade stop loss, take profit, and trailing stops (activation by price or points)
  • Leverage & liquidation — configurable leverage with automatic liquidation price calculation
  • Entry on bar close — optional entry_on_bar_close=True fills at next bar open (matches Pine Script strategy.entry behaviour)
  • Commission & slippage — applied separately to entries and stops

Indicators (self.I / nt.*)

25+ built-in indicators, all Numba-accelerated, organized into five categories:

Category Indicators
Moving Averages EMA, SMA, RMA, WMA, DEMA, TEMA, HMA, VWMA
Momentum RSI, MACD, Stoch, StochRSI, CCI, Williams %R, ADX, MFI
Volatility ATR, STDEV, SuperTrend, Bollinger Bands, Keltner Channel, Donchian Channel
Trend Parabolic SAR, Ichimoku Cloud, Linear Regression
Volume OBV, VWAP

All indicators support a timeframe= parameter for multi-timeframe analysis without look-ahead bias.

Optimization

  • Grid search — exhaustive sweep over all parameter combinations
  • Random search — sampled trials with reproducible seeds
  • Parallel workersn_jobs= via multiprocessing.Pool (Windows-safe)
  • Built-in objectivesnet_profit, sharpe, profit_factor, gt_score, negative_max_drawdown; or pass any callable

Statistics

Professional-grade metrics in the style of TradingView's Strategy Tester: Net Profit, Gross Profit/Loss, Profit Factor, Sharpe, Sortino, Calmar, Max Drawdown, PROM, GT-Score, Win Rate, Avg Win/Loss, Avg Bars in Trade, CAGR, T-Test — all broken down by All / Long / Short.

Jupyter / In-Notebook Visualization

  • plot_equity — equity curve chart from mark-to-market or trade-step fallback
  • plot_drawdown — underwater / drawdown chart (% from running peak)
  • plot_price_with_trades — close price overlaid with long/short entry & exit markers
  • display_statistics_summary — styled statistics table rendered inline in Jupyter
  • QuantStats exportquantstats_returns() converts the equity curve to per-bar decimal returns compatible with the QuantStats tear-sheet library (optional install)

Dashboard & Export

  • HTML dashboard — self-contained interactive report with TradingView price chart, equity curve, drawdown, returns heatmap, MFE/MAE scatter, and paginated trade log
  • Pine Script export — generate a Pine Script indicator from your strategy's signals
  • CSV export — statistics table and full trade list

Performance

Benchmark: EMA(12/26) crossover strategy, 8,640 rows of BTCUSDT 30 m data, measured at 10 / 100 / 1,000 repeated runs (Numba JIT pre-warmed).

Engine Avg time / run × NeutrinoBT × backtrader
Hardcoded (raw NumPy) ~1 ms 22× faster 1,090× faster
NeutrinoBT ~22 ms ~50× faster
backtesting.py ~77 ms 3.5× slower 14× faster
backtrader ~1,090 ms 50× slower

NeutrinoBT is only ~22× behind a raw NumPy loop (the theoretical floor) while delivering a production-grade framework: stops, leverage, multi-position, full statistics, and HTML export. At 1,000-parameter-sweep scale, backtrader takes ~18 min total vs ~22 s for NeutrinoBT.

Source: backtesting-showcase.ipynb in the repo root. Results vary by CPU; the first per-session run includes Numba JIT compilation (~1–2 s one-time cost).


Installation

# Using uv (recommended)
uv pip install neutrinobt

# Or with pip
pip install neutrinobt

Requirements: Python 3.12+, NumPy, Numba, Pandas, Polars, Jinja2, Matplotlib

Optional extras:

# Development tools from a source checkout (JupyterLab, pytest, ruff)
uv sync --group dev

# Binance / CCXT data downloader helpers
pip install "neutrinobt[data]"

# QuantStats tear sheets (pulls scipy, seaborn, yfinance)
pip install "neutrinobt[analytics]"

# Parquet-backed WFO trade stores
pip install "neutrinobt[wfo]"

# Everything optional
pip install "neutrinobt[all]"

Quick Start

import numpy as np
from neutrinobt.data.loader import CSVLoader
from neutrinobt.strategy.base import Strategy
from neutrinobt.core.reactor import Reactor
import neutrinobt.indicators as nt

# 1. Load OHLCV data
loader = CSVLoader("sampledata/BTCUSDTUSDT/1h.csv")
bars = loader.load({
    "time": "timestamp", "open": "open", "high": "high",
    "low": "low", "close": "close", "volume": "volume",
})

# 2. Define a strategy
class EMACrossover(Strategy):
    def init(self):
        self.ema_fast = self.I.EMA(20)
        self.ema_slow = self.I.EMA(50)

    def generate_signals(self):
        valid = ~(np.isnan(self.ema_fast) | np.isnan(self.ema_slow))
        self.buy_cond(nt.crossover(self.ema_fast, self.ema_slow) & valid)
        self.sell_cond(nt.crossunder(self.ema_fast, self.ema_slow) & valid)

    def create_reactor(self):
        return Reactor(bars, initial_balance=10_000.0, commission_rate=0.001)

# 3. Run
results = EMACrossover(bars).run(show_summary=True)
print(f"Final equity: ${results['final_equity']:,.2f}")

Jupyter Plotting

# Pass export_timeseries=True to record bar-by-bar equity
results = EMACrossover(bars).run(export_timeseries=True, show_summary=False)

from neutrinobt.notebook.plots import plot_equity, plot_drawdown, display_statistics_summary
from neutrinobt.notebook.quantstats_export import quantstats_returns

plot_equity(bars, equity_curve=results["equity_curve"])
plot_drawdown(bars, equity_curve=results["equity_curve"])
display_statistics_summary(results["statistics"])

# Export per-bar decimal returns ready for QuantStats
qs = quantstats_returns(bars=bars, equity_curve=results["equity_curve"])
# import quantstats; quantstats.reports.basic(qs.strategy, benchmark=qs.benchmark)

See examples/notebooks/09_jupyter_plotting.ipynb for a full walkthrough.


Tutorials

The examples/ folder is a step-by-step curriculum. Scripts 0108 cover the core engine; the notebooks/ subfolder has interactive Jupyter examples.

Scripts — run from the project root:

File Topic What you learn
01_getting_started.py First backtest Load data, validate, define a strategy, read results
02_strategy_basics.py Strategy class init(), generate_signals(), create_reactor(), statistics keys
03_indicators.py All 25+ indicators Every indicator category, standalone use, multi-timeframe
04_risk_management.py Risk controls Fixed/ATR stop loss & take profit, trailing stops, leverage, sizing
05_advanced_orders.py Order-based API order(), exit(), cancel(), limit/stop entries, multiple positions
06_optimization.py Parameter search Optimizer.run(), grid vs random, built-in objectives, parallel
07_dashboard_report.py HTML report export_html=True, generate_report(), all dashboard sections
08_real_world_strategy.py Full strategy Date range, warmup, production backtest, trade analysis
python examples/01_getting_started.py

Notebooks — open in JupyterLab (uv sync --group dev && uv run jupyter lab):

Notebook Topic What you learn
notebooks/09_jupyter_plotting.ipynb In-notebook visualization Equity curve, drawdown, trade markers, statistics table, QuantStats export

Architecture

neutrinobt/
├── core/
│   ├── reactor_core.py   # Numba @njit compiled engine (the hot loop)
│   ├── reactor.py        # Python wrapper — validation, results, statistics
│   └── statistics.py     # ~30 performance metrics
├── strategy/
│   └── base.py           # Strategy base class + IndicatorFactory (self.I)
├── indicators/           # 25+ @njit indicators
├── notebook/             # Jupyter helpers (no mandatory new deps)
│   ├── plots.py          # plot_equity, plot_drawdown, plot_price_with_trades, display_statistics_summary
│   └── quantstats_export.py  # quantstats_returns, export_quantstats_returns_csv
├── optimization/         # Optimizer — grid/random search
├── dashboard/            # HTML report generator (Jinja2 + ECharts)
├── export/               # Pine Script exporter
└── data/                 # CSVLoader, Resampler, validation

Execution flow:

  1. Strategy.init() — indicators computed, warmup tracked
  2. Strategy.generate_signals() — boolean arrays or Pine-style orders
  3. Reactor.run() — Numba JIT loop processes every bar: pending fills, trailing updates, liquidations, SL/TP, exits, entries
  4. Results — TradeList, Statistics, optional HTML report

Sample Data

CSV bars live under sampledata/<BASE>USDTUSDT/<timeframe>.csv. That directory is gitignored — fetch Binance USDT‑M perpetual OHLCV with CCXT:

uv sync --group data

# Default list: BTC, XRP, ETH, HYPE, BNB, DOGE — timeframes 30m, 1h, 2h
uv run --group data python scripts/fetch_binance_usdt_perp_ohlcv.py --output-dir sampledata

# Tests and ``research_pipeline/configs/datasets.json`` also expect daily BTC / XRP files:
uv run --group data python scripts/fetch_binance_usdt_perp_ohlcv.py --output-dir sampledata \
  --bases BTC XRP --timeframes 1d

See the script docstring for the exact default symbol/timeframe lists.


License

MIT — 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

neutrinobt-0.1.0.tar.gz (185.4 kB view details)

Uploaded Source

Built Distribution

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

neutrinobt-0.1.0-py3-none-any.whl (218.7 kB view details)

Uploaded Python 3

File details

Details for the file neutrinobt-0.1.0.tar.gz.

File metadata

  • Download URL: neutrinobt-0.1.0.tar.gz
  • Upload date:
  • Size: 185.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.9 {"installer":{"name":"uv","version":"0.11.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for neutrinobt-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5d9fc295ecb188a733907c98f914c7e16b2b30c476fb1162fc87b6798f3661a3
MD5 46ccefd8b416543d954d2e8187e93190
BLAKE2b-256 d5d4f95d2c52a76f7bd99959bb6fa00a8e4639b36ab396990bf0f8e269bfa7f3

See more details on using hashes here.

File details

Details for the file neutrinobt-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: neutrinobt-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 218.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.9 {"installer":{"name":"uv","version":"0.11.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for neutrinobt-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 52156b9a82bc24bdf54bd29542f4953faa2afd630635f5921e0b62073526c5d9
MD5 71494a20d9ec60b1c9623069a61fcb05
BLAKE2b-256 09b97aeea9d40e72bd625a2ae2789b64022a91e8a52b0aa202c7c8a99f646839

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