Metadata-Version: 2.3
Name: neutrinobt
Version: 0.2.1
Summary: High-performance Python backtesting engine powered by Numba JIT, with indicators, optimization, walk-forward validation, and reporting
Keywords: backtesting,algorithmic-trading,quantitative-finance,numba,pine-script,trading-strategy,technical-analysis
Author: KlaBuasom
Author-email: KlaBuasom <kla.buasom@gmail.com>
License: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial :: Investment
Classifier: Topic :: Scientific/Engineering
Requires-Dist: numba>=0.63.1
Requires-Dist: numpy>=1.26
Requires-Dist: pandas>=2.0
Requires-Dist: polars>=1.37.1
Requires-Dist: ccxt>=4.4.96 ; extra == 'all'
Requires-Dist: cupy-cuda12x>=14.1.1 ; extra == 'all'
Requires-Dist: cuda-python>=12.6,<13 ; extra == 'all'
Requires-Dist: jinja2>=3.1 ; extra == 'all'
Requires-Dist: matplotlib>=3.9.0 ; extra == 'all'
Requires-Dist: nvidia-cuda-nvcc-cu12>=12.6,<13 ; extra == 'all'
Requires-Dist: nvidia-cuda-runtime-cu12>=12.6,<13 ; extra == 'all'
Requires-Dist: quantstats>=0.0.62 ; extra == 'all'
Requires-Dist: quantstats>=0.0.62 ; extra == 'analytics'
Requires-Dist: ccxt>=4.4.96 ; extra == 'data'
Requires-Dist: cupy-cuda12x>=14.1.1 ; extra == 'gpu'
Requires-Dist: cuda-python>=12.6,<13 ; extra == 'gpu'
Requires-Dist: nvidia-cuda-nvcc-cu12>=12.6,<13 ; extra == 'gpu'
Requires-Dist: nvidia-cuda-runtime-cu12>=12.6,<13 ; extra == 'gpu'
Requires-Dist: jinja2>=3.1 ; extra == 'reporting'
Requires-Dist: matplotlib>=3.9.0 ; extra == 'reporting'
Requires-Python: >=3.12
Project-URL: Homepage, https://github.com/k1assify-dev/NeutrinoBT
Project-URL: Repository, https://github.com/k1assify-dev/NeutrinoBT
Project-URL: Issues, https://github.com/k1assify-dev/NeutrinoBT/issues
Project-URL: Documentation, https://github.com/k1assify-dev/NeutrinoBT#readme
Provides-Extra: all
Provides-Extra: analytics
Provides-Extra: data
Provides-Extra: gpu
Provides-Extra: reporting
Description-Content-Type: text/markdown

# NeutrinoBT

[![CI](https://github.com/KlaBuasom/NeutrinoBT/actions/workflows/ci.yml/badge.svg)](https://github.com/KlaBuasom/NeutrinoBT/actions/workflows/ci.yml)
[![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)

**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
- **Genetic optimizer (`GeneticOptimizer`)** — tournament selection, uniform crossover, per-gene mutation, elitism; for search spaces too large for grid search (100M+ combinations)
- **GPU-accelerated screening** — `backend="auto"/"gpu"/"cpu"` on `Optimizer.run()` / `GeneticOptimizer.run()`; a Numba CUDA kernel (`reactor_cuda.py`, one thread per backtest) screens every parameter set, then the top-K are re-run on the CPU reactor for the authoritative score. Falls back to CPU loudly if no CUDA toolkit is available — see [`docs/gpu_setup.md`](docs/gpu_setup.md)
- **Parallel workers** — `n_jobs=` via `multiprocessing.Pool` (Windows-safe)
- **Built-in objectives** — `net_profit`, `sharpe`, `profit_factor`, `gt_score`, `negative_max_drawdown`, `rto`, `prom`, `ars`; or pass any callable
- **SQLite result store (`OptimizeStore`)** — every trial (grid, random, or GA generation) persisted with stable parameter IDs and stats columns, so a long-running sweep can be queried live from another process

### 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 export** — `quantstats_returns()` converts the equity curve to per-bar decimal returns compatible with the [QuantStats](https://github.com/ranaroussi/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

### Walk-Forward Optimization (`neutrinobt.wfo`)
True walk-forward validation: per-window re-optimization with no look-ahead bias.
- **`run_rolling_wfo(...)`** — rolling train/test windows with per-window parameter search (CPU grid/random or GPU screening), followed by a single CPU ground-truth backtest on the test slice
- **Windowing** — compact horizon syntax (days/weeks/months/quarters/years); both train and test use explicit rolling boundaries
- **Built-in guardrails** — DSR (Deflated Sharpe Ratio), opt-in PBO (Probability of Backtest Overfitting) via fixed candidate list, per-window train/test degradation grid, WFE (Walk-Forward Efficiency), and the composite R97 KILL/ARCHIVE/PROMOTE gate
- **OOS replay** — trades stitched from all windows; full equity curve and statistics from out-of-sample performance
- **Text/HTML reports** — best-parameter and OOS-stitched report export bundles

### Statistical Guardrails (`neutrinobt.statistics`)
Anti-overfitting checks for promoting a strategy out of research, per Bailey & López de Prado:
- **Deflated Sharpe Ratio (DSR)** — corrects Sharpe for multiple-trials selection bias, with PASS/BORDERLINE/FAIL verdicts
- **Probability of Backtest Overfitting (PBO)** — CSCV implementation, vectorized fast path
- **Per-window degradation grid** — train/test metric table with red/yellow/green status per window
- **R97 gate** — composite KILL / ARCHIVE / PROMOTE decision from DSR + PBO + per-window ratio + WFE

---

## 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`](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

```bash
# Using uv (recommended)
uv pip install neutrinobt

# Or with pip
pip install neutrinobt
```

**Requirements:** Python 3.12+, NumPy, Numba, Pandas, Polars. Jinja2/Matplotlib (dashboard), CCXT (data), CuPy/CUDA (GPU) etc. are optional extras — see below.

**Optional extras:**

```bash
# 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]"

# HTML dashboard / static plot export (Jinja2, Matplotlib)
pip install "neutrinobt[reporting]"

# CUDA-accelerated optimization (needs an NVIDIA GPU + CUDA 12 toolkit)
pip install "neutrinobt[gpu]"

# Everything optional
pip install "neutrinobt[all]"
```

---

## Quick Start

```python
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

```python
# 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`](examples/notebooks/09_jupyter_plotting.ipynb) for a full walkthrough.

---

## Tutorials

The `examples/` folder is a step-by-step curriculum. Scripts `01`–`08` 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 |
| `09_gpu_ga_optimization.py` | GA + GPU search | `GeneticOptimizer.run()`, `backend="auto"/"gpu"`, CPU finalize, live SQLite leaderboard |
| `10_pinescript_export.py` | Pine export | `generate_pine_script()`, `export_pine_script()`, `Strategy.run(export_pine=True)` |

```bash
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, CPU)
│   ├── reactor_cuda.py   # Numba CUDA port — one thread per backtest (GPU screening)
│   ├── reactor_gpu.py    # legacy CuPy batch reactor
│   ├── 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, GeneticOptimizer — grid/random/GA, CPU+GPU backends
│   ├── engine.py         # Optimizer (grid/random, backend dispatch)
│   ├── genetic.py        # GeneticOptimizer (GA)
│   ├── cuda_eval.py       # GPU intent-array builder + CUDA grid evaluator
│   ├── gpu_capability.py  # per-strategy CPU/GPU capability gate
│   └── optimize_store.py  # SQLite trial/result store
├── wfo/                  # Walk-forward optimization research pipeline
│   ├── rolling_optimize.py # run_rolling_wfo() — per-window re-optimization WFO
│   └── wfo_result.py       # WFOResult + DSR/PBO/grid/R97 accessors
├── statistics/            # DSR, PBO/CSCV, per-window grid, R97 gate (anti-overfitting)
├── 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:

```bash
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

# Some tests 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

# 1-minute history (checkpointed + slower throttle; re-run to resume after 429s):
uv run --group data python scripts/fetch_binance_usdt_perp_ohlcv.py --output-dir sampledata \
  --bases BTC --timeframes 1m --since 2022-01-01 \
  --rate-limit-ms 250 --checkpoint-every 20
```

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

---

## License

MIT — see [LICENSE](LICENSE) for details.
