Presets + CLI

Declarative TOML configs and the horizon command

You can run a full backtest without writing any Python by using a .hz.toml preset and the CLI.

Bundled presets

bash
PYTHONPATH=. python3 -m horizon.cli presets list

Output:

text
equity_mean_reversion
tech_momentum

Show the contents of one:

bash
PYTHONPATH=. python3 -m horizon.cli presets show equity_mean_reversion

Running a preset

bash
PYTHONPATH=. python3 -m horizon.cli run equity_mean_reversion

Output:

text
backtest complete
  sharpe       = -0.456
  sortino      = -0.598
  total return = -3.988%
  max drawdown = 11.820%
  n trades     = 545

Writing your own preset

Presets are TOML files. Create my_preset.hz.toml:

toml
mode = "backtest"

[asset_classes]
classes = ["equity"]

[[universe]]
type = "static"
markets = ["AAPL", "MSFT", "NVDA", "GOOGL", "AMZN"]
asset_class = "equity"

[[strategies]]
type = "horizon.quant.BollingerMeanRev"
window = 20
entry_z = 2.0
edge_bps = 50

[portfolio]
type = "kelly"
kelly_fraction = 0.25
max_gross_leverage = 1.0
transaction_cost_bps = 5

[risk]
profile = "moderate"
max_gross_leverage = 1.0

[venues.paper]
type = "paper"
initial_cash_usd = 100_000

[backtest]
initial_cash_usd = 100_000

Run:

bash
PYTHONPATH=. python3 -m horizon.cli run ./my_preset.hz.toml

Preset schema

Cloning a preset

Copy a starter and modify it:

bash
cp /path/to/horizon/presets/equity_mean_reversion.hz.toml ./mine.hz.toml
# edit mine.hz.toml
PYTHONPATH=. python3 -m horizon.cli run ./mine.hz.toml

Loading from Python

Sometimes you want to load the preset but override something programmatically (e.g., swap in a live data source):

python
from horizon import run
from horizon.presets_loader import load_preset
from horizon.data import SyntheticGBM

kwargs = load_preset("my_preset.hz.toml")
kwargs["data_source"] = SyntheticGBM(
    market_ids=["AAPL", "MSFT", "NVDA", "GOOGL", "AMZN"],
    n_bars=252,
    seed=1,
)
result = run(**kwargs)

load_preset() returns a dict of hz.run(**kwargs) arguments: everything is a normal Python value you can override.

Convenience: hz.run_preset()

Skip the load+run dance:

python
import horizon as hz

result = hz.run_preset("my_preset.hz.toml")

CLI commands

CommandEffect
horizon run <preset>Run a bundled preset by name or a .hz.toml file path
horizon presets listList bundled presets
horizon presets show <name>Print a bundled preset’s contents
horizon versionPrint the package version

Next