High-performance C++20 backtesting engine with Python interface
Project description
QuantCore
High-performance backtesting engine written in C++20 with a Python research interface.
Overview
QuantCore is an event-driven backtester built around an enhanced version of my limit order book simulator. Market events are processed chronologically through a priority queue, so there's no look-ahead bias and no assumptions about fill prices. Orders go through a real price-time priority matching engine.
Both bar and tick data are supported. Strategies work unchanged across both.
Market Data → EventQueue → Strategy → Signal → OrderBook → Fill → Portfolio
Quick Start
pip install quantcore
import quantcore as qc
class MyStrategy(qc.Strategy):
def on_data(self, event):
if not self.has_position(event.symbol):
self.generate_signal(event.symbol, qc.SignalType.BUY, 1.0, event.timestamp_ns)
results = qc.run_backtest(
strategy=MyStrategy(),
data={'AAPL': qc.load_csv_data('data/aapl.csv', 'AAPL')},
initial_capital=100_000.0,
)
print(results)
Tick data works the same way:
results = qc.run_tick_backtest(
strategy=MyStrategy(),
tick_data={'AAPL': qc.load_tick_csv('data/aapl_ticks.csv', 'AAPL')},
initial_capital=100_000.0,
)
event.close is the tick price when running on tick data. No strategy changes needed.
For the full API reference, see docs/usage.md.
Performance
Single-threaded. Measured on Windows (Release build, MSVC).
Order book
| Pattern | Ops/s |
|---|---|
| Add + cancel (MM quote refresh) | 13.0 M ops/s |
| Add + match (taker sweep) | 4.9 M ops/s |
Bar mode
| Scenario | Bars/s | p99 latency |
|---|---|---|
| 1-year (252 bars) | ~270 K/s | 0.93 ms |
| 5-year (1,260 bars) | ~270 K/s | - |
| 1,000-year stress (252,000 bars) | ~290 K/s | - |
Tick mode
| Scenario | Ticks/s | Wall time |
|---|---|---|
| 10K ticks, no MM throttle | 315 K/s | 31.7 ms |
| 10K ticks, 1s MM throttle | 1.66 M/s | 6.0 ms |
| 1M ticks aggregated to 1-min bars | 247 M/s | 4.1 ms |
The MM refresh interval is the main lever for tick performance. See benchmarks/RESULTS.md for the full breakdown.
vs. Alternatives
| QuantCore | Backtrader | Zipline | |
|---|---|---|---|
| Core language | C++20 | Python | Python |
| Order book simulation | Yes | No | No |
| Tick data | Yes | No | No |
| Event-driven | Yes | Yes | Yes |
| Look-ahead prevention | Priority queue | Yes | Yes |
| Python strategy API | pybind11 | Native | Native |
| Throughput (bars/s) | ~300K | ~7.7K | unverified |
| Maintenance | Active | Stale | Inactive |
Throughput: SMA(50/200) crossover, 50K daily bars, Release build, Windows.
Reproduce: python benchmarks/qcVsBacktrader.py --bars 50000 --runs 20
The core differentiator is the order book. Backtrader and Zipline fill at close price. QuantCore routes orders through a real matching engine, giving you realistic partial fills, spread simulation, and tick-level execution.
Installation
Prerequisites: CMake 3.15+, C++20 compiler (GCC 10+, Clang 12+, MSVC 2022), Python 3.8+
git clone https://github.com/SLMolenaar/quantcore.git
cd quantcore
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
cd python
pip install pybind11
python build_module.py
python -c "import quantcore; print(quantcore.version())"
Run tests:
cmake --build build --target quantcore_tests
./build/quantcore_tests
Examples
| Notebook | Strategy | Concepts |
|---|---|---|
mean_reversion.ipynb |
Z-score mean reversion | Parameter sensitivity, OU process |
sma_crossover.ipynb |
SMA crossover | Trend following, signal generation |
pairs_trading.ipynb |
Statistical arbitrage | Cointegration, spread trading |
build_your_own_strategy.ipynb |
Bollinger Band Breakout | Full walkthrough from scratch |
Contributing
See CONTRIBUTING.md. Open areas:
- VWAP / TWAP algos: child order slicing in
ExecutionEngine - Multi-strategy portfolio: shared capital with a meta-allocator
- Parallel sweeps:
n_jobsworks but Windows process spawn overhead (~500ms per worker) makes it slower than sequential for short backtests. On Linux the break-even is much lower and it works as expected. Use Linux or WSL for parallel parameter sweeps.
The engine doesn't handle survivorship bias or timezone normalization. Feed it clean adjusted data and those aren't problems.
License
MIT: see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quantcore-1.0.0-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: quantcore-1.0.0-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 384.2 kB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e82b815b51db0c0056e581d734297ef7fd074029434d4db14172fcb2bf695d90
|
|
| MD5 |
123e9a5505720cc9b9acf7ddd7070bfc
|
|
| BLAKE2b-256 |
5d30d7a51a0674f90f57c19611c7f0e8dde812b976abfa22c6b38f03187941da
|
File details
Details for the file quantcore-1.0.0-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: quantcore-1.0.0-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 1.0 MB
- Tags: CPython 3.12, manylinux: glibc 2.26+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0c8a037011eb96dc487a89fc5f06534006f98e874e0897260e0521ed184aa0af
|
|
| MD5 |
aac57db133d7aa8bcf79070fdfc2bfa2
|
|
| BLAKE2b-256 |
bd51eb946bd958995d7a4979892194f25386b1ad326ab36b109bddc4bda2e46e
|
File details
Details for the file quantcore-1.0.0-cp312-cp312-macosx_15_0_arm64.whl.
File metadata
- Download URL: quantcore-1.0.0-cp312-cp312-macosx_15_0_arm64.whl
- Upload date:
- Size: 338.1 kB
- Tags: CPython 3.12, macOS 15.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77f43387d5f4e0d2587dcc1683366df4ec3b6485575f63e7f4ded4f4b0b31a0d
|
|
| MD5 |
ab874a303c159347fb1a527e2b429f05
|
|
| BLAKE2b-256 |
600886982eb9b02739a34f4ca1bb67608d4ce6ee34e907aa563f3374f707acc0
|
File details
Details for the file quantcore-1.0.0-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: quantcore-1.0.0-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 382.6 kB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
41ee911d4e457518b7f552cda99a09afd83dca73ce199aecb5acfd033eb32636
|
|
| MD5 |
cfa578c633bbdcf8e8bc4a047891709e
|
|
| BLAKE2b-256 |
d9ae21699a6c62f19a91739332c35757cb4c0d4d0fd2c9bd5651524755419b7e
|
File details
Details for the file quantcore-1.0.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: quantcore-1.0.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 1.0 MB
- Tags: CPython 3.11, manylinux: glibc 2.26+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d4cc066ebec0f4daffce6ffbbf7ad466d32f6a3d21adfcf2cfeb671ca547888
|
|
| MD5 |
d2ba28b38fd2aeb9cece7c11dbd49baf
|
|
| BLAKE2b-256 |
ca7802100691f4cd05af7e92f94b2930f6fa5979a6556e635b6c84939bf68a80
|
File details
Details for the file quantcore-1.0.0-cp311-cp311-macosx_15_0_arm64.whl.
File metadata
- Download URL: quantcore-1.0.0-cp311-cp311-macosx_15_0_arm64.whl
- Upload date:
- Size: 336.5 kB
- Tags: CPython 3.11, macOS 15.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
355cd376d2f5cbcd8a0deea4559e1fddb0f61c0a1f4d74ee60c8c522b50c75b2
|
|
| MD5 |
c1a52354dac12bfaab34ca69d7c3d0e9
|
|
| BLAKE2b-256 |
6e6ef46f4dec2903828bda9febcf554246cbd4eed999d46dec8a936d19bf682a
|
File details
Details for the file quantcore-1.0.0-cp310-cp310-win_amd64.whl.
File metadata
- Download URL: quantcore-1.0.0-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 381.8 kB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3154df1a054eac8845a1258eb47c94dc7e988f29616945b6a3e80612394e8289
|
|
| MD5 |
acf0d5b599f71bc220a6deddc993eaf7
|
|
| BLAKE2b-256 |
2407af1b46a91dceaea3e5a7c348944d20127510c7f4b5a8bb7e0c9fb3d4d115
|
File details
Details for the file quantcore-1.0.0-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: quantcore-1.0.0-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 1.0 MB
- Tags: CPython 3.10, manylinux: glibc 2.26+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9472db4f5378786d27e4590e98ab7c95d1cfd6147958853e6df5c2a37f2c721e
|
|
| MD5 |
6401fb19887e4f37fc2d907ba1671677
|
|
| BLAKE2b-256 |
677554c0a3c8d7e40aa5256d5f7172df1e3a8e0804affc2ae0dc234fea7b27b7
|
File details
Details for the file quantcore-1.0.0-cp310-cp310-macosx_15_0_arm64.whl.
File metadata
- Download URL: quantcore-1.0.0-cp310-cp310-macosx_15_0_arm64.whl
- Upload date:
- Size: 335.6 kB
- Tags: CPython 3.10, macOS 15.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
13f090ebf779cc1e6dd1cebc9ce6e9f6e7e7ec877ba55ae55c5b3a7eda8e0172
|
|
| MD5 |
de8ff11d669f1e82566124979cc0c3c5
|
|
| BLAKE2b-256 |
aff77cc76cabc2f0b7812c899f34f88e41fded6f72db00c4b1d302c4e212ca2d
|
File details
Details for the file quantcore-1.0.0-cp39-cp39-win_amd64.whl.
File metadata
- Download URL: quantcore-1.0.0-cp39-cp39-win_amd64.whl
- Upload date:
- Size: 399.0 kB
- Tags: CPython 3.9, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7913e0aac6404ae98b3e1e52c25b179970bcc763b3f4e5b58a2ec8d29b4cd8f4
|
|
| MD5 |
66472f629f120e29c3437088179cc6cf
|
|
| BLAKE2b-256 |
b1473b018cbb00fda39af7558b6bdc8436339e83bb7fb33264da42c910613c47
|
File details
Details for the file quantcore-1.0.0-cp39-cp39-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: quantcore-1.0.0-cp39-cp39-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 1.0 MB
- Tags: CPython 3.9, manylinux: glibc 2.26+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db244fec81efdfbdc586ff00844b372fcb69207a006fd8a5272a5e88171b81a5
|
|
| MD5 |
1e8edea252bfd680355fd1c4159ea72d
|
|
| BLAKE2b-256 |
874fba12b8580b26e0002f52086f17b9dd7bc93d303b467576a995e6cc524bc0
|
File details
Details for the file quantcore-1.0.0-cp39-cp39-macosx_15_0_arm64.whl.
File metadata
- Download URL: quantcore-1.0.0-cp39-cp39-macosx_15_0_arm64.whl
- Upload date:
- Size: 335.7 kB
- Tags: CPython 3.9, macOS 15.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46c503ca3e87e5c03c03d9488c29ed3b526f5727956af14e3330330f2a0f65b5
|
|
| MD5 |
e84731a49809a27ebc69066f61488702
|
|
| BLAKE2b-256 |
2654ef4db71e820bca1b444806208cc8c733dca4f81a01f1844feeb3e04f8f4f
|