Struct RiskFrame
pub struct RiskFrame<'a> {
risk: &'a RiskVector,
npv: f64,
market: &'a MarketContext,
}Expand description
A risk vector, the value it came from, and the market that explains both.
Holds the market by reference, so a frame built per lens-filtered sub-book borrows one set of ladders rather than copying a matrix per book.
Fields§
§risk: &'a RiskVector§npv: f64§market: &'a MarketContextImplementations§
§impl<'a> RiskFrame<'a>
impl<'a> RiskFrame<'a>
pub fn new(risk: &'a RiskVector, npv: f64, market: &'a MarketContext) -> Self
pub fn new(risk: &'a RiskVector, npv: f64, market: &'a MarketContext) -> Self
A frame from its parts, so a risk vector collected outside a book valuation is measured through the same path as one collected inside.
pub fn risk(&self) -> &'a RiskVector
pub fn risk(&self) -> &'a RiskVector
The vector as collected — per parameter, unweighted and unflipped.
pub fn valuation_date(&self) -> Option<NaiveDate>
pub fn valuation_date(&self) -> Option<NaiveDate>
The date tenor buckets are measured from: the reference date the market’s curves share.
pub fn read(
&self,
axis: RiskAxis,
basis: Basis,
aggregation: Aggregation,
scale: Scale,
) -> Result<Vec<(Label, f64)>, RiskError>
pub fn read( &self, axis: RiskAxis, basis: Basis, aggregation: Aggregation, scale: Scale, ) -> Result<Vec<(Label, f64)>, RiskError>
One reading of the frame: an axis, a basis, an aggregation, and the scale the rows are reported in.
The scale is applied here and nowhere else, so a report and a frame read at the same scale are the same numbers.
§Errors
RiskError when a Basis::Par reading meets a curve pinned without
its ladder, or when a Aggregation::Bucketed reading has no valuation
date to measure tenors from.
fn read_unit(
&self,
axis: RiskAxis,
basis: Basis,
aggregation: Aggregation,
) -> Result<Vec<(Label, f64)>, RiskError>
fn read_unit( &self, axis: RiskAxis, basis: Basis, aggregation: Aggregation, ) -> Result<Vec<(Label, f64)>, RiskError>
read per unit quote.
pub fn read_buckets(
&self,
axis: RiskAxis,
basis: Basis,
edges: &[Period],
scale: Scale,
) -> Result<Vec<(Label, f64)>, RiskError>
pub fn read_buckets( &self, axis: RiskAxis, basis: Basis, edges: &[Period], scale: Scale, ) -> Result<Vec<(Label, f64)>, RiskError>
A zero or par reading on axis bucketed on edges rather than the
fixed ladder: a bucket up to each edge, measured in years from the
valuation date as the fixed ladder is, then one past the last.
§Errors
RiskError::BucketEdges for no edges, or edges that are not day,
week, month or year tenors, positive and rising; otherwise as
read.
fn bucket(
&self,
contributions: Vec<Contribution>,
edges: &[f64],
) -> Result<BTreeMap<usize, f64>, RiskError>
fn bucket( &self, contributions: Vec<Contribution>, edges: &[f64], ) -> Result<BTreeMap<usize, f64>, RiskError>
contributions summed by the first of edges, in years from the
valuation date, each one’s date falls on or before; the last edge is
open-ended.
fn zero_contributions(
&self,
axis: RiskAxis,
parallel: bool,
) -> Vec<Contribution>
fn zero_contributions( &self, axis: RiskAxis, parallel: bool, ) -> Vec<Contribution>
The axis’s entries, each weighted into its own curve node’s quote.
parallel reads each entry as its share of the axis moving as a whole,
for a sum: a fitted curve’s shape parameters and a SABR node’s ρ and ν
then weigh nothing, where a ladder shows each as its own row.
fn par_contributions(
&self,
axis: RiskAxis,
) -> Result<Vec<Contribution>, RiskError>
fn par_contributions( &self, axis: RiskAxis, ) -> Result<Vec<Contribution>, RiskError>
The axis’s entries flipped onto the instruments that calibrated them.
∂V/∂q = Σ_p (∂V/∂p)·(∂p/∂q) where p runs over the pillars of the
ladder a rung belongs to — which is the Jacobian’s column, read down.
The contraction takes the raw parameter sensitivity, not the
zero-basis one: ∂z/∂q is already expressed against the parameters the
curve stores, so weighting first would apply ∂p/∂q twice.
Columns are keyed by the ladder’s identity and position, not by the role the curve was pinned under. A curve serving two roles shares one ladder, so both roles’ pillars land on the same column and sum there — which is the right answer for an instrument that calibrated a curve doing two jobs, and is not reachable if columns are keyed by role.
On the vol axis the same flip runs through a SABR fit: a node’s sensitivity lands on the grid quotes its slice was fitted to, through the fit’s quote Jacobian. A grid node already is a quote and stands as itself.