quantlab.runs.run_metrics.AccountRecord#

class quantlab.runs.run_metrics.AccountRecord(value, returns, orders, rebalances, init_cash, bar_interval, year_freq, trades=None, settlements=(), rejected_orders=(), max_target_deviation=None, holdings=None)[source]#

Bases: object

What one account did over its bars, in the form every engine produces.

The input of run_metrics. Every series is on the account’s own bars, a timestamp axis.

Attributes:
valuexarray.DataArray

The account’s value after each bar, on timestamp.

returnsxarray.DataArray

Its per-bar returns on the same bars.

ordersxarray.Dataset

One fill per entry of an order dimension: timestamp (the fill bar), symbol, size (signed or not), price and fees. A dataset without an order dimension means no fills.

rebalancesxarray.Dataset

The rebalance record: scheduled and decided, booleans on timestamp. Turnover and the rebalance win rate count its decided bars.

init_cashfloat

The value before the first bar.

bar_interval

The bar spacing, anything pandas.Timedelta accepts.

year_freqpandas.Timedelta

One year, backtest_stats.year_freq of the bar spacing.

tradesxarray.Dataset or None

The round trips on a trade dimension, with entry_timestamp, exit_timestamp and status ("Open" or "Closed"); None or empty when nothing traded.

settlementssequence of dict

The delisting settlements among orders (settlement_timestamp and axis_symbol, the order’s symbol), left out of turnover. Empty when orders holds only rebalance fills.

rejected_orderssequence of dict

Orders that found no fill price, each with its fill_timestamp; the holding was kept.

max_target_deviationfloat or None

The largest gap between a target weight and the weight held after its fill bar; None when nothing rebalanced.

holdingsxarray.DataArray or None

Each symbol’s share of the book after each bar, on (timestamp, symbol); not read by run_metrics: the report’s Holdings section (quantlab.runs.backtest_report).

Examples

>>> bars = pd.bdate_range("2024-01-01", periods=3)
>>> on_bars = dict(dims="timestamp", coords={"timestamp": bars})
>>> account = AccountRecord(
...     value=xr.DataArray([100.0, 110.0, 99.0], **on_bars),
...     returns=xr.DataArray([0.0, 0.1, -0.1], **on_bars),
...     orders=xr.Dataset({
...         "timestamp": ("order", bars[[1]].values), "symbol": ("order", ["AAA"]),
...         "size": ("order", [10.0]), "price": ("order", [10.0]), "fees": ("order", [0.0]),
...     }),
...     rebalances=xr.Dataset({
...         "scheduled": ("timestamp", [True, False, False]),
...         "decided": ("timestamp", [True, False, False]),
...     }, coords={"timestamp": bars}),
...     init_cash=100.0, bar_interval="1D",
...     year_freq=backtest_stats.year_freq("1D", 252, 390),
... )
>>> pd.DatetimeIndex(decided_bars(account.rebalances)).strftime("%Y-%m-%d").tolist()
['2024-01-01']