Skip to content

Risk

stochPathSim.risk

Risk analytics: path statistics, exposure, VaR and backtesting.

PortfolioRisk dataclass

Normal VaR/ES and risk contributions in portfolio P&L currency units.

Marginal arrays are derivatives with respect to position weights; component arrays multiply marginal derivatives by those weights. Component contributions sum to total risk, including expected P&L. Negative VaR/contributions are possible for profitable or hedged books.

ExposureProfile dataclass

Exposure metrics of a simulated portfolio.

from_mtm classmethod

from_mtm(mtm, times, pfe_level=0.95, horizon=1.0)

Compute all metrics from simulated values.

to_frame

to_frame()

Profiles as a pandas.DataFrame indexed by time.

normal_portfolio_risk

normal_portfolio_risk(weights, covariance, mean=None, *, level=0.99, horizon=1.0)

Delta-normal portfolio VaR/ES with additive Euler risk attribution.

Positions weights multiply one-period asset P&Ls. mean and covariance describe annualised (or other unit-time) P&L mean and covariance, respectively. Both scale linearly with horizon. Correlated assets and negative portfolio weights are supported.

Portfolio loss is the negative of P&L. VaR = z*sd - expected_pnl and ES = phi(z)/(1-level)*sd - expected_pnl. Components add to total VaR/ES by positive homogeneity in positions.

A zero-volatility portfolio has zero covariance risk and only deterministic mean-based contributions. Parameter uncertainty and nonnormal loss tails are not included.

anderson_darling_uniform

anderson_darling_uniform(pit)

Anderson-Darling test of uniformity for PIT values.

Returns the statistic and an asymptotic p-value (Marsaglia & Marsaglia 2004).

christoffersen_independence

christoffersen_independence(exceed_indicator)

Christoffersen test that exceedances are independent over time.

Returns the likelihood-ratio statistic (chi-square, 1 dof) and p-value.

cramer_von_mises_uniform

cramer_von_mises_uniform(pit)

Cramer-von Mises test of uniformity for PIT values (statistic, p-value).

kupiec_pof

kupiec_pof(n_obs, n_exceed, level=0.99)

Kupiec proportion-of-failures test.

Parameters:

Name Type Description Default
n_obs int

Number of observations.

required
n_exceed int

Number of exceedances.

required
level float

VaR confidence level; the expected exceedance rate is 1 - level.

0.99

Returns:

Type Description
(float, float)

Likelihood-ratio statistic (chi-square, 1 dof) and p-value.

pit_values

pit_values(simulated_distributions, realised)

Probability integral transform of realised values.

Parameters:

Name Type Description Default
simulated_distributions array_like

Simulated values, shape (n_dates, n_sims): one forecast distribution per date.

required
realised array_like

Realised values, shape (n_dates,).

required

Returns:

Type Description
ndarray

F_i(x_i) for each date, the share of simulations at or below the realisation. Uniform on [0, 1] when the model is correct.

collateralised_exposure

collateralised_exposure(mtm, threshold=0.0, mta=0.0, margin_period_steps=0)

Mark-to-market net of variation margin with a margin period of risk.

Collateral posted at time t is based on the value margin_period_steps steps earlier: C(t) = max(V(t - MPoR) - threshold, 0) (and symmetrically for negative values), set to zero when below the minimum transfer amount. No collateral is held before the first margin call.

Returns the collateralised value V(t) - C(t).

cva_from_exposure

cva_from_exposure(ee, times, hazard_rate=None, survival=None, recovery=0.4, discount_rate=0.0, discount_curve=None)

Unilateral CVA (1 - R) * sum_i D(t_i) EE(t_i) [S(t_{i-1}) - S(t_i)].

Parameters:

Name Type Description Default
ee array_like

Expected exposure on times.

required
hazard_rate float

Flat hazard rate; survival is exp(-h t).

None
survival callable or array_like

Survival probabilities on times (or a function of time) instead of a hazard rate.

None
recovery float

Recovery rate.

0.4
discount_rate float

Flat continuously compounded rate, or an object with discount(t) (e.g. :class:stochPathSim.curves.ZeroCurve).

0.0
discount_curve float

Flat continuously compounded rate, or an object with discount(t) (e.g. :class:stochPathSim.curves.ZeroCurve).

0.0

effective_ee

effective_ee(ee)

Effective EE: the running maximum of EE (Basel non-decreasing EE).

effective_epe

effective_epe(ee, times, horizon=1.0)

Effective EPE: time average of effective EE over the first horizon years.

expected_exposure

expected_exposure(mtm)

EE(t) = E[max(V(t), 0)].

expected_negative_exposure

expected_negative_exposure(mtm)

ENE(t) = E[min(V(t), 0)] (non-positive).

expected_positive_exposure

expected_positive_exposure(ee, times, horizon=None)

EPE: time average of EE over [0, horizon] (whole grid by default).

potential_future_exposure

potential_future_exposure(mtm, level=0.95)

PFE(t): the level quantile of max(V(t), 0).

exceedance_counts

exceedance_counts(simulated, realised, lower=0.01, upper=0.99, name=None)

Count how often realised values fall outside the simulated quantile band.

For each time step the band [q_lower, q_upper] of the simulated distribution is compared with the realised value(s). This is the usual band backtest for risk-factor models. (The legacy calculate_statistics compared the initial value with the band, which says nothing about model quality; this function compares realisations.)

Parameters:

Name Type Description Default
simulated SimulationResult or ndarray

Simulated paths (n_paths, n_times).

required
realised array_like

One realised path (n_times,) or several (n_realisations, n_times).

required
lower float

Quantile levels of the band.

0.01
upper float

Quantile levels of the band.

0.01

Returns:

Type Description
dict

upper and lower exceedance counts, n_obs, the expected counts under a correct model, and boolean upper_mask/lower_mask.

path_statistics

path_statistics(result_or_array, reference=None, quantiles=(0.01, 0.1, 0.9, 0.99), name=None)

Mean, standard deviation, P-level and quantiles at each time.

Parameters:

Name Type Description Default
result_or_array SimulationResult or ndarray

Simulated paths, shape (n_paths, n_times) for an array.

required
reference float or array_like

Level against which p_level is measured: the share of paths above it at each time. Defaults to the initial value of the paths.

None
quantiles sequence of float

Quantile levels in [0, 1]; columns are named q01, q99 etc.

(0.01, 0.1, 0.9, 0.99)
name str

State variable to use when a SimulationResult holds several.

None

Returns:

Type Description
DataFrame

Indexed by time.

monte_carlo_var

monte_carlo_var(terminal_values, initial_value, level=0.99)

VaR and ES of terminal_values - initial_value from simulated values.

var_es

var_es(pnl, level=0.99, method='historical')

VaR and expected shortfall of a P&L sample.

Parameters:

Name Type Description Default
pnl array_like

Profit-and-loss observations or simulations.

required
level float

Confidence level, e.g. 0.99.

0.99
method ('historical', 'parametric', 'cornish_fisher')

Empirical quantile, normal approximation, or normal with a Cornish-Fisher skew/kurtosis adjustment (ES from the empirical tail beyond that VaR for Cornish-Fisher).

"historical"

Returns:

Type Description
(float, float)

(VaR, ES), losses positive.

attribution

Euler allocation of delta-normal portfolio VaR and expected shortfall.

PortfolioRisk dataclass

Normal VaR/ES and risk contributions in portfolio P&L currency units.

Marginal arrays are derivatives with respect to position weights; component arrays multiply marginal derivatives by those weights. Component contributions sum to total risk, including expected P&L. Negative VaR/contributions are possible for profitable or hedged books.

normal_portfolio_risk

normal_portfolio_risk(weights, covariance, mean=None, *, level=0.99, horizon=1.0)

Delta-normal portfolio VaR/ES with additive Euler risk attribution.

Positions weights multiply one-period asset P&Ls. mean and covariance describe annualised (or other unit-time) P&L mean and covariance, respectively. Both scale linearly with horizon. Correlated assets and negative portfolio weights are supported.

Portfolio loss is the negative of P&L. VaR = z*sd - expected_pnl and ES = phi(z)/(1-level)*sd - expected_pnl. Components add to total VaR/ES by positive homogeneity in positions.

A zero-volatility portfolio has zero covariance risk and only deterministic mean-based contributions. Parameter uncertainty and nonnormal loss tails are not included.

backtest

Backtests for VaR and risk-factor simulation models.

kupiec_pof

kupiec_pof(n_obs, n_exceed, level=0.99)

Kupiec proportion-of-failures test.

Parameters:

Name Type Description Default
n_obs int

Number of observations.

required
n_exceed int

Number of exceedances.

required
level float

VaR confidence level; the expected exceedance rate is 1 - level.

0.99

Returns:

Type Description
(float, float)

Likelihood-ratio statistic (chi-square, 1 dof) and p-value.

christoffersen_independence

christoffersen_independence(exceed_indicator)

Christoffersen test that exceedances are independent over time.

Returns the likelihood-ratio statistic (chi-square, 1 dof) and p-value.

pit_values

pit_values(simulated_distributions, realised)

Probability integral transform of realised values.

Parameters:

Name Type Description Default
simulated_distributions array_like

Simulated values, shape (n_dates, n_sims): one forecast distribution per date.

required
realised array_like

Realised values, shape (n_dates,).

required

Returns:

Type Description
ndarray

F_i(x_i) for each date, the share of simulations at or below the realisation. Uniform on [0, 1] when the model is correct.

anderson_darling_uniform

anderson_darling_uniform(pit)

Anderson-Darling test of uniformity for PIT values.

Returns the statistic and an asymptotic p-value (Marsaglia & Marsaglia 2004).

cramer_von_mises_uniform

cramer_von_mises_uniform(pit)

Cramer-von Mises test of uniformity for PIT values (statistic, p-value).

exposure

Counterparty exposure profiles from simulated mark-to-market values.

All functions take mtm of shape (n_paths, n_times): the portfolio value to us on each path and date.

ExposureProfile dataclass

Exposure metrics of a simulated portfolio.

from_mtm classmethod
from_mtm(mtm, times, pfe_level=0.95, horizon=1.0)

Compute all metrics from simulated values.

to_frame
to_frame()

Profiles as a pandas.DataFrame indexed by time.

expected_exposure

expected_exposure(mtm)

EE(t) = E[max(V(t), 0)].

expected_negative_exposure

expected_negative_exposure(mtm)

ENE(t) = E[min(V(t), 0)] (non-positive).

potential_future_exposure

potential_future_exposure(mtm, level=0.95)

PFE(t): the level quantile of max(V(t), 0).

expected_positive_exposure

expected_positive_exposure(ee, times, horizon=None)

EPE: time average of EE over [0, horizon] (whole grid by default).

effective_ee

effective_ee(ee)

Effective EE: the running maximum of EE (Basel non-decreasing EE).

effective_epe

effective_epe(ee, times, horizon=1.0)

Effective EPE: time average of effective EE over the first horizon years.

collateralised_exposure

collateralised_exposure(mtm, threshold=0.0, mta=0.0, margin_period_steps=0)

Mark-to-market net of variation margin with a margin period of risk.

Collateral posted at time t is based on the value margin_period_steps steps earlier: C(t) = max(V(t - MPoR) - threshold, 0) (and symmetrically for negative values), set to zero when below the minimum transfer amount. No collateral is held before the first margin call.

Returns the collateralised value V(t) - C(t).

cva_from_exposure

cva_from_exposure(ee, times, hazard_rate=None, survival=None, recovery=0.4, discount_rate=0.0, discount_curve=None)

Unilateral CVA (1 - R) * sum_i D(t_i) EE(t_i) [S(t_{i-1}) - S(t_i)].

Parameters:

Name Type Description Default
ee array_like

Expected exposure on times.

required
hazard_rate float

Flat hazard rate; survival is exp(-h t).

None
survival callable or array_like

Survival probabilities on times (or a function of time) instead of a hazard rate.

None
recovery float

Recovery rate.

0.4
discount_rate float

Flat continuously compounded rate, or an object with discount(t) (e.g. :class:stochPathSim.curves.ZeroCurve).

0.0
discount_curve float

Flat continuously compounded rate, or an object with discount(t) (e.g. :class:stochPathSim.curves.ZeroCurve).

0.0

statistics

Cross-sectional statistics of simulated paths and band backtests.

These are the tools behind risk-factor simulation backtesting: for each horizon, compare the simulated distribution with what was realised.

path_statistics

path_statistics(result_or_array, reference=None, quantiles=(0.01, 0.1, 0.9, 0.99), name=None)

Mean, standard deviation, P-level and quantiles at each time.

Parameters:

Name Type Description Default
result_or_array SimulationResult or ndarray

Simulated paths, shape (n_paths, n_times) for an array.

required
reference float or array_like

Level against which p_level is measured: the share of paths above it at each time. Defaults to the initial value of the paths.

None
quantiles sequence of float

Quantile levels in [0, 1]; columns are named q01, q99 etc.

(0.01, 0.1, 0.9, 0.99)
name str

State variable to use when a SimulationResult holds several.

None

Returns:

Type Description
DataFrame

Indexed by time.

exceedance_counts

exceedance_counts(simulated, realised, lower=0.01, upper=0.99, name=None)

Count how often realised values fall outside the simulated quantile band.

For each time step the band [q_lower, q_upper] of the simulated distribution is compared with the realised value(s). This is the usual band backtest for risk-factor models. (The legacy calculate_statistics compared the initial value with the band, which says nothing about model quality; this function compares realisations.)

Parameters:

Name Type Description Default
simulated SimulationResult or ndarray

Simulated paths (n_paths, n_times).

required
realised array_like

One realised path (n_times,) or several (n_realisations, n_times).

required
lower float

Quantile levels of the band.

0.01
upper float

Quantile levels of the band.

0.01

Returns:

Type Description
dict

upper and lower exceedance counts, n_obs, the expected counts under a correct model, and boolean upper_mask/lower_mask.

var

Value at risk and expected shortfall.

Losses are reported as positive numbers: for P&L x, the loss is -x.

var_es

var_es(pnl, level=0.99, method='historical')

VaR and expected shortfall of a P&L sample.

Parameters:

Name Type Description Default
pnl array_like

Profit-and-loss observations or simulations.

required
level float

Confidence level, e.g. 0.99.

0.99
method ('historical', 'parametric', 'cornish_fisher')

Empirical quantile, normal approximation, or normal with a Cornish-Fisher skew/kurtosis adjustment (ES from the empirical tail beyond that VaR for Cornish-Fisher).

"historical"

Returns:

Type Description
(float, float)

(VaR, ES), losses positive.

monte_carlo_var

monte_carlo_var(terminal_values, initial_value, level=0.99)

VaR and ES of terminal_values - initial_value from simulated values.