Documentation

Data

The P&L parameters from Vorobets [2022] and simulation from Vorobets [2021] follow with this package. The simulation assumes that returns follow a log-normal distribution, while the parameters are given by the Danish common return expectations for the 2nd half of 2021.

The parameters and P&L simulation are used in the examples and allow you to immediately start exploring the functionality of this package. You can also use it to test your understanding of the theory by replicating results, for example, the sequential Entropy Pooling results from Vorobets [2021].

In addition to the above, simulated time series of an equity index, an associated implied volatility surface, a risk-free zero-coupon curve, and a credit spread curve is included. You can use this time series data to, for example, validate your risk modeling approach. See this introduction example and this modeling example for an example of how to use the data with a very simple risk model as well as Entropy Pooling views on risk factors.

load_parameters()

Function for loading the P&L parameters from https://ssrn.com/abstract=4034316.

Return type:

Tuple[list, ndarray, ndarray]

Returns:

Instrument names, means vector, and covariance matrix.

load_pnl()

Function for loading the P&L simulation from https://ssrn.com/abstract=3936392, https://ssrn.com/abstract=4217884, and https://ssrn.com/abstract=4444291.

Return type:

DataFrame

Returns:

P&L simulation.

load_risk_factors()

Function for loading the risk factor simulation from 7_RiskFactorViews.ipynb that is used in https://ssrn.com/abstract=4444291.

Return type:

DataFrame

Returns:

Risk factor simulation.

load_time_series()

Function for loading an SDE based time series simulation.

Return type:

DataFrame

Returns:

Time series simulation.

plot_vol_surface(index, vol_surface, figsize=None, zoom=None)

Function for plotting the implied vol surface from the time series simulation.

Parameters:
  • index (int) – Index for the implied vol surface scenario.

  • vol_surface (ndarray) – Matrix with shape (T, 35) or (S, 35) containing the implied vols.

  • figsize (Tuple[float, float]) – Figure size. Default (10, 7).

Return type:

Tuple[Figure, Axes]

Returns:

3d implied vol surface plot.

Simulation

This package includes a Fully Flexible Resampling (FFR) method as well as a very simple exponential decay simulation model. The FFR functionality, originally introduced in the Portfolio Construction and Risk Management book, is only implemented with one continous state variable.

For detailed proofs of all the nice properties of the Fully Flexible Resampling method, see Kristensen and Vorobets [2025].

The exponentially decaying probabilities can be used directly with historical scenarios, for example, as a prior probability for Sequential Entropy Pooling (SeqEP) views/stress tests, the FFR method, or for a normal distribution calibration which new samples can be generated from.

class FullyFlexibleResampling(stationary_transformations)

Fully Flexible Resampling (FFR) class for simulaton with one state variable.

The Fully Flexible Resampling (FFR) method was first introduced in Chapter 3 of the Portfolio Construction and Risk Management book.

It is an instance of the more general Time and State-Dependent Resampling class documented: https://ssrn.com/abstract=5117589.

Parameters:

stationary_transformations (Union[DataFrame, ndarray]) – Data containing the stationary transformations with shape (T_tilde, N_tilde).

compute_probabilities(state_variable, conditioning_values, half_life=None)

Method for computing the Fully Flexible Resampling probabilities.

Parameters:
  • state_variable (ndarray) – Time series for the state variable with shape (T_tilde, 1).

  • conditioning_values (list) – Conditioning values used to define the crisp probability bands.

  • half_life (int) – Half life parameter for exponentially decaying prior probabilities. Default: uniform probabilities.

Return type:

Tuple[ndarray, ndarray]

Returns:

Matrix with Fully Flexible Resampling probabilities and historical states vector.

simulate(S, H, probabilities, states_vector, initial_state=None)

Simulation method for Fully Flexible Resampling.

Parameters:
  • S (int) – Number of simulated future paths.

  • H (int) – Simulation horizon.

  • probabilities (ndarray) – The resampling probabilities for each state.

  • states_vector (ndarray) – Vector containing the historical states.

  • initial_state (int) – Optional initial state. Default: the latest state.

Return type:

ndarray

Returns:

Resampled stationary transformations simulations with shape (S, I, H).

exp_decay_probs(R, half_life)

Function for computing exponential decay probabilities.

Parameters:
  • R (Union[DataFrame, ndarray]) – P&L / risk factor simulation with shape (T, I).

  • half_life (int) – Exponential decay half life.

Return type:

ndarray

Returns:

Exponentially decaying probabilities vector with shape (T, 1).

normal_exp_decay_calib(R, half_life)

Function for computing exponential decay mean vector and covariance matrix.

Parameters:
  • R (Union[DataFrame, ndarray]) – P&L / risk factor simulation with shape (T, I).

  • half_life (int) – Exponential decay half life.

Return type:

Union[Tuple[ndarray, ndarray], Tuple[DataFrame, DataFrame]]

Returns:

Mean vector with shape (I, 1) and covariance matrix with shape (I, I).

Entropy Pooling

The Entropy Pooling approach solves the problem

q=argmin{xT(lnxlnp)},

subject to the constraints

Ax=b,Gxh.

The approach was first introduced by Meucci [2008], while the code is implemented using notation from Vorobets [2021]. For an introduction to Entropy Pooling, see this video or this Substack post.

entropy_pooling(p, A, b, G=None, h=None, method=None)

Function for computing Entropy Pooling posterior probabilities.

Parameters:
  • p (ndarray) – Prior probability vector with shape (S, 1).

  • A (ndarray) – Equality constraint matrix with shape (M, S).

  • b (ndarray) – Equality constraint vector with shape (M, 1).

  • G (ndarray) – Inequality constraint matrix with shape (N, S).

  • h (ndarray) – Inequality constraint vector with shape (N, 1).

  • method (str) – Optimization method: {‘TNC’, ‘L-BFGS-B’}. Default ‘TNC’.

Return type:

ndarray

Returns:

Posterior probability vector with shape (S, 1).

Functions

The functions below are useful when working with Entropy Pooling, for example, they can be used to calculate posterior moments and correlation matrix to verify that views have been implemented correctly. The covariance matrix function is useful for mean-variance optimization with Entropy Pooling views.

correlation_matrix(R, p=None)

Function for computing the correlation matrix.

Parameters:
  • R (Union[DataFrame, ndarray]) – P&L / risk factor simulation with shape (S, I).

  • p (ndarray) – probability vector with shape (S, 1). Default: np.ones((S, 1)) / S.

Return type:

DataFrame

Returns:

Correlation matrix with shape (I, I).

covariance_matrix(R, p=None)

Function for computing the covariance matrix.

Parameters:
  • R (Union[DataFrame, ndarray]) – P&L / risk factor simulation with shape (S, I).

  • p (ndarray) – probability vector with shape (S, 1). Default: np.ones((S, 1)) / S.

Return type:

DataFrame

Returns:

Covariance matrix with shape (I, I).

exposure_stacking(L, sample_portfolios)

Computes the L-fold Exposure Stacking portfolio from https://ssrn.com/abstract=4709317.

Parameters:
  • L – Number of partition sets.

  • sample_portfolios – Sample portfolio exposures with shape (I, B).

Returns:

Exposure Stacking portfolio.

portfolio_cvar(e, R, p=None, alpha=None, demean=None)

Function for computing portfolio CVaR.

Parameters:
  • e (ndarray) – Vector / matrix of portfolio exposures with shape (I, num_portfolios).

  • R (Union[DataFrame, ndarray]) – P&L / risk factor simulation with shape (S, I).

  • p (ndarray) – probability vector with shape (S, 1). Default np.ones((S, 1)) / S.

  • alpha (float) – alpha level for alpha-CVaR. Default: 0.95.

  • demean (bool) – Boolean indicating whether to use demeaned P&L. Default: True.

Return type:

Union[float, ndarray]

Returns:

Portfolio alpha-CVaR.

portfolio_var(e, R, p=None, alpha=None, demean=None)

Function for computing portfolio VaR.

Parameters:
  • e (ndarray) – Vector / matrix of portfolio exposures with shape (I, num_portfolios).

  • R (Union[DataFrame, ndarray]) – P&L / risk factor simulation with shape (S, I).

  • p (ndarray) – probability vector with shape (S, 1). Default np.ones((S, 1)) / S.

  • alpha (float) – alpha level for alpha-VaR. Default: 0.95.

  • demean (bool) – Boolean indicating whether to use demeaned P&L. Default: True.

Return type:

Union[float, ndarray]

Returns:

Portfolio alpha-VaR.

portfolio_vol(e, R, p=None)

Function for computing portfolio volatility.

Parameters:
  • e (ndarray) – Vector / matrix of portfolio exposures with shape (I, num_portfolios).

  • R (Union[DataFrame, ndarray]) – P&L / risk factor simulation with shape (S, I).

  • p (ndarray) – probability vector with shape (S, 1). Default: np.ones((S, 1)) / S.

Return type:

Union[float, ndarray]

Returns:

Portfolio volatility / volatilities.

simulation_moments(R, p=None)

Function for computing simulation moments (mean, volatility, skewness, and kurtosis).

Parameters:
  • R (Union[DataFrame, ndarray]) – P&L / risk factor simulation with shape (S, I).

  • p (ndarray) – probability vector with shape (S, 1). Default: np.ones((S, 1)) / S.

Return type:

DataFrame

Returns:

DataFrame with shape (I, 4) containing simulation moments.

Option Pricing

The option pricing functionality consists of functions that use Black’s model to price European call and put options.

call_option(F, K, sigma, r, T)

Function for computing European call option price using Black’s formula.

Parameters:
  • F (float) – Forward price for maturity T.

  • K (float) – Strike value.

  • sigma (float) – Implied volatility for maturity T and strike K.

  • r (float) – Interest rate for maturity T.

  • T (float) – Time to maturity.

Return type:

float

Returns:

European call option price.

forward(S, r, q, T)

Function for computing the continuously compounded forward price.

Parameters:
  • S (float) – Spot price.

  • r (float) – Risk-free rate for maturity T.

  • q (float) – Dividend yield.

  • T (float) – Time to maturity.

Return type:

float

Returns:

Forward price for maturity T.

put_option(F, K, sigma, r, T)

Function for computing European put option price using Black’s formula.

Parameters:
  • F (float) – Forward price for maturity T.

  • K (float) – Strike value.

  • sigma (float) – Implied volatility for maturity T and strike K.

  • r (float) – Interest rate for maturity T.

  • T (float) – Time to maturity.

Return type:

float

Returns:

European put option price.

Portfolio Optimization

The MeanCVaR and MeanVariance objects solve the problem

mineR(e),

with R(e) being the CVaR or variance for exposures eRI, subject to the constraints

μeμtarget,ve=1,Geh,Ae=b.

Here, vRI is the vector of relative market values introduced by Vorobets [2022]. See this example for how to use this parameter.

A method for solving the CVaR problem was first introduced by Rockafellar and Uryasev [2000], while the implemented algorithm is based on Künzi-Bay and Mayer [2006]. The notation in relation to the P&L simulations R follows Vorobets [2021]. For the variance risk measure, a standard quadratic programming solver is used.

class MeanCVaR(R, G=None, h=None, A=None, b=None, v=None, p=None, alpha=None, **kwargs)

Class for efficient mean-CVaR optimization using Benders decomposition.

Parameters:
  • R (ndarray) – Matrix with P&L simulations and shape (S, I).

  • G (ndarray) – Inequality constraints matrix with shape (N, I).

  • h (ndarray) – Inequality constraints vector with shape (N,).

  • A (ndarray) – Equality constraints matrix with shape (M, I).

  • b (ndarray) – Equality constraints vector with shape (M,).

  • v (ndarray) – Vector of relative market values and shape (I,). Default: np.ones(I).

  • p (ndarray) – Vector containing scenario probabilities with shape (S, 1). Default: np.ones((S, 1)) / S.

  • alpha (float) – Alpha value for alpha-VaR and alpha-CVaR. Default: 0.95.

  • kwargs (dict) – options dictionary with Benders algorithm parameters.

Raises:

ValueError – If constraints or options parameters are infeasible.

efficient_frontier(num_portfolios=None)

Method for computing the efficient frontier.

Parameters:

num_portfolios (int) – Number of portfolios used to span the efficient frontier. Default: 9.

Return type:

ndarray

Returns:

Efficient frontier with shape (I, num_portfolios).

Raises:

ValueError – If expected return is unbounded.

efficient_portfolio(return_target=None)

Method for computing a mean-CVaR efficient portfolio with return a target.

Parameters:

return_target (float) – Return target for the efficient portfolio. The minimum CVaR portfolio is computed by default.

Return type:

ndarray

Returns:

Efficient portfolio exposures with shape (I, 1).

class MeanVariance(mean, covariance_matrix, G=None, h=None, A=None, b=None, v=None)

Class for efficient mean-variance optimization.

Parameters:
  • mean (ndarray) – Mean vector with shape (I,).

  • covariance_matrix (ndarray) – Covariance matrix with shape (I, I).

  • G (ndarray) – Inequality constraints matrix with shape (N, I).

  • h (ndarray) – Inequality constraints vector with shape (N,).

  • A (ndarray) – Equality constraints matrix with shape (M, I).

  • b (ndarray) – Equality constraints vector with shape (M,).

  • v (ndarray) – Vector of relative market values and shape (I,). Default: np.ones(I).

Raises:

ValueError – If constraints are infeasible.

efficient_frontier(num_portfolios=None)

Method for computing the efficient frontier.

Parameters:

num_portfolios (int) – Number of portfolios used to span the efficient frontier. Default: 9.

Return type:

ndarray

Returns:

Efficient frontier with shape (I, num_portfolios).

Raises:

ValueError – If expected return is unbounded.

efficient_portfolio(return_target=None)

Method for computing a mean-variance efficient portfolio with a return target.

Parameters:

return_target (float) – Return target for the efficient portfolio. The minimum variance portfolio is computed by default.

Return type:

ndarray

Returns:

Efficient portfolio exposures with shape (I, 1).

Algorithm Parameters

For the variance risk measure, CVXOPT’s default values are used. These can be adjusted directly following the instructions given in the link.

For the CVaR risk measure, control parameters can be set globally using the cvar_options dictionary, e.g.,

import fortitudo.tech as ft
ft.cvar_options['demean'] = False
ft.cvar_options['R_scalar'] = 10000

or for a particular instance of the MeanCVaR class:

opt = ft.MeanCVaR(R, G, h, A, b, options={'demean': False, 'R_scalar': 10000})

The following parameters can be adjusted:

'demean'

Whether to use demeaned P&L when calculating CVaR. Default: True.

'R_scalar'

Scaling factor for the P&L simulation. Default: 1000.

'maxiter'

Maximum number of iterations for the decomposition algorithm, i.e., maximum number of relaxed master problems the algorithm is allowed to solve. Default: 500.

'reltol'

Relative tolerance for the difference between the currently best upper and lower bounds. Default: 1e-8.

'abstol'

Absolute tolerance for the difference between the currently best upper and lower bounds if the lower bound is less than 1e-10. Default: 1e-8.

The algorithm stops when one of the 'maxiter', 'reltol', or 'abstol' conditions are satisfied. The parameters have been tested with “percentage return” P&L and work well. In most cases, the algorithm stops due to relative convergence in less than 100 iterations. If you use P&L simulations that are scaled differently, you might need to adjust them.