Implied correlation and dispersion from an index and its constituents.

FerroRisk reads the average pairwise correlation the market is pricing between an index and its constituents, and the dispersion premium that falls out of it, on one typed path.

Why this needs one shared risk path

!

Implied correlation is easy to state and easy to get wrong when the constituent weights and variances are combined inconsistently.

!

Dispersion desks need the weighted-average vol and the uncorrelated index variance, not just a single correlation number.

!

Index and constituent IVs must share a tenor for the read to mean anything.

How FerroRisk handles it

01

Assemble the basket

BasketConstituent::new(iv, weight) validates each constituent so a bad weight or IV is rejected up front.

02

Read implied correlation

implied_correlation(index_iv, &constituents, tenor) returns a typed DispersionRead with the implied average pairwise correlation.

03

Use the dispersion legs

The read exposes weighted-average vol, uncorrelated index variance, and the dispersion premium in both variance and vol-point units.

What makes this FerroRisk-shaped

implied_correlation and BasketConstituent are public crate-root exports.

The read shares the SurfaceTenor type with the surface and VRP workflows, so tenors line up across the crate.

The dispersion hot path is benchmarked, and degenerate baskets fail loud with typed errors.

Common concerns

Is the correlation clamped to [-1, 1]?

No. rho_implied is reported raw and unclamped so you can see when the inputs imply an out-of-range correlation, rather than having it silently hidden.

What else does the read expose besides correlation?

DispersionRead carries the weighted-average vol and variance, the uncorrelated index variance, the dispersion premium, the weight sum, and the constituent count.