quantlab.portfolio.base.DecisionPanel#

class quantlab.portfolio.base.DecisionPanel(timestamps, symbols, predictions, tradable, valuation_prices=None, rows=None, history_bars=1, factors=None, risk_exposures=None, risk_estimates=None)[source]#

Bases: object

What a rule may read at a block of decision bars at once: the panel counterpart of a context.

DecisionInputs.panel assembles it for the approximate backtest (quantlab.backtest.approximate), from the same reads as the per-bar context. It holds no holdings.

Attributes:
timestampspd.DatetimeIndex

The decision bars, in time order.

symbolsnp.ndarray

The symbols, the second axis of every array here.

predictionsxr.Dataset

Every label’s prediction at the bars: one variable per label name on (timestamp, symbol).

tradablenp.ndarray

Booleans [bars, symbols]: whether the symbol can be traded at the bar, as PortfolioContext.tradable judges it.

valuation_pricesnp.ndarray or None

[rows, symbols]: the raw valuation prices from the first bar’s warm-up to the last bar, the prices every bar’s return window and staleness are read from (return_windows, staleness); None in a panel built by hand for a rule that reads none.

rowsnp.ndarray or None

Each bar’s row in valuation_prices.

history_barsint

Raw prices up to and including a bar that its window reads, as InputDeclaration.history_bars.

factorsxr.Dataset or None

The values at the bars of the Factor panels the rule declares (InputDeclaration.factors): one variable per factor name on (timestamp, symbol), NaN where a symbol has none, as each bar’s PortfolioContext.factors holds them. None when the rule declares none.

risk_exposuresxr.Dataset or None

The exposures of the declared factor risk model at the bars, on (timestamp, symbol), as each bar’s PortfolioContext.risk_exposures holds them; None when the rule declares no risk model.

risk_estimatesxr.Dataset or None

The model’s estimate store’s rows at the bars it has a row for, on their own timestamp axis: bar t’s row is its context’s risk_estimate, and a bar without one has none. None when the rule declares no risk model or the store has no row at the bars.

Examples

>>> panel = DecisionPanel(
...     timestamps=pd.DatetimeIndex(["2024-01-02", "2024-01-03"]),
...     symbols=np.array(["AAA", "BBB"]),
...     predictions=xr.Dataset(
...         {"ret": (("timestamp", "symbol"), [[0.1, 0.2], [0.3, np.nan]])},
...         coords={"timestamp": pd.DatetimeIndex(["2024-01-02", "2024-01-03"]), "symbol": ["AAA", "BBB"]},
...     ),
...     tradable=np.array([[True, True], [True, False]]),
...     valuation_prices=np.array([[10.0, 20.0], [11.0, 20.0], [12.1, np.nan]]),
...     rows=np.array([1, 2]),
...     history_bars=3,
... )
>>> panel.tradable.shape
(2, 2)
return_windows(bars, lookback)[source]#

[len(bars), lookback, symbols]: the bars’ trailing one-bar returns, as each context holds them.

Bar k’s window equals the last lookback rows of PortfolioContext.returns at that bar: the bar’s last history_bars valuation prices forward-filled within themselves alone, so a price before them never fills a gap, NaN before a symbol’s first price in them (and NaN rows when fewer than lookback + 1 prices are there).

Parameters:
barsnp.ndarray

Positions of the bars in the panel.

lookbackint

Returns per window.

Returns:
np.ndarray

Examples

>>> panel.return_windows(np.array([1]), 2)
array([[[0.1, 0. ],
        [0.1, 0. ]]])
staleness()[source]#

[bars, symbols]: each bar’s PortfolioContext.staleness.

The bars since the symbol’s last real valuation price within the bar’s last history_bars prices, NaN with none there.

Examples

>>> panel.staleness()  # BBB's last price is a bar before the second bar
array([[0., 0.],
       [0., 1.]])