quantlab.backtest.approximate.ApproximateBacktest#

class quantlab.backtest.approximate.ApproximateBacktest(config)[source]#

Bases: Component

Decide every rebalance of a prediction panel at once and simulate the window as arrays.

Built once over config.price_dataset and the window, then run many times. The market conventions (the fill and valuation price columns, the annualisation) are MARKET, set by a concrete class such as quantlab.backtest.predefined.us_equity.USEquityApproximateBacktest. The window’s prices are read on the first run and kept.

Parameters:
configApproximateBacktestConfig

The price dataset, the window, rebalance_periods, the cost rate, the chunk size and the solver’s stopping rule.

Raises:
TypeError

If config is not an ApproximateBacktestConfig or the class sets no MARKET.

Examples

>>> from quantlab.backtest.config import ApproximateBacktestConfig
>>> from quantlab.backtest.predefined.us_equity import USEquityApproximateBacktest
>>> backtest = USEquityApproximateBacktest(
...     ApproximateBacktestConfig(
...         price_dataset=prices, start_date="2024-03-25", end_date="2024-06-26",
...         rebalance_periods=5, cost=0.0005,
...     )
... )
>>> predictions = BacktestRun.open(run_dir).predictions()
>>> account = backtest.run(predictions, TopNConstructor(TopNConfig(direction="long_only", top_n=4)))
>>> round(account.metrics["whole"]["Total Return [%]"], 2)  # the backtest run's: 9.51
9.49
MARKET = None#

The market’s price columns and annualisation; set by a concrete class.

config_cls#

alias of ApproximateBacktestConfig

run(predictions, constructor)[source]#

Backtest one prediction panel with one rule and return the account.

The rule’s implementation is found first (quantlab.portfolio.approximate.implementation: its exact class, its config’s fields and its covariance estimator), before any data is read, then the rule is bound to the panel’s label specs. The predictions are spread over the window’s prices (a symbol without one is never picked) and both are cut to the symbols the rule decides on (DecisionInputs.decision_symbols, as a backtest run keeps), the schedule names the decision bars, and each chunk of chunk_bars bars is decided once, in time order, from the weights decided before it.

Parameters:
predictionsPredictionPanel

The predictions and their label specs, for instance a run’s (BacktestRun.predictions()).

constructorPortfolioConstructor

The rule, with the config a backtest run would take.

Returns:
ApproximateAccount
Raises:
TypeError

If constructor is not a PortfolioConstructor.

ValueError

If the approximate backtest does not run the rule as configured (the message names the rule, the estimator or the field), the rule refuses the labels, or the window has fewer than two price bars.

Examples

>>> account = backtest.run(predictions, rule)
>>> account.value.sizes
Frozen({'timestamp': 68})