- Published on
Backtesting on Synthetic Data
Backtesting on Synthetic Data
This chapter argues that standard backtesting (historical simulation) is a flawed method for calibrating trading rules (like stop-losses and profit-taking barriers). This practice leads to backtest overfitting, where the rules are tuned to a single, random historical path and fail out-of-sample.
The solution proposed is to backtest on synthetic data. This method avoids overfitting by optimizing the trading rules based on the underlying stochastic properties of the asset, not on a single historical scenario.
The Problem: Backtest Overfitting of Trading Rules
A trading rule is defined by its stop-loss () and profit-taking () thresholds: .
The standard (and flawed) approach is to brute-force a historical backtest to find the rule that maximizes the in-sample Sharpe Ratio ():
This is overfit because it targets specific in-sample outliers and is not fit for the future.
The Solution: An Optimal Trading Rule (OTR) from Synthetic Data
The chapter proposes a method to find the Optimal Trading Rule (OTR) by modeling the price series as a stochastic process.
1. Model the Stochastic Process
The price is modeled as a mean-reverting Ornstein-Uhlenbeck (O-U) process, which is characterized by its mean-reversion speed (), volatility (), and long-term equilibrium price ().
- O-U Process Equation:
- Half-Life: The mean-reversion speed can be expressed by its half-life :
2. The Numerical Algorithm
Instead of a historical backtest, the OTR is found through a 5-step simulation:
- Estimate Parameters: Use OLS on the entire historical dataset to estimate the O-U parameters and .
- Create a Mesh: Define a grid of all possible trading rules (e.g., 20 stop-loss values 20 profit-take values).
- Generate Synthetic Paths: Using the estimated and , simulate a large number (e.g., 100,000) of new, synthetic price paths.
- Evaluate Mesh: Test every rule from the mesh (Step 2) against all 100,000 synthetic paths (Step 3).
- Find the OTR: Calculate the average Sharpe Ratio for each rule across all synthetic paths. The OTR is the rule with the highest average Sharpe Ratio.
Key Findings & Conclusion
This method generates a "heat map" of Sharpe Ratios for all possible trading rules.
- The experiments show that when a genuine mean-reverting property exists (low , positive forecast), a clear, stable optimal rule emerges.
- As the process approaches a random walk (high ), the heat map becomes noisy, and no stable optimal rule appears.
- This is the method's greatest strength: It prevents overfitting by confirming when no optimal rule exists, saving the researcher from "discovering" a false, overfit rule from a single historical path.

Advanced Synthetic Data: Markov-Switching Heston-Merton Model
While the Ornstein-Uhlenbeck process is useful for modeling mean-reversion, financial markets exhibit more complex behaviors, such as jumps and switching volatility regimes. In our RiskLabAI.data.synthetic_data.synthetic_controlled_environment module, we implement a powerful synthetic price generator that combines two models:
- Heston-Merton Model: This model generates prices with stochastic volatility (Heston) and sudden price jumps (Merton).
- Markov-Switching: The parameters of the Heston-Merton model (like drift, volatility-of-volatility, and jump intensity) are not constant. They are controlled by a hidden Markov-switching process, allowing the simulation to move between distinct regimes (e.g., "Bull Market," "Bear Market," "Crash").
Methodology
The core of the simulation is a Numba-optimized function that computes the log returns based on the Heston-Merton stochastic differential equations for price and volatility:
- Heston Volatility Process:
- Merton Jump-Diffusion (Price):
API reference
RiskLabAI implements these in Python and Julia (signatures auto-generated from the package source):
| Python | Julia |
|---|---|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |