Parameter Scan
Find the best strategy parameters automatically
hz.quick.scan() tests every combination of parameters you specify and ranks them by Sharpe.
Basic scan
python
import horizon as hz
scan = hz.quick.scan(
"mean_reversion",
params={
"window": [10, 15, 20, 30],
"entry_z": [1.5, 2.0, 2.5, 3.0],
},
tickers=["AAPL", "MSFT", "NVDA"],
)
print(scan.summary())
print(f"\nBest: {scan.best_params}")
print(f"Best Sharpe: {scan.best_result.sharpe:+.3f}")
This runs 16 backtests (4 windows x 4 entry thresholds) on the same data and shows the ranking.
Reading results
python
# Best parameters
scan.best_params # {"window": 20, "entry_z": 2.0}
# Best backtest result
scan.best_result.sharpe
scan.best_result.max_drawdown
scan.best_result.n_trades
# All results (dict of label -> BacktestResult)
for label, result in scan.results.items():
print(f"{label}: Sharpe={result.sharpe:+.3f}")
# Summary table (top 20 by Sharpe)
print(scan.summary())
Scanning different strategies
python
# Momentum lookback
scan = hz.quick.scan("momentum", params={"lookback": [5, 10, 20, 40, 60]})
# MA crossover windows
scan = hz.quick.scan("ma_cross", params={"fast": [5, 10, 15], "slow": [20, 30, 50]})
# RSI window and thresholds (pass any strategy-accepted params)
scan = hz.quick.scan("rsi", params={"window": [7, 14, 21]})
With regime data
Test parameter robustness across market regimes:
python
scan = hz.quick.scan(
"mean_reversion",
params={"window": [10, 20, 30], "entry_z": [1.5, 2.0, 2.5]},
data="regimes",
bars=500,
)
Parameters that work well on smooth data may fail under regime switches. Always validate with data="regimes".
Warning: overfitting
A parameter scan on synthetic data tells you which parameters work on that specific random path. It does not tell you which parameters will work in live trading.
To get honest estimates:
- Use
hz.quick.scan()to narrow the search - Take the best parameters and validate with Bootstrap confidence intervals
- Or use Walk-Forward to test out-of-sample
The scan is a research tool, not a deployment decision.