Use case · Volatility
Read implied correlation and dispersion from a basket
implied_correlation takes an index implied vol and a slice of typed BasketConstituent weights and IVs on a shared tenor, and returns a DispersionRead — the average pairwise correlation the market is pricing, plus the dispersion premium.
When to use it
- You need the option-implied average pairwise correlation between an index and its constituents.
- You want the dispersion premium — the gap between weighted-average constituent vol and the index vol — in variance and vol-point units.
- You need the intermediate legs (weighted-average variance, uncorrelated index variance) rather than a single opaque number.
Example
use ferro_risk::{implied_correlation, BasketConstituent, SurfaceTenor};
let tenor = SurfaceTenor::new(30.0 / 365.0)?; // 30-day tenor, in years
// Each constituent: implied vol and index weight.
let constituents = vec![
BasketConstituent::new(0.28, 0.35)?,
BasketConstituent::new(0.24, 0.40)?,
BasketConstituent::new(0.31, 0.25)?,
];
// index_iv is the index's own implied vol on the same tenor.
let read = implied_correlation(0.19, &constituents, tenor)?;
println!("implied correlation = {}", read.rho_implied());
println!("dispersion (variance) = {}", read.dispersion_variance());
println!("dispersion (vol pts) = {}", read.dispersion_vol_pts());
println!("weighted-avg vol = {}", read.weighted_avg_vol());
# Ok::<(), ferro_risk::FerroRiskError>(())The read
| DispersionRead | Description |
|---|---|
| rho_implied() | The implied average pairwise correlation — raw and unclamped. |
| dispersion_variance() | Dispersion premium in variance units (weighted-avg variance − index variance). |
| dispersion_vol_pts() | Dispersion premium in volatility points (weighted-avg vol − index vol). |
| index_iv() | The index implied volatility input. |
| weighted_avg_vol() | Weight-weighted average constituent volatility. |
| weighted_avg_var() | Weight-weighted average constituent variance. |
| uncorrelated_index_var() | Index variance implied if constituents were uncorrelated. |
| weight_sum() | Sum of the constituent weights. |
| constituent_count() | Number of constituents in the basket. |
| tenor() | The SurfaceTenor the read is quoted on. |
Notes
rho_implied()is reported raw and unclamped — a value outside[-1, 1]is surfaced rather than hidden, so you can see when the inputs imply an out-of-range correlation.- The index and every constituent IV must be quoted on the same
SurfaceTenor— the same type used across the surface and VRP workflows. BasketConstituent::new(iv, weight)validates each constituent up front, so a non-positive weight or a non-finite IV is rejected at construction.- A basket needs at least two constituents; degenerate baskets and a zero denominator fail loud with a typed
FerroRiskErrorin theimplied_correlation.*namespace.
Related
Dispersion sits beside the variance risk premium and realized volatility in the volatility-analytics layer — all three share the SurfaceTenor contract.