Skip to content

Study


class backtide.backtest.study.Study(config=None, strategy=None, parameter_space=None, min_trades=0, max_drawdown=None, walk_forward=None)[source]

Run a study with a parameter sweep and optional walk-forward validation.

A study helps assess a strategy's robustness by comparing multiple experiments across a parameter neighborhood. Full-sample candidate experiments are persisted under one study record. Walk-forward training and test experiments are temporary: Backtide summarizes each fold into the study and removes the temporary experiments immediately.

Parameters

config : ExperimentConfig | None, default=None

Complete experiment settings shared by every candidate.

strategy : str | BaseStrategy | None, default=None
Saved strategy name or runtime strategy instance. When omitted, exactly one saved strategy must be selected in config.

parameter_space : dict[str, sequence[object]] | None, default=None
Constructor parameter values whose Cartesian product forms the sweep.

min_trades : int, default=0
Exclude candidates with fewer completed trades.

max_drawdown : float | None, default=None
Exclude candidates whose drawdown magnitude exceeds this positive fraction. For example, 0.25 permits at most a 25% drawdown.

walk_forward : WalkForwardConfig | None, default=None
Optional rolling or anchored out-of-sample validation.


See Also

Experiment

Configure and run one historical backtest experiment.

query_study

Return a persisted study.

StudyResult

Return the persisted result of a study.


Example

>>> from math import prod

>>> from backtide import ExperimentConfig, Study, WalkForwardConfig

>>> config = ExperimentConfig.from_dict(
...     {
...         "general": {"name": "SMA parameter study"},
...         "data": {
...             "symbols": ["SPY"],
...             "full_history": False,
...             "start_date": "2012-01-01",
...             "end_date": "2025-12-31",
...         },
...         "strategy": {"strategies": ["My SMA strategy"]},
...     }
... )
>>> study = Study(
...     config,
...     parameter_space={"fast": [10, 20, 30], "slow": [100, 150, 200]},
...     min_trades=30,
...     walk_forward=WalkForwardConfig(training_days=1095, test_days=365),
... )
>>> print(f"{prod(len(values) for values in study.parameter_space.values())} candidates")

9 candidates
>>> result = study.run(verbose=False)  


Methods

run Run and persist the study.


method run(verbose=True, progress_callback=None)[source]

Run and persist the study.

Parameters

verbose : bool, default=True

Show experiment progress output.

progress_callback : Callable[[float, int], None] | None, default=None
Receive (completed, total) candidate-run progress across the full-sample sweep and every walk-forward experiment.

Returns

StudyResult

Candidate rankings, walk-forward folds, and study id.