Backtest.Net
4.1.15
dotnet add package Backtest.Net --version 4.1.15
NuGet\Install-Package Backtest.Net -Version 4.1.15
<PackageReference Include="Backtest.Net" Version="4.1.15" />
<PackageVersion Include="Backtest.Net" Version="4.1.15" />
<PackageReference Include="Backtest.Net" />
paket add Backtest.Net --version 4.1.15
#r "nuget: Backtest.Net, 4.1.15"
#:package Backtest.Net@4.1.15
#addin nuget:?package=Backtest.Net&version=4.1.15
#tool nuget:?package=Backtest.Net&version=4.1.15
High-Performance Backtest.Net
A high-performance backtesting engine for algorithmic trading strategies in .NET.
Introduction
High-Performance Backtest.Net is a specialized backtesting library designed for quantitative trading applications. It processes multi-timeframe candlestick data across multiple symbols, simulating tick-by-tick strategy execution with proper warmup periods and OHLC handling.
Key Characteristics
- Multi-Symbol Support: Process multiple trading symbols in parallel
- Multi-Timeframe: Handle multiple timeframes per symbol with automatic synchronization
- Performance Optimized: 10 iteratively optimized engine versions with zero-allocation patterns
- Data Splitting: Intelligent data partitioning for memory-efficient large-scale backtests
- Cancellation Support: Graceful async cancellation with progress tracking
Features
| Feature | Description |
|---|---|
| EngineV10 | Latest engine with Span-based iteration, binary search, and parallel processing |
| SymbolDataSplitter | Partitions large datasets into memory-efficient chunks |
| Warmup Handling | Configurable warmup candle counts per timeframe |
| OHLC Simulation | Accurate current-candle OHLC handling during backtest |
| Progress Tracking | Real-time progress from 0-100% |
| SIMD Acceleration | Leverages SimdLinq for vectorized operations |
Performance Optimizations
The library implements sophisticated performance techniques:
- Zero-Allocation Hot Paths: Uses
Span<T>andCollectionsMarshal.AsSpan - Parallel Processing:
Parallel.ForEachfor symbol-level parallelism - Binary Search: O(log n) candlestick lookups
- Aggressive Inlining:
[MethodImpl(MethodImplOptions.AggressiveInlining)] - Sealed Classes: JIT optimization hints
Installation
Package Manager
dotnet add package Backtest.Net
PackageReference
<PackageReference Include="Backtest.Net" Version="4.1.14" />
Requires .NET 10.0 or later.
Quickstart
Basic Engine Usage
using Backtest.Net.Engines;
using Backtest.Net.SymbolsData;
using Backtest.Net.SymbolDataSplitters;
using Backtest.Net.Timeframes;
using Backtest.Net.Enums;
// 1. Prepare your symbol data (candlesticks per timeframe)
// Candlestick properties: OpenTime, Open, High, Low, Close, CloseTime, Volume
var symbolsData = new List<SymbolDataV2>
{
new SymbolDataV2
{
Symbol = "BTCUSDT",
Timeframes = new List<TimeframeV2>
{
new TimeframeV2
{
Timeframe = CandlestickInterval.OneMinute,
Candlesticks = yourOneMinuteCandles
},
new TimeframeV2
{
Timeframe = CandlestickInterval.OneHour,
Candlesticks = yourOneHourCandles
}
}
}
};
// 2. Split data for efficient processing
var splitter = new SymbolDataSplitterV2(
daysPerSplit: 30,
warmupCandlesCount: 100,
backtestingStartDateTime: new DateTime(2024, 1, 1)
);
var splitData = await splitter.SplitAsyncV2(symbolsData);
// 3. Create and configure the engine
var engine = new EngineV10(
warmupCandlesCount: 100,
sortCandlesInDescOrder: false,
useFullCandleForCurrent: false
);
// 4. Set up your strategy callback
engine.OnTick = async (symbolData) =>
{
foreach (var symbol in symbolData)
{
var latestCandle = symbol.Timeframes[0].Candlesticks[^1];
// Your strategy logic here
Console.WriteLine($"{symbol.Symbol}: Close = {latestCandle.Close}");
}
};
// 5. Run the backtest
await engine.RunAsync(splitData);
Console.WriteLine($"Progress: {engine.GetProgress()}%");
With Cancellation Support
using var cts = new CancellationTokenSource();
engine.OnCancellationFinishedDelegate = () =>
{
Console.WriteLine("Backtest cancelled gracefully");
};
// Cancel after 30 seconds
cts.CancelAfter(TimeSpan.FromSeconds(30));
await engine.RunAsync(splitData, cts.Token);
Engine Versions
| Engine | Description | Use Case |
|---|---|---|
EngineV8 |
SymbolDataV2 support | Standard workloads |
EngineV9 |
Optimized OHLC handling | Memory-sensitive scenarios |
EngineV10 |
Full optimization suite | Production recommended |
Use EngineV10 for new projects. It provides the best performance through zero-allocation patterns and parallel processing.
Benchmarks
Performance benchmarks run on Apple M3 Max with .NET 10.0, processing 4 million candlesticks (1 symbol × 4 timeframes × 1,000,000 candles each):
| Method | Mean | Error | StdDev | Gen0 | Allocated |
|---|---|---|---|---|---|
| EngineV8Run | 99.78 ns | 1.564 ns | 1.463 ns | 0.0621 | 520 B |
| EngineV9Run | 96.69 ns | 1.933 ns | 2.148 ns | 0.0631 | 528 B |
| EngineV10Run | 80.16 ns | 1.553 ns | 1.453 ns | 0.0545 | 456 B |
Key findings:
- EngineV10 is ~20% faster than EngineV8 and ~17% faster than EngineV9
- EngineV10 allocates 12% less memory than EngineV8
- All engines maintain sub-100ns per-tick latency
- .NET 10 migration improved all engines by ~20% compared to .NET 9
Benchmarks run with BenchmarkDotNet v0.15.8 on macOS Tahoe 26.2, Apple M3 Max, .NET 10.0
Development
Prerequisites
- .NET 10.0 SDK or later
- Git
Build
git clone https://github.com/islero/High-Performance-Backtest.Net.git
cd High-Performance-Backtest.Net
dotnet build
Test
dotnet test
Benchmark
cd benchmarks/Backtest.Net.Benchmarks
dotnet run -c Release
Format
dotnet format
Versioning & Releases
This project follows Semantic Versioning.
| Branch | Version Format | NuGet Feed |
|---|---|---|
master |
X.Y.Z (stable) |
nuget.org |
beta |
X.Y.Z-beta.N (prerelease) |
nuget.org |
Release Process
- Update version in
src/Backtest.Net/Backtest.Net.csproj - Create GitHub Release with tag
vX.Y.Z - CI automatically publishes to NuGet
Contributing
Contributions are welcome! Please read CONTRIBUTING.md for guidelines.
License
This project is licensed under the GNU Lesser General Public License v3.0.
Acknowledgments
- SimdLinq - SIMD-accelerated LINQ operations
- BenchmarkDotNet - Performance benchmarking
<p align="center"> Built for the algorithmic trading community </p>
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- SimdLinq (>= 1.3.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Migrated project to .NET 10, updated benchmarks and README accordingly, optimized `SymbolDataSplitterV2` by removing redundant `.ToList()` calls, and improved candlestick processing efficiency with in-place modifications.