neutrinobt 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. neutrinobt-0.1.0/PKG-INFO +287 -0
  2. neutrinobt-0.1.0/README.md +247 -0
  3. neutrinobt-0.1.0/pyproject.toml +92 -0
  4. neutrinobt-0.1.0/src/neutrinobt/.DS_Store +0 -0
  5. neutrinobt-0.1.0/src/neutrinobt/__init__.py +31 -0
  6. neutrinobt-0.1.0/src/neutrinobt/core/__init__.py +5 -0
  7. neutrinobt-0.1.0/src/neutrinobt/core/exit_orders.py +268 -0
  8. neutrinobt-0.1.0/src/neutrinobt/core/orders.py +617 -0
  9. neutrinobt-0.1.0/src/neutrinobt/core/output_paths.py +73 -0
  10. neutrinobt-0.1.0/src/neutrinobt/core/position_tracker.py +773 -0
  11. neutrinobt-0.1.0/src/neutrinobt/core/reactor.py +609 -0
  12. neutrinobt-0.1.0/src/neutrinobt/core/reactor_config.py +92 -0
  13. neutrinobt-0.1.0/src/neutrinobt/core/reactor_core.py +1284 -0
  14. neutrinobt-0.1.0/src/neutrinobt/core/results.py +308 -0
  15. neutrinobt-0.1.0/src/neutrinobt/core/schema.py +32 -0
  16. neutrinobt-0.1.0/src/neutrinobt/core/statistics.py +774 -0
  17. neutrinobt-0.1.0/src/neutrinobt/core/trade.py +123 -0
  18. neutrinobt-0.1.0/src/neutrinobt/core/trade_tracker.py +188 -0
  19. neutrinobt-0.1.0/src/neutrinobt/dashboard/.DS_Store +0 -0
  20. neutrinobt-0.1.0/src/neutrinobt/dashboard/__init__.py +7 -0
  21. neutrinobt-0.1.0/src/neutrinobt/dashboard/data_prep.py +658 -0
  22. neutrinobt-0.1.0/src/neutrinobt/dashboard/report.py +103 -0
  23. neutrinobt-0.1.0/src/neutrinobt/dashboard/templates/backtest_report.html +1751 -0
  24. neutrinobt-0.1.0/src/neutrinobt/data/__init__.py +5 -0
  25. neutrinobt-0.1.0/src/neutrinobt/data/ccxt_binance_fetch.py +246 -0
  26. neutrinobt-0.1.0/src/neutrinobt/data/loader.py +97 -0
  27. neutrinobt-0.1.0/src/neutrinobt/data/resampler.py +82 -0
  28. neutrinobt-0.1.0/src/neutrinobt/data/validation.py +104 -0
  29. neutrinobt-0.1.0/src/neutrinobt/export/__init__.py +1 -0
  30. neutrinobt-0.1.0/src/neutrinobt/export/pinescript.py +222 -0
  31. neutrinobt-0.1.0/src/neutrinobt/indicators/__init__.py +79 -0
  32. neutrinobt-0.1.0/src/neutrinobt/indicators/ma.py +390 -0
  33. neutrinobt-0.1.0/src/neutrinobt/indicators/momentum.py +393 -0
  34. neutrinobt-0.1.0/src/neutrinobt/indicators/multiframe.py +72 -0
  35. neutrinobt-0.1.0/src/neutrinobt/indicators/signals.py +57 -0
  36. neutrinobt-0.1.0/src/neutrinobt/indicators/trend.py +319 -0
  37. neutrinobt-0.1.0/src/neutrinobt/indicators/volatility.py +436 -0
  38. neutrinobt-0.1.0/src/neutrinobt/indicators/volume.py +350 -0
  39. neutrinobt-0.1.0/src/neutrinobt/notebook/__init__.py +25 -0
  40. neutrinobt-0.1.0/src/neutrinobt/notebook/plots.py +362 -0
  41. neutrinobt-0.1.0/src/neutrinobt/notebook/quantstats_export.py +227 -0
  42. neutrinobt-0.1.0/src/neutrinobt/optimization/__init__.py +16 -0
  43. neutrinobt-0.1.0/src/neutrinobt/optimization/engine.py +273 -0
  44. neutrinobt-0.1.0/src/neutrinobt/optimization/genetic.py +428 -0
  45. neutrinobt-0.1.0/src/neutrinobt/optimization/objectives.py +94 -0
  46. neutrinobt-0.1.0/src/neutrinobt/optimization/optimize_store.py +192 -0
  47. neutrinobt-0.1.0/src/neutrinobt/optimization/param_space.py +94 -0
  48. neutrinobt-0.1.0/src/neutrinobt/py.typed +0 -0
  49. neutrinobt-0.1.0/src/neutrinobt/signal/__init__.py +31 -0
  50. neutrinobt-0.1.0/src/neutrinobt/signal/base.py +53 -0
  51. neutrinobt-0.1.0/src/neutrinobt/signal/template.py +157 -0
  52. neutrinobt-0.1.0/src/neutrinobt/signal/vwap_atr_supertrend.py +112 -0
  53. neutrinobt-0.1.0/src/neutrinobt/statistics/__init__.py +45 -0
  54. neutrinobt-0.1.0/src/neutrinobt/statistics/deflated_sharpe.py +347 -0
  55. neutrinobt-0.1.0/src/neutrinobt/statistics/pbo.py +356 -0
  56. neutrinobt-0.1.0/src/neutrinobt/statistics/per_window_grid.py +332 -0
  57. neutrinobt-0.1.0/src/neutrinobt/statistics/progress.py +43 -0
  58. neutrinobt-0.1.0/src/neutrinobt/statistics/r97_gate.py +139 -0
  59. neutrinobt-0.1.0/src/neutrinobt/statistics/research_log.py +233 -0
  60. neutrinobt-0.1.0/src/neutrinobt/strategy/__init__.py +5 -0
  61. neutrinobt-0.1.0/src/neutrinobt/strategy/base.py +1715 -0
  62. neutrinobt-0.1.0/src/neutrinobt/wfo/__init__.py +49 -0
  63. neutrinobt-0.1.0/src/neutrinobt/wfo/atomic_io.py +451 -0
  64. neutrinobt-0.1.0/src/neutrinobt/wfo/engine_fingerprint.py +114 -0
  65. neutrinobt-0.1.0/src/neutrinobt/wfo/ledger.py +202 -0
  66. neutrinobt-0.1.0/src/neutrinobt/wfo/matrix.py +407 -0
  67. neutrinobt-0.1.0/src/neutrinobt/wfo/oos_helpers.py +88 -0
  68. neutrinobt-0.1.0/src/neutrinobt/wfo/protocols.py +117 -0
  69. neutrinobt-0.1.0/src/neutrinobt/wfo/robustness.py +150 -0
  70. neutrinobt-0.1.0/src/neutrinobt/wfo/selection.py +260 -0
  71. neutrinobt-0.1.0/src/neutrinobt/wfo/strategy_fingerprint.py +196 -0
  72. neutrinobt-0.1.0/src/neutrinobt/wfo/trade_store.py +199 -0
  73. neutrinobt-0.1.0/src/neutrinobt/wfo/ts_metrics.py +196 -0
  74. neutrinobt-0.1.0/src/neutrinobt/wfo/wfo_evaluator.py +198 -0
  75. neutrinobt-0.1.0/src/neutrinobt/wfo/wfo_html_report.py +214 -0
  76. neutrinobt-0.1.0/src/neutrinobt/wfo/wfo_plots.py +132 -0
  77. neutrinobt-0.1.0/src/neutrinobt/wfo/wfo_report.py +368 -0
  78. neutrinobt-0.1.0/src/neutrinobt/wfo/wfo_result.py +209 -0
  79. neutrinobt-0.1.0/src/neutrinobt/wfo/windowing.py +120 -0
@@ -0,0 +1,287 @@
1
+ Metadata-Version: 2.3
2
+ Name: neutrinobt
3
+ Version: 0.1.0
4
+ Summary: High-performance Python backtesting engine powered by Numba JIT, with indicators, optimization, walk-forward validation, and reporting
5
+ Keywords: backtesting,algorithmic-trading,quantitative-finance,numba,pine-script,trading-strategy,technical-analysis
6
+ Author: KlaBuasom
7
+ Author-email: KlaBuasom <kla.buasom@gmail.com>
8
+ License: MIT
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Financial and Insurance Industry
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Topic :: Office/Business :: Financial :: Investment
16
+ Classifier: Topic :: Scientific/Engineering
17
+ Requires-Dist: numba>=0.63.1
18
+ Requires-Dist: numpy>=2.3.5
19
+ Requires-Dist: pandas>=3.0.0
20
+ Requires-Dist: polars>=1.37.1
21
+ Requires-Dist: matplotlib>=3.9.0
22
+ Requires-Dist: jinja2>=3.1
23
+ Requires-Dist: openpyxl>=3.1.5
24
+ Requires-Dist: ccxt>=4.4.96 ; extra == 'all'
25
+ Requires-Dist: quantstats>=0.0.62 ; extra == 'all'
26
+ Requires-Dist: pyarrow>=16.0.0 ; extra == 'all'
27
+ Requires-Dist: quantstats>=0.0.62 ; extra == 'analytics'
28
+ Requires-Dist: ccxt>=4.4.96 ; extra == 'data'
29
+ Requires-Dist: pyarrow>=16.0.0 ; extra == 'wfo'
30
+ Requires-Python: >=3.12
31
+ Project-URL: Homepage, https://github.com/KlaBuasom/NeutrinoBT
32
+ Project-URL: Repository, https://github.com/KlaBuasom/NeutrinoBT
33
+ Project-URL: Issues, https://github.com/KlaBuasom/NeutrinoBT/issues
34
+ Project-URL: Documentation, https://github.com/KlaBuasom/NeutrinoBT#readme
35
+ Provides-Extra: all
36
+ Provides-Extra: analytics
37
+ Provides-Extra: data
38
+ Provides-Extra: wfo
39
+ Description-Content-Type: text/markdown
40
+
41
+ # NeutrinoBT
42
+
43
+ [![CI](https://github.com/KlaBuasom/NeutrinoBT/actions/workflows/ci.yml/badge.svg)](https://github.com/KlaBuasom/NeutrinoBT/actions/workflows/ci.yml)
44
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/)
45
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
46
+
47
+ **A high-performance Python backtesting library powered by Numba JIT.**
48
+
49
+ 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.
50
+
51
+ ---
52
+
53
+ ## Features
54
+
55
+ ### Core Engine
56
+ - **Numba JIT backtesting** — `@njit(cache=True)` compiled execution loop; orders, stops, and equity curves computed at native speed
57
+ - **Two signal modes** — vectorized (NumPy arrays) for simple strategies; Pine Script-style order API (`order()`, `exit()`, `cancel()`) for complex logic
58
+ - **Multiple positions** — FIFO, LIFO, or BY_ID close selection; configurable `max_positions`
59
+ - **Stops & exits** — per-trade stop loss, take profit, and trailing stops (activation by price or points)
60
+ - **Leverage & liquidation** — configurable leverage with automatic liquidation price calculation
61
+ - **Entry on bar close** — optional `entry_on_bar_close=True` fills at next bar open (matches Pine Script `strategy.entry` behaviour)
62
+ - **Commission & slippage** — applied separately to entries and stops
63
+
64
+ ### Indicators (`self.I` / `nt.*`)
65
+ 25+ built-in indicators, all Numba-accelerated, organized into five categories:
66
+
67
+ | Category | Indicators |
68
+ |----------|-----------|
69
+ | Moving Averages | EMA, SMA, RMA, WMA, DEMA, TEMA, HMA, VWMA |
70
+ | Momentum | RSI, MACD, Stoch, StochRSI, CCI, Williams %R, ADX, MFI |
71
+ | Volatility | ATR, STDEV, SuperTrend, Bollinger Bands, Keltner Channel, Donchian Channel |
72
+ | Trend | Parabolic SAR, Ichimoku Cloud, Linear Regression |
73
+ | Volume | OBV, VWAP |
74
+
75
+ All indicators support a `timeframe=` parameter for multi-timeframe analysis without look-ahead bias.
76
+
77
+ ### Optimization
78
+ - **Grid search** — exhaustive sweep over all parameter combinations
79
+ - **Random search** — sampled trials with reproducible seeds
80
+ - **Parallel workers** — `n_jobs=` via `multiprocessing.Pool` (Windows-safe)
81
+ - **Built-in objectives** — `net_profit`, `sharpe`, `profit_factor`, `gt_score`, `negative_max_drawdown`; or pass any callable
82
+
83
+ ### Statistics
84
+ Professional-grade metrics in the style of TradingView's Strategy Tester:
85
+ 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**.
86
+
87
+ ### Jupyter / In-Notebook Visualization
88
+ - **`plot_equity`** — equity curve chart from mark-to-market or trade-step fallback
89
+ - **`plot_drawdown`** — underwater / drawdown chart (% from running peak)
90
+ - **`plot_price_with_trades`** — close price overlaid with long/short entry & exit markers
91
+ - **`display_statistics_summary`** — styled statistics table rendered inline in Jupyter
92
+ - **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)
93
+
94
+ ### Dashboard & Export
95
+ - **HTML dashboard** — self-contained interactive report with TradingView price chart, equity curve, drawdown, returns heatmap, MFE/MAE scatter, and paginated trade log
96
+ - **Pine Script export** — generate a Pine Script indicator from your strategy's signals
97
+ - **CSV export** — statistics table and full trade list
98
+
99
+ ---
100
+
101
+ ## Performance
102
+
103
+ 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).
104
+
105
+ | Engine | Avg time / run | × NeutrinoBT | × backtrader |
106
+ |--------|---------------|-------------|-------------|
107
+ | Hardcoded (raw NumPy) | ~1 ms | 22× faster | 1,090× faster |
108
+ | **NeutrinoBT** | **~22 ms** | — | **~50× faster** |
109
+ | backtesting.py | ~77 ms | 3.5× slower | 14× faster |
110
+ | backtrader | ~1,090 ms | 50× slower | — |
111
+
112
+ 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.
113
+
114
+ > 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).
115
+
116
+ ---
117
+
118
+ ## Installation
119
+
120
+ ```bash
121
+ # Using uv (recommended)
122
+ uv pip install neutrinobt
123
+
124
+ # Or with pip
125
+ pip install neutrinobt
126
+ ```
127
+
128
+ **Requirements:** Python 3.12+, NumPy, Numba, Pandas, Polars, Jinja2, Matplotlib
129
+
130
+ **Optional extras:**
131
+
132
+ ```bash
133
+ # Development tools from a source checkout (JupyterLab, pytest, ruff)
134
+ uv sync --group dev
135
+
136
+ # Binance / CCXT data downloader helpers
137
+ pip install "neutrinobt[data]"
138
+
139
+ # QuantStats tear sheets (pulls scipy, seaborn, yfinance)
140
+ pip install "neutrinobt[analytics]"
141
+
142
+ # Parquet-backed WFO trade stores
143
+ pip install "neutrinobt[wfo]"
144
+
145
+ # Everything optional
146
+ pip install "neutrinobt[all]"
147
+ ```
148
+
149
+ ---
150
+
151
+ ## Quick Start
152
+
153
+ ```python
154
+ import numpy as np
155
+ from neutrinobt.data.loader import CSVLoader
156
+ from neutrinobt.strategy.base import Strategy
157
+ from neutrinobt.core.reactor import Reactor
158
+ import neutrinobt.indicators as nt
159
+
160
+ # 1. Load OHLCV data
161
+ loader = CSVLoader("sampledata/BTCUSDTUSDT/1h.csv")
162
+ bars = loader.load({
163
+ "time": "timestamp", "open": "open", "high": "high",
164
+ "low": "low", "close": "close", "volume": "volume",
165
+ })
166
+
167
+ # 2. Define a strategy
168
+ class EMACrossover(Strategy):
169
+ def init(self):
170
+ self.ema_fast = self.I.EMA(20)
171
+ self.ema_slow = self.I.EMA(50)
172
+
173
+ def generate_signals(self):
174
+ valid = ~(np.isnan(self.ema_fast) | np.isnan(self.ema_slow))
175
+ self.buy_cond(nt.crossover(self.ema_fast, self.ema_slow) & valid)
176
+ self.sell_cond(nt.crossunder(self.ema_fast, self.ema_slow) & valid)
177
+
178
+ def create_reactor(self):
179
+ return Reactor(bars, initial_balance=10_000.0, commission_rate=0.001)
180
+
181
+ # 3. Run
182
+ results = EMACrossover(bars).run(show_summary=True)
183
+ print(f"Final equity: ${results['final_equity']:,.2f}")
184
+ ```
185
+
186
+ ### Jupyter Plotting
187
+
188
+ ```python
189
+ # Pass export_timeseries=True to record bar-by-bar equity
190
+ results = EMACrossover(bars).run(export_timeseries=True, show_summary=False)
191
+
192
+ from neutrinobt.notebook.plots import plot_equity, plot_drawdown, display_statistics_summary
193
+ from neutrinobt.notebook.quantstats_export import quantstats_returns
194
+
195
+ plot_equity(bars, equity_curve=results["equity_curve"])
196
+ plot_drawdown(bars, equity_curve=results["equity_curve"])
197
+ display_statistics_summary(results["statistics"])
198
+
199
+ # Export per-bar decimal returns ready for QuantStats
200
+ qs = quantstats_returns(bars=bars, equity_curve=results["equity_curve"])
201
+ # import quantstats; quantstats.reports.basic(qs.strategy, benchmark=qs.benchmark)
202
+ ```
203
+
204
+ See [`examples/notebooks/09_jupyter_plotting.ipynb`](examples/notebooks/09_jupyter_plotting.ipynb) for a full walkthrough.
205
+
206
+ ---
207
+
208
+ ## Tutorials
209
+
210
+ The `examples/` folder is a step-by-step curriculum. Scripts `01`–`08` cover the core engine; the `notebooks/` subfolder has interactive Jupyter examples.
211
+
212
+ **Scripts** — run from the project root:
213
+
214
+ | File | Topic | What you learn |
215
+ |------|-------|----------------|
216
+ | `01_getting_started.py` | First backtest | Load data, validate, define a strategy, read results |
217
+ | `02_strategy_basics.py` | Strategy class | `init()`, `generate_signals()`, `create_reactor()`, statistics keys |
218
+ | `03_indicators.py` | All 25+ indicators | Every indicator category, standalone use, multi-timeframe |
219
+ | `04_risk_management.py` | Risk controls | Fixed/ATR stop loss & take profit, trailing stops, leverage, sizing |
220
+ | `05_advanced_orders.py` | Order-based API | `order()`, `exit()`, `cancel()`, limit/stop entries, multiple positions |
221
+ | `06_optimization.py` | Parameter search | `Optimizer.run()`, grid vs random, built-in objectives, parallel |
222
+ | `07_dashboard_report.py` | HTML report | `export_html=True`, `generate_report()`, all dashboard sections |
223
+ | `08_real_world_strategy.py` | Full strategy | Date range, warmup, production backtest, trade analysis |
224
+
225
+ ```bash
226
+ python examples/01_getting_started.py
227
+ ```
228
+
229
+ **Notebooks** — open in JupyterLab (`uv sync --group dev && uv run jupyter lab`):
230
+
231
+ | Notebook | Topic | What you learn |
232
+ |----------|-------|----------------|
233
+ | `notebooks/09_jupyter_plotting.ipynb` | In-notebook visualization | Equity curve, drawdown, trade markers, statistics table, QuantStats export |
234
+
235
+ ---
236
+
237
+ ## Architecture
238
+
239
+ ```
240
+ neutrinobt/
241
+ ├── core/
242
+ │ ├── reactor_core.py # Numba @njit compiled engine (the hot loop)
243
+ │ ├── reactor.py # Python wrapper — validation, results, statistics
244
+ │ └── statistics.py # ~30 performance metrics
245
+ ├── strategy/
246
+ │ └── base.py # Strategy base class + IndicatorFactory (self.I)
247
+ ├── indicators/ # 25+ @njit indicators
248
+ ├── notebook/ # Jupyter helpers (no mandatory new deps)
249
+ │ ├── plots.py # plot_equity, plot_drawdown, plot_price_with_trades, display_statistics_summary
250
+ │ └── quantstats_export.py # quantstats_returns, export_quantstats_returns_csv
251
+ ├── optimization/ # Optimizer — grid/random search
252
+ ├── dashboard/ # HTML report generator (Jinja2 + ECharts)
253
+ ├── export/ # Pine Script exporter
254
+ └── data/ # CSVLoader, Resampler, validation
255
+ ```
256
+
257
+ **Execution flow:**
258
+ 1. `Strategy.init()` — indicators computed, warmup tracked
259
+ 2. `Strategy.generate_signals()` — boolean arrays or Pine-style orders
260
+ 3. `Reactor.run()` — Numba JIT loop processes every bar: pending fills, trailing updates, liquidations, SL/TP, exits, entries
261
+ 4. Results — `TradeList`, `Statistics`, optional HTML report
262
+
263
+ ---
264
+
265
+ ## Sample Data
266
+
267
+ CSV bars live under ``sampledata/<BASE>USDTUSDT/<timeframe>.csv``. That directory is **gitignored**
268
+ — fetch Binance USDT‑M perpetual OHLCV with CCXT:
269
+
270
+ ```bash
271
+ uv sync --group data
272
+
273
+ # Default list: BTC, XRP, ETH, HYPE, BNB, DOGE — timeframes 30m, 1h, 2h
274
+ uv run --group data python scripts/fetch_binance_usdt_perp_ohlcv.py --output-dir sampledata
275
+
276
+ # Tests and ``research_pipeline/configs/datasets.json`` also expect daily BTC / XRP files:
277
+ uv run --group data python scripts/fetch_binance_usdt_perp_ohlcv.py --output-dir sampledata \
278
+ --bases BTC XRP --timeframes 1d
279
+ ```
280
+
281
+ See the script docstring for the exact default symbol/timeframe lists.
282
+
283
+ ---
284
+
285
+ ## License
286
+
287
+ MIT — see [LICENSE](LICENSE) for details.
@@ -0,0 +1,247 @@
1
+ # NeutrinoBT
2
+
3
+ [![CI](https://github.com/KlaBuasom/NeutrinoBT/actions/workflows/ci.yml/badge.svg)](https://github.com/KlaBuasom/NeutrinoBT/actions/workflows/ci.yml)
4
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/)
5
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
6
+
7
+ **A high-performance Python backtesting library powered by Numba JIT.**
8
+
9
+ 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.
10
+
11
+ ---
12
+
13
+ ## Features
14
+
15
+ ### Core Engine
16
+ - **Numba JIT backtesting** — `@njit(cache=True)` compiled execution loop; orders, stops, and equity curves computed at native speed
17
+ - **Two signal modes** — vectorized (NumPy arrays) for simple strategies; Pine Script-style order API (`order()`, `exit()`, `cancel()`) for complex logic
18
+ - **Multiple positions** — FIFO, LIFO, or BY_ID close selection; configurable `max_positions`
19
+ - **Stops & exits** — per-trade stop loss, take profit, and trailing stops (activation by price or points)
20
+ - **Leverage & liquidation** — configurable leverage with automatic liquidation price calculation
21
+ - **Entry on bar close** — optional `entry_on_bar_close=True` fills at next bar open (matches Pine Script `strategy.entry` behaviour)
22
+ - **Commission & slippage** — applied separately to entries and stops
23
+
24
+ ### Indicators (`self.I` / `nt.*`)
25
+ 25+ built-in indicators, all Numba-accelerated, organized into five categories:
26
+
27
+ | Category | Indicators |
28
+ |----------|-----------|
29
+ | Moving Averages | EMA, SMA, RMA, WMA, DEMA, TEMA, HMA, VWMA |
30
+ | Momentum | RSI, MACD, Stoch, StochRSI, CCI, Williams %R, ADX, MFI |
31
+ | Volatility | ATR, STDEV, SuperTrend, Bollinger Bands, Keltner Channel, Donchian Channel |
32
+ | Trend | Parabolic SAR, Ichimoku Cloud, Linear Regression |
33
+ | Volume | OBV, VWAP |
34
+
35
+ All indicators support a `timeframe=` parameter for multi-timeframe analysis without look-ahead bias.
36
+
37
+ ### Optimization
38
+ - **Grid search** — exhaustive sweep over all parameter combinations
39
+ - **Random search** — sampled trials with reproducible seeds
40
+ - **Parallel workers** — `n_jobs=` via `multiprocessing.Pool` (Windows-safe)
41
+ - **Built-in objectives** — `net_profit`, `sharpe`, `profit_factor`, `gt_score`, `negative_max_drawdown`; or pass any callable
42
+
43
+ ### Statistics
44
+ Professional-grade metrics in the style of TradingView's Strategy Tester:
45
+ 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**.
46
+
47
+ ### Jupyter / In-Notebook Visualization
48
+ - **`plot_equity`** — equity curve chart from mark-to-market or trade-step fallback
49
+ - **`plot_drawdown`** — underwater / drawdown chart (% from running peak)
50
+ - **`plot_price_with_trades`** — close price overlaid with long/short entry & exit markers
51
+ - **`display_statistics_summary`** — styled statistics table rendered inline in Jupyter
52
+ - **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)
53
+
54
+ ### Dashboard & Export
55
+ - **HTML dashboard** — self-contained interactive report with TradingView price chart, equity curve, drawdown, returns heatmap, MFE/MAE scatter, and paginated trade log
56
+ - **Pine Script export** — generate a Pine Script indicator from your strategy's signals
57
+ - **CSV export** — statistics table and full trade list
58
+
59
+ ---
60
+
61
+ ## Performance
62
+
63
+ 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).
64
+
65
+ | Engine | Avg time / run | × NeutrinoBT | × backtrader |
66
+ |--------|---------------|-------------|-------------|
67
+ | Hardcoded (raw NumPy) | ~1 ms | 22× faster | 1,090× faster |
68
+ | **NeutrinoBT** | **~22 ms** | — | **~50× faster** |
69
+ | backtesting.py | ~77 ms | 3.5× slower | 14× faster |
70
+ | backtrader | ~1,090 ms | 50× slower | — |
71
+
72
+ 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.
73
+
74
+ > 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).
75
+
76
+ ---
77
+
78
+ ## Installation
79
+
80
+ ```bash
81
+ # Using uv (recommended)
82
+ uv pip install neutrinobt
83
+
84
+ # Or with pip
85
+ pip install neutrinobt
86
+ ```
87
+
88
+ **Requirements:** Python 3.12+, NumPy, Numba, Pandas, Polars, Jinja2, Matplotlib
89
+
90
+ **Optional extras:**
91
+
92
+ ```bash
93
+ # Development tools from a source checkout (JupyterLab, pytest, ruff)
94
+ uv sync --group dev
95
+
96
+ # Binance / CCXT data downloader helpers
97
+ pip install "neutrinobt[data]"
98
+
99
+ # QuantStats tear sheets (pulls scipy, seaborn, yfinance)
100
+ pip install "neutrinobt[analytics]"
101
+
102
+ # Parquet-backed WFO trade stores
103
+ pip install "neutrinobt[wfo]"
104
+
105
+ # Everything optional
106
+ pip install "neutrinobt[all]"
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Quick Start
112
+
113
+ ```python
114
+ import numpy as np
115
+ from neutrinobt.data.loader import CSVLoader
116
+ from neutrinobt.strategy.base import Strategy
117
+ from neutrinobt.core.reactor import Reactor
118
+ import neutrinobt.indicators as nt
119
+
120
+ # 1. Load OHLCV data
121
+ loader = CSVLoader("sampledata/BTCUSDTUSDT/1h.csv")
122
+ bars = loader.load({
123
+ "time": "timestamp", "open": "open", "high": "high",
124
+ "low": "low", "close": "close", "volume": "volume",
125
+ })
126
+
127
+ # 2. Define a strategy
128
+ class EMACrossover(Strategy):
129
+ def init(self):
130
+ self.ema_fast = self.I.EMA(20)
131
+ self.ema_slow = self.I.EMA(50)
132
+
133
+ def generate_signals(self):
134
+ valid = ~(np.isnan(self.ema_fast) | np.isnan(self.ema_slow))
135
+ self.buy_cond(nt.crossover(self.ema_fast, self.ema_slow) & valid)
136
+ self.sell_cond(nt.crossunder(self.ema_fast, self.ema_slow) & valid)
137
+
138
+ def create_reactor(self):
139
+ return Reactor(bars, initial_balance=10_000.0, commission_rate=0.001)
140
+
141
+ # 3. Run
142
+ results = EMACrossover(bars).run(show_summary=True)
143
+ print(f"Final equity: ${results['final_equity']:,.2f}")
144
+ ```
145
+
146
+ ### Jupyter Plotting
147
+
148
+ ```python
149
+ # Pass export_timeseries=True to record bar-by-bar equity
150
+ results = EMACrossover(bars).run(export_timeseries=True, show_summary=False)
151
+
152
+ from neutrinobt.notebook.plots import plot_equity, plot_drawdown, display_statistics_summary
153
+ from neutrinobt.notebook.quantstats_export import quantstats_returns
154
+
155
+ plot_equity(bars, equity_curve=results["equity_curve"])
156
+ plot_drawdown(bars, equity_curve=results["equity_curve"])
157
+ display_statistics_summary(results["statistics"])
158
+
159
+ # Export per-bar decimal returns ready for QuantStats
160
+ qs = quantstats_returns(bars=bars, equity_curve=results["equity_curve"])
161
+ # import quantstats; quantstats.reports.basic(qs.strategy, benchmark=qs.benchmark)
162
+ ```
163
+
164
+ See [`examples/notebooks/09_jupyter_plotting.ipynb`](examples/notebooks/09_jupyter_plotting.ipynb) for a full walkthrough.
165
+
166
+ ---
167
+
168
+ ## Tutorials
169
+
170
+ The `examples/` folder is a step-by-step curriculum. Scripts `01`–`08` cover the core engine; the `notebooks/` subfolder has interactive Jupyter examples.
171
+
172
+ **Scripts** — run from the project root:
173
+
174
+ | File | Topic | What you learn |
175
+ |------|-------|----------------|
176
+ | `01_getting_started.py` | First backtest | Load data, validate, define a strategy, read results |
177
+ | `02_strategy_basics.py` | Strategy class | `init()`, `generate_signals()`, `create_reactor()`, statistics keys |
178
+ | `03_indicators.py` | All 25+ indicators | Every indicator category, standalone use, multi-timeframe |
179
+ | `04_risk_management.py` | Risk controls | Fixed/ATR stop loss & take profit, trailing stops, leverage, sizing |
180
+ | `05_advanced_orders.py` | Order-based API | `order()`, `exit()`, `cancel()`, limit/stop entries, multiple positions |
181
+ | `06_optimization.py` | Parameter search | `Optimizer.run()`, grid vs random, built-in objectives, parallel |
182
+ | `07_dashboard_report.py` | HTML report | `export_html=True`, `generate_report()`, all dashboard sections |
183
+ | `08_real_world_strategy.py` | Full strategy | Date range, warmup, production backtest, trade analysis |
184
+
185
+ ```bash
186
+ python examples/01_getting_started.py
187
+ ```
188
+
189
+ **Notebooks** — open in JupyterLab (`uv sync --group dev && uv run jupyter lab`):
190
+
191
+ | Notebook | Topic | What you learn |
192
+ |----------|-------|----------------|
193
+ | `notebooks/09_jupyter_plotting.ipynb` | In-notebook visualization | Equity curve, drawdown, trade markers, statistics table, QuantStats export |
194
+
195
+ ---
196
+
197
+ ## Architecture
198
+
199
+ ```
200
+ neutrinobt/
201
+ ├── core/
202
+ │ ├── reactor_core.py # Numba @njit compiled engine (the hot loop)
203
+ │ ├── reactor.py # Python wrapper — validation, results, statistics
204
+ │ └── statistics.py # ~30 performance metrics
205
+ ├── strategy/
206
+ │ └── base.py # Strategy base class + IndicatorFactory (self.I)
207
+ ├── indicators/ # 25+ @njit indicators
208
+ ├── notebook/ # Jupyter helpers (no mandatory new deps)
209
+ │ ├── plots.py # plot_equity, plot_drawdown, plot_price_with_trades, display_statistics_summary
210
+ │ └── quantstats_export.py # quantstats_returns, export_quantstats_returns_csv
211
+ ├── optimization/ # Optimizer — grid/random search
212
+ ├── dashboard/ # HTML report generator (Jinja2 + ECharts)
213
+ ├── export/ # Pine Script exporter
214
+ └── data/ # CSVLoader, Resampler, validation
215
+ ```
216
+
217
+ **Execution flow:**
218
+ 1. `Strategy.init()` — indicators computed, warmup tracked
219
+ 2. `Strategy.generate_signals()` — boolean arrays or Pine-style orders
220
+ 3. `Reactor.run()` — Numba JIT loop processes every bar: pending fills, trailing updates, liquidations, SL/TP, exits, entries
221
+ 4. Results — `TradeList`, `Statistics`, optional HTML report
222
+
223
+ ---
224
+
225
+ ## Sample Data
226
+
227
+ CSV bars live under ``sampledata/<BASE>USDTUSDT/<timeframe>.csv``. That directory is **gitignored**
228
+ — fetch Binance USDT‑M perpetual OHLCV with CCXT:
229
+
230
+ ```bash
231
+ uv sync --group data
232
+
233
+ # Default list: BTC, XRP, ETH, HYPE, BNB, DOGE — timeframes 30m, 1h, 2h
234
+ uv run --group data python scripts/fetch_binance_usdt_perp_ohlcv.py --output-dir sampledata
235
+
236
+ # Tests and ``research_pipeline/configs/datasets.json`` also expect daily BTC / XRP files:
237
+ uv run --group data python scripts/fetch_binance_usdt_perp_ohlcv.py --output-dir sampledata \
238
+ --bases BTC XRP --timeframes 1d
239
+ ```
240
+
241
+ See the script docstring for the exact default symbol/timeframe lists.
242
+
243
+ ---
244
+
245
+ ## License
246
+
247
+ MIT — see [LICENSE](LICENSE) for details.
@@ -0,0 +1,92 @@
1
+ [project]
2
+ name = "neutrinobt"
3
+ version = "0.1.0"
4
+ description = "High-performance Python backtesting engine powered by Numba JIT, with indicators, optimization, walk-forward validation, and reporting"
5
+ readme = { file = "README.md", content-type = "text/markdown" }
6
+ license = { text = "MIT" }
7
+ authors = [
8
+ { name = "KlaBuasom", email = "kla.buasom@gmail.com" }
9
+ ]
10
+ keywords = [
11
+ "backtesting", "algorithmic-trading", "quantitative-finance",
12
+ "numba", "pine-script", "trading-strategy", "technical-analysis",
13
+ ]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Financial and Insurance Industry",
17
+ "Intended Audience :: Science/Research",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Topic :: Office/Business :: Financial :: Investment",
22
+ "Topic :: Scientific/Engineering",
23
+ ]
24
+ requires-python = ">=3.12"
25
+ dependencies = [
26
+ "numba>=0.63.1",
27
+ "numpy>=2.3.5",
28
+ "pandas>=3.0.0",
29
+ "polars>=1.37.1",
30
+ "matplotlib>=3.9.0",
31
+ "jinja2>=3.1",
32
+ "openpyxl>=3.1.5",
33
+ ]
34
+
35
+ [project.urls]
36
+ Homepage = "https://github.com/KlaBuasom/NeutrinoBT"
37
+ Repository = "https://github.com/KlaBuasom/NeutrinoBT"
38
+ Issues = "https://github.com/KlaBuasom/NeutrinoBT/issues"
39
+ Documentation = "https://github.com/KlaBuasom/NeutrinoBT#readme"
40
+
41
+ [project.optional-dependencies]
42
+ # Binance / CCXT data downloader helpers.
43
+ data = [
44
+ "ccxt>=4.4.96",
45
+ ]
46
+ # QuantStats tear sheets and portfolio analytics.
47
+ analytics = [
48
+ "quantstats>=0.0.62",
49
+ ]
50
+ # Parquet-backed WFO trade stores using pandas read_parquet/to_parquet.
51
+ wfo = [
52
+ "pyarrow>=16.0.0",
53
+ ]
54
+ all = [
55
+ "ccxt>=4.4.96",
56
+ "quantstats>=0.0.62",
57
+ "pyarrow>=16.0.0",
58
+ ]
59
+
60
+ [build-system]
61
+ requires = ["uv_build>=0.9.28,<1"]
62
+ build-backend = "uv_build"
63
+
64
+ [tool.pytest.ini_options]
65
+ testpaths = ["tests"]
66
+ python_files = ["test_*.py"]
67
+ python_classes = ["Test*"]
68
+ python_functions = ["test_*"]
69
+ addopts = "-v --tb=short"
70
+ filterwarnings = [
71
+ "ignore::numba.core.errors.NumbaPerformanceWarning",
72
+ ]
73
+
74
+ [dependency-groups]
75
+ dev = [
76
+ "jupyterlab>=4.5.3",
77
+ "pytest>=9.0.2",
78
+ "ruff>=0.14.14",
79
+ ]
80
+ publish = [
81
+ "twine>=6.2.0",
82
+ ]
83
+ # CCXT-backed OHLCV download scripts (scripts/fetch_binance_usdt_perp_ohlcv.py).
84
+ data = [
85
+ "ccxt>=4.4.96",
86
+ ]
87
+ # Optional analytics — QuantStats tear sheets + portfolio metrics.
88
+ # Install with: uv sync --group analytics
89
+ # quantstats pulls in scipy, seaborn, yfinance — not bundled by default.
90
+ analytics = [
91
+ "quantstats>=0.0.62",
92
+ ]
@@ -0,0 +1,31 @@
1
+ """
2
+ NeutrinoBT - High-performance backtesting engine.
3
+
4
+ Usage:
5
+ from neutrinobt import Strategy, Reactor
6
+ from neutrinobt import indicators as nt
7
+ """
8
+
9
+ from neutrinobt.strategy.base import Strategy
10
+ from neutrinobt.core.reactor import Reactor
11
+ from neutrinobt.core.reactor import CloseMethod
12
+ from neutrinobt.data.loader import CSVLoader
13
+ from neutrinobt.data.resampler import Resampler
14
+ from neutrinobt.optimization.engine import Optimizer
15
+
16
+ import neutrinobt.indicators as indicators
17
+ from neutrinobt.export.pinescript import generate_pine_script
18
+
19
+ __version__ = "0.1.0"
20
+
21
+ __all__ = [
22
+ "Strategy",
23
+ "Reactor",
24
+ "CloseMethod",
25
+ "CSVLoader",
26
+ "Resampler",
27
+ "Optimizer",
28
+ "indicators",
29
+ "generate_pine_script",
30
+ "__version__",
31
+ ]
@@ -0,0 +1,5 @@
1
+ """Core module for NeutrinoBT - contains schema and reactor engine."""
2
+
3
+ from neutrinobt.core.reactor import Reactor
4
+
5
+ __all__ = ['Reactor']