pyvallocation.utils.projection module
- pyvallocation.utils.projection.compose_repricers(instruments, invariant_columns)[source]
Build a repricing function mapping K invariant columns to N instrument P&Ls.
For mixed portfolios where each instrument may depend on one or more risk drivers (Prayer P4). Three specification formats are supported:
callable – 1-to-1: uses the invariant column with the same name as the instrument.
(“driver”, callable) or ([“driver”], callable) – single named driver whose name differs from the instrument.
([“d1”, “d2”], callable) – multi-driver: the callable receives an
(n_sim, n_drivers)array.
- Parameters:
instruments – Dict mapping instrument name to repricing spec.
invariant_columns – Ordered column names of the invariant scenario matrix (length K).
- Returns:
Tuple[Callable, List[str]] –
(repricing_fn, instrument_names)where repricing_fn maps(n_sim, K) -> (n_sim, N)and instrument_names is the ordered list of output column labels.- Raises:
KeyError – If a required driver column is not in invariant_columns.
TypeError – If a spec is neither a callable nor a
(drivers, callable)tuple.
Examples
>>> fn, names = compose_repricers( ... {"Stock": reprice_exp, ... "Bond": (["yield_10y"], lambda dy: reprice_taylor(dy, delta=-7, gamma=50)), ... "Call": (["stock_logret", "iv_chg"], my_option_fn)}, ... invariant_columns=["stock_logret", "yield_10y", "iv_chg"], ... ) >>> names ['Stock', 'Bond', 'Call']
- pyvallocation.utils.projection.convert_scenarios_compound_to_simple(scenarios)[source]
Convert compound returns to simple returns.
- Parameters:
scenarios – Log/compound return scenarios.
- Returns:
np.ndarray – Simple return scenarios.
- Parameters:
scenarios (numpy.ndarray)
- Return type:
numpy.ndarray
- pyvallocation.utils.projection.convert_scenarios_simple_to_compound(scenarios)[source]
Convert simple returns to compound (log) returns.
- Parameters:
scenarios – Simple return scenarios. All values must be strictly greater than -1 (i.e.,
1 + r > 0).- Returns:
np.ndarray – Log/compound return scenarios.
- Raises:
ValueError – If any scenario has a return <= -1.
- Parameters:
scenarios (numpy.ndarray)
- Return type:
numpy.ndarray
- pyvallocation.utils.projection.log2simple(mu_g, cov_g)[source]
mu,Sigma of log-returns -> mu,Sigma of simple returns (vectorised, pandas-aware).
- Parameters:
mu_g – Mean of log-returns.
cov_g – Covariance of log-returns.
- Returns:
Tuple[ArrayLike, ArrayLike] – Mean and covariance in simple-return units.
- pyvallocation.utils.projection.make_repricing_fn(pricing_fn, current_drivers)[source]
Build a repricing callable from an arbitrary pricing function.
For full repricing (Prayer P4), the user supplies a function
pricing_fn(Y)that maps risk-driver levels to instrument prices. The returned callable computes:P&L = pricing_fn(Y_T + Δy) - pricing_fn(Y_T)- Parameters:
pricing_fn – Callable
f(Y) -> prices, whereYhas the same columns as the risk-driver scenarios. Must be vectorised over the first (scenario) axis.current_drivers – Current risk-driver levels
Y_T(1-D array of lengthn_drivers).
- Returns:
Callable – Repricing function suitable for the
repriceparameter ofproject_scenarios().- Parameters:
current_drivers (numpy.ndarray)
Examples
>>> # Bond: price = face * exp(-yield * maturity) >>> import numpy as np >>> face, maturity = 100, 5 >>> pricing_fn = lambda Y: face * np.exp(-Y * maturity) >>> current_yield = np.array([0.03]) >>> repricer = make_repricing_fn(pricing_fn, current_yield) >>> # repricer(delta_y) returns bond P&L scenarios
- pyvallocation.utils.projection.project_mean_covariance(mu, cov, annualization_factor)[source]
Scale mean and covariance by
annualization_factor.- Parameters:
mu – Mean vector.
cov – Covariance matrix.
annualization_factor – Scaling factor (e.g., 12 for monthly to annual).
- Returns:
tuple – Scaled mean vector and covariance matrix.
- Parameters:
mu (numpy.ndarray | pandas.Series)
cov (numpy.ndarray | pandas.DataFrame)
annualization_factor (float)
- Return type:
tuple[numpy.ndarray | pandas.Series, numpy.ndarray | pandas.DataFrame]
- pyvallocation.utils.projection.project_risk_drivers(R, investment_horizon=2, p=None, n_simulations=1000, reprice=None, seed=None)
Simulate horizon sums by sampling invariants with replacement.
Implements P3 (Projection) of Meucci’s Prayer framework: invariants are bootstrapped over
investment_horizonsteps and summed (random walk). If arepricecallable is supplied, it is applied to the projected risk drivers to obtain P&L scenarios (P4 Pricing).- Parameters:
R – Historical or simulated invariants (e.g. log-returns, yield changes). One-dimensional inputs represent single-instrument (length
T). Two-dimensional inputs representTscenarios acrossNrisk drivers.investment_horizon – Number of draws (with replacement) per simulated path. Defaults to
2.p – Scenario probabilities. When omitted, draws are uniform. Length must match the number of rows in
R.n_simulations – Number of simulated paths to generate. Defaults to
1000.reprice – Optional callable
f(projected_risk_drivers) -> pnl_scenariosthat converts projected risk-driver changes into P&L or simple-return scenarios. Built-in options:reprice_exp()(stocks:exp(Δy) - 1),reprice_taylor()(greeks/duration:θτ + δΔy + ½γΔy²).seed – Random seed for reproducibility. Defaults to
None.
- Returns:
numpy.ndarray or pandas.Series or pandas.DataFrame – Simulated sums whose structure mirrors the input type:
1-D inputs yield length-
n_simulationsvectors.2-D inputs yield
(n_simulations, n_assets)matrices.
Examples
>>> import numpy as np >>> project_scenarios( ... np.array([0.01, -0.02, 0.03]), ... investment_horizon=2, ... n_simulations=4, ... ).shape (4,) >>> import pandas as pd >>> df = pd.DataFrame({"a": [0.01, -0.02], "b": [0.0, 0.02]}) >>> project_scenarios(df, investment_horizon=2, n_simulations=3).shape (3, 2)
- pyvallocation.utils.projection.project_scenarios(R, investment_horizon=2, p=None, n_simulations=1000, reprice=None, seed=None)[source]
Simulate horizon sums by sampling invariants with replacement.
Implements P3 (Projection) of Meucci’s Prayer framework: invariants are bootstrapped over
investment_horizonsteps and summed (random walk). If arepricecallable is supplied, it is applied to the projected risk drivers to obtain P&L scenarios (P4 Pricing).- Parameters:
R – Historical or simulated invariants (e.g. log-returns, yield changes). One-dimensional inputs represent single-instrument (length
T). Two-dimensional inputs representTscenarios acrossNrisk drivers.investment_horizon – Number of draws (with replacement) per simulated path. Defaults to
2.p – Scenario probabilities. When omitted, draws are uniform. Length must match the number of rows in
R.n_simulations – Number of simulated paths to generate. Defaults to
1000.reprice – Optional callable
f(projected_risk_drivers) -> pnl_scenariosthat converts projected risk-driver changes into P&L or simple-return scenarios. Built-in options:reprice_exp()(stocks:exp(Δy) - 1),reprice_taylor()(greeks/duration:θτ + δΔy + ½γΔy²).seed – Random seed for reproducibility. Defaults to
None.
- Returns:
numpy.ndarray or pandas.Series or pandas.DataFrame – Simulated sums whose structure mirrors the input type:
1-D inputs yield length-
n_simulationsvectors.2-D inputs yield
(n_simulations, n_assets)matrices.
Examples
>>> import numpy as np >>> project_scenarios( ... np.array([0.01, -0.02, 0.03]), ... investment_horizon=2, ... n_simulations=4, ... ).shape (4,) >>> import pandas as pd >>> df = pd.DataFrame({"a": [0.01, -0.02], "b": [0.0, 0.02]}) >>> project_scenarios(df, investment_horizon=2, n_simulations=3).shape (3, 2)
- pyvallocation.utils.projection.reprice_exp(delta_y)[source]
Reprice via exponentiation (stocks, equity indices).
Maps projected log-return invariants to simple returns:
P&L / V_0 = exp(Δy) - 1.This is the exact repricing for instruments whose risk driver is the log-price (Meucci Prayer P4, Eq. 17 for stocks).
- Parameters:
delta_y – Projected risk-driver changes
Y_{T+τ} - Y_T(log-returns).- Returns:
np.ndarray – Simple-return scenarios.
- Parameters:
delta_y (numpy.ndarray)
- Return type:
numpy.ndarray
- pyvallocation.utils.projection.reprice_taylor(delta_y, *, theta=None, delta=None, gamma=None, tau=0.0)[source]
Reprice via Taylor / Greek approximation (options, bonds).
Approximates the P&L using a second-order expansion around the current risk-driver values (Meucci Prayer P4, Eq. 18):
\[\text{P\&L} \approx \theta\,\tau + \delta\,\Delta y + \tfrac12\,\gamma\,(\Delta y)^2.\]The coefficients are instrument-specific sensitivities:
Equities:
delta=1, others zero (reduces to linear return).Options:
theta(time decay),delta(option delta),gamma(option gamma). For multi-factor options,deltaandgammacan be vectors/matrices matching risk-driver columns.Bonds:
delta = -duration * price,gamma = convexity * price.
- Parameters:
delta_y – Projected risk-driver changes (
n_sim × n_drivers).theta – Time-decay coefficient(s). Scalar or per-instrument array.
delta – First-order sensitivity (delta, -duration, etc.).
gamma – Second-order sensitivity (gamma, convexity, etc.).
tau – Time step (e.g.
1/252for daily,1/12for monthly).
- Returns:
np.ndarray – Approximate P&L scenarios, same shape as
delta_y.- Parameters:
delta_y (numpy.ndarray)
theta (numpy.ndarray | float | None)
delta (numpy.ndarray | float | None)
gamma (numpy.ndarray | float | None)
tau (float)
- Return type:
numpy.ndarray
- pyvallocation.utils.projection.simple2log(mu_r, cov_r)[source]
mu,Sigma of simple returns -> mu,Sigma of log-returns (log-normal assumption).
- Parameters:
mu_r – Mean of simple returns.
cov_r – Covariance of simple returns.
- Returns:
Tuple[ArrayLike, ArrayLike] – Mean and covariance in log-return units.
- pyvallocation.utils.projection.simulate_paths(R, horizon=2, n_paths=1000, p=None, reprice=None, seed=None)[source]
Simulate full trajectory paths by bootstrapping invariants.
Unlike
project_scenarios()which returns only the terminal sum, this function returns the cumulative risk-driver change at every intermediate step, enabling drawdown analysis and fan charts.- Parameters:
R – Invariant scenarios
(T, N)or(T,)(e.g. log-returns).horizon – Number of bootstrap steps per path.
n_paths – Number of simulated paths.
p – Optional scenario probabilities.
reprice – Optional callable applied to cumulative risk-driver changes at each step (e.g.
reprice_expfor cumulative simple returns).seed – Random seed for reproducibility.
- Returns:
np.ndarray – Shape
(n_paths, horizon, N)— cumulative risk-driver changes (or repriced values) at each time step.- Parameters:
horizon (int)
n_paths (int)