quantlab.backtest.predefined.weights.WeightsVectorBt#

class quantlab.backtest.predefined.weights.WeightsVectorBt(config)[source]#

Bases: VectorBtBacktester

Backtest given target weights with vectorbt, on the market its config describes.

MARKET is built from the config’s fill_price_column, valuation_price_column, trading_days_per_year and session_minutes_per_day whenever a config is assigned. Everything else is VectorBtBacktester’s: a weight formed at bar t fills at bar t+1’s fill price, and the metrics cover the whole window.

Parameters:
configWeightsBacktestConfig

The price dataset, window, costs, optional benchmark and market conventions; model and model_mode must be None.

Raises:
TypeError

If config is not a WeightsBacktestConfig.

ValueError

If the config carries a model, a price column name is empty, the day or session length is below 1, or the recorded top_n or direction is invalid.

Examples

>>> import numpy as np
>>> import pandas as pd
>>> import xarray as xr
>>> from quantlab.backtest.predefined.weights import WeightsVectorBt
>>> from quantlab.backtest.config import WeightsBacktestConfig
>>> from quantlab.dataset.memory import FrameDataset
>>> bars = pd.bdate_range("2024-01-01", periods=5)
>>> prices = FrameDataset(pd.DataFrame({
...     "timestamp": np.repeat(bars, 2),
...     "symbol": ["AAA", "BBB"] * 5,
...     "open": [10.0, 20.0, 11.0, 20.0, 12.0, 21.0, 12.0, 22.0, 13.0, 22.0],
...     "close": [10.5, 20.0, 11.5, 20.5, 12.0, 21.5, 12.5, 22.0, 13.0, 22.5],
... }))
>>> backtester = WeightsVectorBt(WeightsBacktestConfig(
...     price_dataset=prices, start_date="2024-01-01", end_date="2024-01-05",
...     output_dir=None, rebalance_periods=1, fees=0.0, slippage=0.0,
...     fill_price_column="open", valuation_price_column="close",
...     trading_days_per_year=252, session_minutes_per_day=390,
... ))
>>> backtester.MARKET.fill_price_column
'open'
>>> weights = xr.DataArray(
...     [[1.0, 0.0]] + [[np.nan, np.nan]] * 4, dims=("timestamp", "symbol"),
...     coords={"timestamp": bars, "symbol": ["AAA", "BBB"]},
... )
>>> result = backtester.run_weights(weights)
>>> result.simulation.value.values.round(2).tolist()
[1000000.0, 1045454.55, 1090909.09, 1136363.64, 1181818.18]

Kept on disk, the run rebuilds from its directory and replays its weights:

>>> import dataclasses, tempfile
>>> from quantlab.runs.backtest_run import BacktestRun
>>> kept = WeightsVectorBt(
...     dataclasses.replace(backtester.config, output_dir=tempfile.mkdtemp())
... ).run_weights(weights)
>>> run = BacktestRun.open(kept.run_dir)
>>> replay = run.rebuild_backtester().run_weights(run.weights())
>>> replay.simulation.value.values.round(2).tolist()
[1000000.0, 1045454.55, 1090909.09, 1136363.64, 1181818.18]
config_cls#

alias of WeightsBacktestConfig