qis.RiskModel

class qis.RiskModel(covar, factor_loadings=None, factor_covar=None, residual_vars=None)[source]

Bases: object

Dated covariance matrices with an optional point-in-time factor block.

The covariance at each date is authoritative for both the asset universe and total-risk computations. The optional factor block enables factor exposures and systematic/residual decompositions; it never replaces or rebuilds the supplied covariance.

Variables:
Raises:

ValueError – If the covariance or factor data are incomplete, non-finite, misaligned, non-unique, non-square, or non-symmetric.

Parameters:
__init__(covar, factor_loadings=None, factor_covar=None, residual_vars=None)
Parameters:
Return type:

None

Methods

__init__(covar[, factor_loadings, ...])

compute_benchmark_beta_at_date(...[, strict])

Compute ex-ante portfolio beta to a weighted benchmark.

compute_benchmark_beta_history(...[, strict])

Compute ex-ante benchmark beta on the covariance date grid.

compute_benchmark_beta_loadings_at_date(...)

Compute per-asset loadings to a weighted benchmark.

compute_exposures_at_date(portfolio_weights, ...)

Compute factor exposures on one covariance date.

compute_exposures_history(portfolio_weights)

Compute factor exposures on the covariance date grid.

compute_marginal_tre_at_date(...[, ...])

Compute canonical Euler marginal tracking-error contributions.

compute_tre_at_date(benchmark_weights, ...)

Compute ex-ante tracking error on one covariance date.

compute_tre_by_group_loadings_at_date(...[, ...])

Compute ex-ante tracking error for fractional or overlapping group loadings.

compute_tre_decomposition_at_date(...[, strict])

Decompose tracking error into factor and residual components.

compute_tre_decomposition_history(...[, strict])

Compute factor/residual tracking-error decomposition through time.

compute_tre_history(benchmark_weights, ...)

Compute ex-ante tracking error on the covariance date grid.

Attributes

dates

Sorted covariance date grid.

factor_covar

factor_loadings

residual_vars

covar

covar: Dict[Timestamp, DataFrame]
factor_loadings: Dict[Timestamp, DataFrame] | None = None
factor_covar: Dict[Timestamp, DataFrame] | None = None
residual_vars: Dict[Timestamp, Series] | None = None
property dates: DatetimeIndex

Sorted covariance date grid.

Returns:

Covariance dates in increasing order.

compute_tre_at_date(benchmark_weights, portfolio_weights, date, group_data=None, total_column='Total', strict=True)[source]

Compute ex-ante tracking error on one covariance date.

For active weights d = w_p - w_b, tracking error is sqrt(d' Sigma d). When groups are requested, each group result zeroes active weights outside that group before applying the full covariance. These standalone sleeve risks are not additive and are not forced to sum to total tracking error. No annualisation is applied.

Parameters:
  • benchmark_weights (Series) – Benchmark weights indexed by asset.

  • portfolio_weights (Series) – Portfolio weights indexed by asset.

  • date (Timestamp) – Exact covariance-grid date.

  • group_data (Series | None) – Optional group label per asset. Missing labels become 'Unassigned'.

  • total_column (str) – Label for total tracking error when groups are returned.

  • strict (bool) – If True, reject material weights outside the covariance universe.

Returns:

Total tracking error as a float, or total and standalone group tracking errors as a Series.

Raises:
  • KeyError – If date is not an exact covariance-grid date.

  • ValueError – If weights or model data violate the alignment policy.

Return type:

float | Series

compute_tre_by_group_loadings_at_date(benchmark_weights, portfolio_weights, date, group_loadings, total_column='Total', strict=True)[source]

Compute ex-ante tracking error for fractional or overlapping group loadings.

For active weights d = w_p - w_b and an asset-by-group loading matrix L, group g has standalone tracking error sqrt((d * L_g)' Sigma (d * L_g)). Loadings may be fractional, overlapping, or signed and need not sum to one. Group tracking errors are not additive and are not forced to sum to total tracking error. Missing covariance-universe rows and loading NaNs become zero; extra loading rows are ignored. No annualisation is applied.

Parameters:
  • benchmark_weights (Series) – Benchmark weights indexed by asset.

  • portfolio_weights (Series) – Portfolio weights indexed by asset.

  • date (Timestamp) – Exact covariance-grid date.

  • group_loadings (DataFrame) – Asset-by-group loading matrix. Column order defines result order.

  • total_column (str) – Label for total tracking error.

  • strict (bool) – If True, reject material weights outside the covariance universe.

Returns:

Series containing total and standalone group tracking errors.

Raises:
  • KeyError – If date is not an exact covariance-grid date.

  • ValueError – If weights or group loadings violate the alignment policy, loading labels are duplicated, values are nonnumeric or infinite, or total_column duplicates a group label.

Return type:

Series

compute_tre_history(benchmark_weights, portfolio_weights, group_data=None, total_column='Total', strict=True)[source]

Compute ex-ante tracking error on the covariance date grid.

Dated weights are selected as-of each covariance date using forward fill; dates before the first weight observation receive zero weights. The mathematics and group convention are those of compute_tre_at_date(). No annualisation is applied.

Parameters:
  • benchmark_weights (Series | DataFrame) – Static Series or dated DataFrame of benchmark weights.

  • portfolio_weights (Series | DataFrame) – Static Series or dated DataFrame of portfolio weights.

  • group_data (Series | None) – Optional group label per asset. Missing labels become 'Unassigned'.

  • total_column (str) – Label for total tracking error when groups are returned.

  • strict (bool) – If True, reject material weights outside the covariance universe.

Returns:

A Series named 'Tracking error', or a DataFrame containing total and standalone group tracking errors.

Raises:

ValueError – If weights or model data violate the alignment policy.

Return type:

Series | DataFrame

compute_exposures_at_date(portfolio_weights, date, strict=True)[source]

Compute factor exposures on one covariance date.

Loadings B have shape assets x factors and exposure is B' w. The construction-time alignment guarantee is retained: the method does not reindex or relax the loadings matrix.

Parameters:
  • portfolio_weights (Series) – Portfolio weights indexed by asset.

  • date (Timestamp) – Exact covariance-grid date.

  • strict (bool) – If True, reject material weights outside the covariance universe.

Returns:

Factor exposure Series indexed by factor.

Raises:
  • KeyError – If date is not an exact covariance-grid date.

  • ValueError – If factor_loadings is missing or weights violate the alignment policy.

Return type:

Series

compute_exposures_history(portfolio_weights, strict=True)[source]

Compute factor exposures on the covariance date grid.

Dated weights are selected as-of each covariance date using forward fill; dates before the first weight observation receive zero weights. At every date the exposure is B_t' w_t for asset-by-factor loadings B_t.

Parameters:
  • portfolio_weights (Series | DataFrame) – Static Series or dated DataFrame of portfolio weights.

  • strict (bool) – If True, reject material weights outside the covariance universe.

Returns:

DataFrame with covariance dates as rows and factors as columns.

Raises:

ValueError – If factor_loadings is missing or weights violate the alignment policy.

Return type:

DataFrame

compute_benchmark_beta_at_date(benchmark_weights, portfolio_weights, date, strict=True)[source]

Compute ex-ante portfolio beta to a weighted benchmark.

For portfolio weights w_p, benchmark weights w_b, and covariance Sigma, beta is (w_p' Sigma w_b) / (w_b' Sigma w_b). The factor block is not required.

Parameters:
  • benchmark_weights (Series) – Benchmark weights indexed by asset.

  • portfolio_weights (Series) – Portfolio weights indexed by asset.

  • date (Timestamp) – Exact covariance-grid date.

  • strict (bool) – If True, reject material weights outside the covariance universe.

Returns:

Scalar ex-ante portfolio beta to the benchmark.

Raises:
  • KeyError – If date is not an exact covariance-grid date.

  • ValueError – If weights violate the alignment policy or benchmark variance is nonpositive.

Return type:

float

compute_benchmark_beta_history(benchmark_weights, portfolio_weights, strict=True)[source]

Compute ex-ante benchmark beta on the covariance date grid.

Dated weights are selected as-of each covariance date using forward fill; dates before the first weight observation receive zero weights. At every date beta is (w_p' Sigma w_b) / (w_b' Sigma w_b).

Parameters:
  • benchmark_weights (Series | DataFrame) – Static Series or dated DataFrame of benchmark weights.

  • portfolio_weights (Series | DataFrame) – Static Series or dated DataFrame of portfolio weights.

  • strict (bool) – If True, reject material weights outside the covariance universe.

Returns:

Series named 'Benchmark beta' on the covariance date grid.

Raises:

ValueError – If weights violate the alignment policy or benchmark variance is nonpositive.

Return type:

Series

compute_benchmark_beta_loadings_at_date(benchmark_weights, date, strict=True)[source]

Compute per-asset loadings to a weighted benchmark.

The loading vector is c = Sigma w_b / (w_b' Sigma w_b), so the beta of any aligned portfolio is the linear form c' w_p. The factor block is not required.

Parameters:
  • benchmark_weights (Series) – Benchmark weights indexed by asset.

  • date (Timestamp) – Exact covariance-grid date.

  • strict (bool) – If True, reject material weights outside the covariance universe.

Returns:

Benchmark-beta loading Series indexed by covariance asset.

Raises:
  • KeyError – If date is not an exact covariance-grid date.

  • ValueError – If weights violate the alignment policy or benchmark variance is nonpositive.

Return type:

Series

compute_tre_decomposition_at_date(benchmark_weights, portfolio_weights, date, strict=True)[source]

Decompose tracking error into factor and residual components.

For active weights d = w_p - w_b, asset-by-factor loadings B, factor covariance Sigma_x, and diagonal residual variance D, the components are TE_f^2 = (B' d)' Sigma_x (B' d) and TE_r^2 = d' D d. The returned tracking error is sqrt(TE_f^2 + TE_r^2). It equals covariance tracking error only when the supplied covariance satisfies Sigma = B Sigma_x B' + D; inconsistent views are not reconciled silently.

Parameters:
  • benchmark_weights (Series) – Benchmark weights indexed by asset.

  • portfolio_weights (Series) – Portfolio weights indexed by asset.

  • date (Timestamp) – Exact covariance-grid date.

  • strict (bool) – If True, reject material weights outside the covariance universe.

Returns:

Series with tracking_error, factor_te, and residual_te.

Raises:
  • KeyError – If date is not an exact covariance-grid date.

  • ValueError – If the factor block is missing or weights violate the alignment policy.

Return type:

Series

compute_tre_decomposition_history(benchmark_weights, portfolio_weights, strict=True)[source]

Compute factor/residual tracking-error decomposition through time.

Dated weights are selected as-of each covariance date using forward fill. Each row uses the factor-block formulas documented by compute_tre_decomposition_at_date(); no annualisation is applied.

Parameters:
  • benchmark_weights (Series | DataFrame) – Static Series or dated DataFrame of benchmark weights.

  • portfolio_weights (Series | DataFrame) – Static Series or dated DataFrame of portfolio weights.

  • strict (bool) – If True, reject material weights outside the covariance universe.

Returns:

DataFrame with tracking_error, factor_te, and residual_te columns.

Raises:

ValueError – If the factor block is missing or weights violate the alignment policy.

Return type:

DataFrame

compute_marginal_tre_at_date(benchmark_weights, portfolio_weights, date, group_data=None, strict=True)[source]

Compute canonical Euler marginal tracking-error contributions.

With active weights d = w_p - w_b and TE = sqrt(d' Sigma d), each asset contribution is mcte_i = d_i (Sigma d)_i / TE and the contributions sum to TE. At TE equal to zero, all contributions are defined as zero.

When a complete factor block is present, systematic and residual columns use B Sigma_x B' d and D d respectively. They sum to total per asset when Sigma = B Sigma_x B' + D; inconsistent supplied views are shown without silent reconciliation. Group rows aggregate asset contributions additively and therefore differ from the standalone, non-additive group risks returned by compute_tre_*.

Parameters:
  • benchmark_weights (Series) – Benchmark weights indexed by asset.

  • portfolio_weights (Series) – Portfolio weights indexed by asset.

  • date (Timestamp) – Exact covariance-grid date.

  • group_data (Series | None) – Optional group label per asset. Missing labels become 'Unassigned'.

  • strict (bool) – If True, reject material weights outside the covariance universe.

Returns:

Per-asset DataFrame, or a DataFrame with Total and group rows. Column mcte is always present; a complete factor block adds mcte_systematic and mcte_residual.

Raises:
  • KeyError – If date is not an exact covariance-grid date.

  • ValueError – If weights or model data violate the alignment policy.

Return type:

DataFrame