Estimate potential future losses using VaR, Expected Shortfall, Monte Carlo simulation, and stress testing. Use when the user asks about Value-at-Risk, CVaR, Expected Shortfall, scenario analysis, stress testing, or factor-based risk decomposition. Also trigger when users mention 'how much could I lose', 'worst-case scenario', 'tail risk', 'risk budget', 'component VaR', 'marginal VaR', '99% confidence loss', 'Monte Carlo simulation', or ask how to project portfolio risk forward.
Scanned 6/12/2026
Install via CLI
openskills install JoelLewis/finance_skills---
name: forward-risk
description: "Estimate potential future losses using VaR, Expected Shortfall, Monte Carlo simulation, and stress testing. Use when the user asks about Value-at-Risk, CVaR, Expected Shortfall, scenario analysis, stress testing, or factor-based risk decomposition. Also trigger when users mention 'how much could I lose', 'worst-case scenario', 'tail risk', 'risk budget', 'component VaR', 'marginal VaR', '99% confidence loss', 'Monte Carlo simulation', or ask how to project portfolio risk forward."
---
# Forward-Looking Risk Analysis
## Core Concepts
### Parametric (Variance-Covariance) VaR
Assumes returns are normally distributed. For a single asset or portfolio in dollar terms (assuming zero expected return over short horizons):
```
VaR = W * z_alpha * sigma_p
```
where:
- W = portfolio value
- z_alpha = z-score for confidence level (1.645 for 95%, 2.326 for 99%)
- sigma_p = portfolio volatility over the relevant horizon
More generally, including expected return:
```
VaR_alpha = mu - z_alpha * sigma
```
To convert from 1-day VaR to h-day VaR (assuming i.i.d. returns):
```
VaR_h = VaR_1 * sqrt(h)
```
### Portfolio VaR (Multiple Assets)
For a portfolio with weight vector w and covariance matrix Sigma:
```
sigma_p = sqrt(w' * Sigma * w)
VaR_p = W * z_alpha * sqrt(w' * Sigma * w)
```
The covariance matrix captures both individual volatilities and correlations between assets.
### Monte Carlo VaR
Simulate a large number of portfolio return scenarios (e.g., 10,000+), then take the alpha-percentile of the simulated loss distribution.
Steps:
1. Estimate the return distribution parameters (mean vector, covariance matrix, or use a copula model).
2. Generate N random return scenarios (e.g., via Cholesky decomposition of the covariance matrix for multivariate normal).
3. Compute portfolio return for each scenario.
4. Sort results and identify the alpha-percentile loss.
Monte Carlo VaR can accommodate non-normal distributions, fat tails, path-dependent instruments, and nonlinear payoffs (e.g., options).
### Conditional VaR (CVaR) / Expected Shortfall
CVaR answers: "Given that losses exceed VaR, what is the expected loss?"
```
ES_alpha = E[Loss | Loss > VaR_alpha]
```
For a normal distribution:
```
ES_alpha = mu + sigma * phi(z_alpha) / (1 - alpha)
```
where phi is the standard normal PDF.
CVaR is a **coherent risk measure** (unlike VaR) because it satisfies subadditivity: CVaR(A+B) <= CVaR(A) + CVaR(B). This means diversification always reduces or maintains CVaR, which is not guaranteed for VaR.
### Component VaR
Decomposes total portfolio VaR into contributions from each position. Component VaRs sum to total VaR.
```
CVaR_i = w_i * beta_i * VaR_p
```
where beta_i = Cov(R_i, R_p) / Var(R_p) is the asset's beta to the portfolio.
Equivalently:
```
CVaR_i = w_i * (partial VaR / partial w_i)
sum(CVaR_i) = VaR_p
```
This decomposition identifies which positions are the largest contributors to portfolio risk.
### Marginal VaR
Measures the rate of change of portfolio VaR with respect to a small increase in a position's weight.
```
MVaR_i = partial(VaR_p) / partial(w_i) = z_alpha * (Sigma * w)_i / sigma_p
```
Marginal VaR is used for position sizing: adding to a position with low marginal VaR reduces portfolio risk more efficiently.
### Scenario Analysis
Apply specific historical or hypothetical market moves to the current portfolio to estimate P&L impact.
- **Historical scenarios:** Replay actual market events (e.g., 2008 GFC, 2020 COVID crash, 2022 rate hiking cycle) with current holdings.
- **Hypothetical scenarios:** Construct custom shocks (e.g., "equities -20%, rates +200bp, credit spreads +300bp, USD +10%").
Scenario P&L is computed by applying the scenario returns to current position exposures and revaluing.
### Stress Testing
A structured framework for assessing portfolio resilience under extreme but plausible conditions.
Common stress scenarios:
- Equity crash: S&P 500 -30% to -40%
- Interest rate shock: +300bp parallel shift
- Credit crisis: investment-grade spreads +200bp, high-yield +800bp
- Liquidity freeze: bid-ask spreads widen 10x, forced selling at discount
- Currency shock: major currency pair moves 15-20%
- Stagflation: inflation +5%, GDP -3%, rates +200bp
Stress tests should include second-order effects: margin calls, liquidity demands, correlation spikes, counterparty risk.
### Factor-Based Risk Decomposition
Separate total portfolio risk into systematic factor risk and idiosyncratic (security-specific) risk.
```
sigma^2_p = b' * Sigma_f * b + sum(w_i^2 * sigma^2_epsilon_i)
```
where:
- b = vector of portfolio factor exposures
- Sigma_f = factor covariance matrix
- sigma^2_epsilon_i = idiosyncratic variance of asset i
Common factor models: Fama-French (market, size, value, momentum), Barra risk models, PCA-based statistical factors.
## Key Formulas
| Formula | Expression | Use Case |
|---------|-----------|----------|
| Parametric VaR (single) | W * z_alpha * sigma | Simple position VaR |
| Portfolio VaR | W * z_alpha * sqrt(w' * Sigma * w) | Multi-asset VaR |
| Multi-day VaR | VaR_1 * sqrt(h) | Scale to h-day horizon |
| CVaR (normal) | mu + sigma * phi(z_alpha) / (1 - alpha) | Expected tail loss |
| Component VaR | w_i * beta_i * VaR_p | Risk contribution per position |
| Marginal VaR | z_alpha * (Sigma * w)_i / sigma_p | Sensitivity to weight change |
| Factor Risk | b' * Sigma_f * b | Systematic risk component |
| Idiosyncratic Risk | sum(w_i^2 * sigma^2_epsilon_i) | Security-specific risk |
## Worked Examples
### Example 1: Parametric 95% VaR
**Given:** A $1,000,000 equity portfolio with an annualized volatility of 15%.
**Calculate:** 1-day 95% parametric VaR (assuming 252 trading days and zero expected daily return).
**Solution:**
Daily volatility:
```
sigma_daily = 0.15 / sqrt(252) = 0.15 / 15.875 = 0.00945
```
1-day 95% VaR:
```
VaR = $1,000,000 * 1.645 * 0.00945 = $15,545
```
Alternatively, computing directly from annual figures:
```
VaR_annual = $1,000,000 * 1.645 * 0.15 = $246,750
VaR_1day = $246,750 / sqrt(252) = $15,545
```
Interpretation: There is a 5% chance of losing more than $15,545 in a single day under normal market conditions.
### Example 2: Monte Carlo VaR
**Given:** A two-asset portfolio (60% equities, 40% bonds). Equities: mu = 10%, sigma = 18%. Bonds: mu = 4%, sigma = 5%. Correlation rho = -0.2. Portfolio value = $1,000,000.
**Calculate:** 95% annual VaR via Monte Carlo simulation (conceptual steps).
**Solution:**
1. **Construct covariance matrix:**
```
Sigma = | 0.0324 -0.0018 |
| -0.0018 0.0025 |
```
2. **Cholesky decomposition** of Sigma to get lower triangular matrix L.
3. **Simulate 10,000 scenarios:** For each simulation, draw z ~ N(0, I), compute r = mu + L*z, then portfolio return R_p = w' * r.
4. **Compute portfolio P&L** for each scenario: P&L = $1,000,000 * R_p.
5. **Sort P&L** from worst to best. The 500th worst (5th percentile) is the 95% VaR.
For this portfolio, the analytical answer provides a benchmark:
```
sigma_p = sqrt(0.6^2 * 0.0324 + 0.4^2 * 0.0025 + 2 * 0.6 * 0.4 * (-0.0018))
= sqrt(0.011664 + 0.0004 - 0.000864)
= sqrt(0.0112)
= 10.58%
VaR_95% = $1,000,000 * 1.645 * 0.1058 = $174,090
```
The Monte Carlo result should converge to approximately this value for a multivariate normal assumption.
### Example 3: Expected Shortfall
**Given:** From the Monte Carlo simulation above, the losses exceeding VaR (the worst 500 out of 10,000 scenarios) have an average loss of $225,000.
**Calculate:** 95% CVaR.
**Solution:**
```
CVaR_95% = $225,000
```
Interpretation: When losses exceed the 95% VaR threshold, the average loss is $225,000. This is roughly 29% worse than the $174,090 VaR figure, highlighting the severity of tail events.
## Common Pitfalls
- **VaR says nothing about tail shape:** VaR only identifies a threshold. Two portfolios with identical VaR can have vastly different tail losses. Always compute CVaR alongside VaR to understand tail severity.
- **Parametric VaR assumes normality:** Financial returns exhibit fat tails and skewness. Parametric VaR systematically underestimates tail risk. Use Monte Carlo with fat-tailed distributions or historical simulation for more realistic estimates.
- **Correlation breakdown in crises:** Correlations spike toward 1.0 during market stress, precisely when diversification is most needed. Stress tests should use crisis-period correlations, not calm-period correlations.
- **Using too short a lookback for covariance estimation:** Too short a window is noisy; too long a window includes stale data from different market regimes. A common compromise is 1-3 years of daily data, or use EWMA-weighted covariances.
- **Not distinguishing between absolute VaR and relative VaR:** Absolute VaR includes expected return (VaR = -mu + z*sigma); relative VaR excludes it (VaR = z*sigma). For short horizons (1-10 days), the expected return is negligible and the distinction is minor. For longer horizons, it matters.
- **Square-root-of-time scaling limitations:** VaR_h = VaR_1 * sqrt(h) assumes i.i.d. returns. With serial correlation or volatility clustering, this scaling is inaccurate.
## Cross-References
- **historical-risk**: Historical VaR and realized volatility serve as non-parametric alternatives and calibration benchmarks for the forward-looking models in this skill.
- **performance-metrics**: VaR and CVaR can be used as risk denominators in modified risk-adjusted ratios (e.g., return/CVaR).
- **volatility-modeling**: EWMA and GARCH volatility forecasts provide the volatility inputs (sigma) for parametric and Monte Carlo VaR.
## Running the Script
```bash
uv run scripts/forward_risk.py # run the demo (uses PEP 723 inline deps)
uv run scripts/forward_risk.py --verify # check demo outputs against the worked examples (exit 1 on mismatch)
python3 scripts/forward_risk.py # alternative (requires: pip install numpy scipy)
```
The demo prints the calculations covered above; its values match the worked examples in this skill. Run `--help` for a list of the classes and functions. For programmatic use, import the module rather than running it — the demo only executes under `python forward_risk.py`.
No comments yet. Be the first to comment!