TOML Schema
The .hz.toml format for declarative backtest configs
Presets are TOML files that describe a full backtest configuration. The preset loader parses them and constructs the arguments to hz.run().
Top-level fields
toml
mode = "backtest" # backtest | paper | shadow | live
[asset_classes]
classes = ["equity"]
[[universe]]
type = "static"
markets = ["AAPL", "MSFT", "NVDA"]
asset_class = "equity"
[[strategies]]
type = "horizon.quant.BollingerMeanRev"
window = 20
entry_z = 2.0
[portfolio]
type = "kelly"
kelly_fraction = 0.25
[risk]
profile = "moderate"
max_gross_leverage = 1.0
[venues.paper]
type = "paper"
initial_cash_usd = 100_000
[backtest]
start = "2023-01-01"
end = "2024-12-31"
initial_cash_usd = 100_000
Sections
What’s NOT in presets
Presets cover the common case. For advanced features, use the Python API:
- Custom Python strategies (beyond dotted-path imports)
- Full
RiskConfig: stacked drawdown guards, custom stops, per-asset-class rules - Custom sizers
- Custom data sources
- Custom executors
LifecycleConfigMetricsConfig
The preset is the “80% case”. zero-code config for standard backtests. Anything more sophisticated uses Python.
Loading from Python
python
from horizon.presets_loader import load_preset
kwargs = load_preset("my_preset.hz.toml")
# kwargs is a dict ready to pass to hz.run(**kwargs)
# Override anything before running
kwargs["data_source"] = my_custom_source
result = hz.run(**kwargs)
Validation
Parsing errors raise ValueError at load time:
python
# Unknown portfolio type
[portfolio]
type = "nonsense"
# → ValueError: Unknown portfolio type 'nonsense'
# Missing strategy type
[[strategies]]
lookback = 20
# → ValueError: strategy entry missing 'type'
Errors are caught at load: you don’t discover bad config 10 bars into a backtest.