Skip to content

hybridizer-io/SimpleStrategyBacktest

Repository files navigation

StrategyBacktest — GPU-Accelerated Trading Strategy Parameter Sweep

A GPU-accelerated exhaustive parameter sweep of Moving Average crossover strategies on real market data, powered by Hybridizer.

The program tests 78,804 combinations of (shortMA, longMA) parameters across a configurable price history and produces both a performance benchmark and a visual heatmap of strategy returns.

Prerequisites

Requirement Details
.NET 8.0 SDK Download
NVIDIA GPU Any CUDA-capable GPU (compute capability auto-detected at build time)
CUDA Toolkit 13.0 Version is set in Directory.Build.props — adjust <CUDAVersion> if needed
Hybridizer CLI Install with dotnet tool install -g hybridizer
C++ toolchain Visual Studio 2022+ with Desktop development with C++ workload (Windows) or GCC (Linux)

Note

The build system automatically detects your GPU architecture via nvidia-smi — no manual -gencode flags needed.

Build

Always build in Release mode for accurate benchmark results. Debug mode disables compiler optimizations and gives misleading timings.

# Restore NuGet packages (first time only)
dotnet restore

# Build in Release mode
dotnet build --configuration Release

What happens during build

The build pipeline has three stages:

  1. C# compilation — Standard dotnet build compiles the project
  2. Hybridizer code generation — The GenerateCUDA target invokes hybridizer to transpile [EntryPoint] / [Kernel] methods into CUDA C++ (output in generated-sources/)
  3. CUDA compilation — The CompileCUDA target calls nvcc to compile the generated C++ into a native GPU DLL (StrategyBacktest_CUDA.dll)

Tip

If you don't have a GPU, the build will fail at step 3. You can disable GPU compilation by removing <CompileCUDA>enable</CompileCUDA> from StrategyBacktest.csproj — the program will then fall back to CPU-only execution at runtime.

Run

dotnet run --configuration Release --no-build -- [options]

Important

The -- separator is required before program arguments to distinguish them from dotnet options.

Options

Option Description Default
--file <path> Load price data from a local CSV file (downloads from Yahoo Finance)
--symbol <ticker> Yahoo Finance ticker symbol to download BTC-USD
--days <count> Number of days of history to download 3650 (10 years)

Examples

# Download BTC-USD data automatically (default)
dotnet run --configuration Release --no-build

# Use a local CSV file
dotnet run --configuration Release --no-build -- --file btc_history.csv

# Download Apple stock data
dotnet run --configuration Release --no-build -- --symbol AAPL

# Download 5 years of Ethereum data
dotnet run --configuration Release --no-build -- --symbol ETH-USD --days 1825

Data sources

The program tries to download price data from the Yahoo Finance API. If the download fails (network error, rate limit, etc.), it automatically falls back to synthetic price data generated via geometric Brownian motion, so the benchmark always runs.

CSV file format

Standard Yahoo Finance CSV format is supported:

Date,Open,High,Low,Close,Adj Close,Volume
2024-01-02,42681.37,44733.25,42526.00,44156.78,44156.78,6543567891

The loader looks for a Close column in the header (falls back to Adj Close, then the second column).

To download a CSV manually:

  1. Go to https://finance.yahoo.com/quote/BTC-USD/history/
  2. Set the time period (at least 2 years recommended)
  3. Click Download
  4. Run with --file downloaded.csv

Output

The program produces:

  • Benchmark timing — Execution time with GPU (or CPU fallback)
  • Best/worst strategy — The parameter combinations with highest and lowest returns
  • Heatmap PNG (strategy_heatmap.png) — Visual map of returns by parameter combination

Example output

GPU: NVIDIA GeForce RTX 4070 Laptop GPU
Loaded 3651 price data points
Parameter sweep: short MA [2..200], long MA [5..400]
Total combinations: 78804

Warmup...                                  done
Running benchmark...                         84 ms

  Best strategy:  MA(5,17) -> +432.15% return
  Worst strategy: MA(197,398) -> -87.23% return

Heatmap saved to: strategy_heatmap.png

When no GPU is available the program runs on CPU using Parallel.For and reports accordingly.

How it works

Parameter sweep

The program performs an exhaustive sweep over all combinations of short and long moving average periods:

Parameter Range Count
Short MA 2 to 200 199 values
Long MA 5 to 400 396 values
Total 78,804 combinations (~59,500 valid where short < long)

Backtest logic

For each (shortMA, longMA) combination, starting with $10,000:

  1. Compute both moving averages at each time step (naive O(window) sum)
  2. Detect golden cross (short MA crosses above long MA) → buy
  3. Detect death cross (short MA crosses below long MA) → sell
  4. Track equity and compute total return

GPU acceleration

Factor Why it helps
Massive parallelism Each of the 78,804 combinations runs as an independent GPU thread
High arithmetic intensity Naive SMA = O(window_size) per data point per combination
Read-only shared data Price array (~15 KB) fits entirely in GPU L2 cache
Minimal transfers Prices uploaded once, results downloaded once

Hybridizer approach

The code uses idiomatic C#: the backtest lives in a [Kernel] method (RunBacktest) called from a [EntryPoint] method (BacktestAll) via Parallel.For. Hybridizer transpiles this into CUDA C++ automatically — no pointer arithmetic, no manual memory management, no explicit thread indexing.

At runtime, the program checks for a compiled GPU DLL (*_CUDA.dll). If found, HybRunner wraps the entry point and dispatches it to the GPU. If not, the same Parallel.For code runs on CPU cores — the same source code powers both paths.

Project structure

StrategyBacktest/
├── Program.cs               # Entry point, GPU wrapper, backtest kernels
├── PriceDataLoader.cs        # CSV parser + Yahoo Finance downloader + synthetic fallback
├── HeatmapGenerator.cs       # PNG heatmap (ImageSharp) + ANSI console heatmap
├── StrategyBacktest.csproj   # Project file (Hybridizer + ImageSharp refs, CUDA build targets)
├── Directory.Build.props     # CUDA version setting
├── Directory.Build.targets   # GPU arch detection + nvcc compilation logic
└── generated-sources/        # (build output) Hybridizer-generated CUDA C++

License

No license specified.

About

A GPU-accelerated C# trading backtester that performs exhaustive parameter sweeps of Moving Average crossover strategies using Hybridizer.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages