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 |
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 |
required |
realised
|
array_like
|
Realised values, shape |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
|
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 |
required |
hazard_rate
|
float
|
Flat hazard rate; survival is |
None
|
survival
|
callable or array_like
|
Survival probabilities on |
None
|
recovery
|
float
|
Recovery rate. |
0.4
|
discount_rate
|
float
|
Flat continuously compounded rate, or an object with |
0.0
|
discount_curve
|
float
|
Flat continuously compounded rate, or an object with |
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 |
required |
realised
|
array_like
|
One realised path |
required |
lower
|
float
|
Quantile levels of the band. |
0.01
|
upper
|
float
|
Quantile levels of the band. |
0.01
|
Returns:
| Type | Description |
|---|---|
dict
|
|
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 |
required |
reference
|
float or array_like
|
Level against which |
None
|
quantiles
|
sequence of float
|
Quantile levels in [0, 1]; columns are named |
(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)
|
|
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 |
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 |
required |
realised
|
array_like
|
Realised values, shape |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
|
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 |
required |
hazard_rate
|
float
|
Flat hazard rate; survival is |
None
|
survival
|
callable or array_like
|
Survival probabilities on |
None
|
recovery
|
float
|
Recovery rate. |
0.4
|
discount_rate
|
float
|
Flat continuously compounded rate, or an object with |
0.0
|
discount_curve
|
float
|
Flat continuously compounded rate, or an object with |
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 |
required |
reference
|
float or array_like
|
Level against which |
None
|
quantiles
|
sequence of float
|
Quantile levels in [0, 1]; columns are named |
(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 |
required |
realised
|
array_like
|
One realised path |
required |
lower
|
float
|
Quantile levels of the band. |
0.01
|
upper
|
float
|
Quantile levels of the band. |
0.01
|
Returns:
| Type | Description |
|---|---|
dict
|
|
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)
|
|
monte_carlo_var
monte_carlo_var(terminal_values, initial_value, level=0.99)
VaR and ES of terminal_values - initial_value from simulated values.