Class BootstrapJacobian
MultiCurveRisk).
The plain idea: the bootstrap makes every instrument reprice,
q = I(Y), where Y are the pillar values
y_j = -ln P(t_j) of the OIS curve and then the projection curve.
Differentiating that identity (implicit function theorem) gives the pillar
response to a quote move without re-solving anything:
J = dI/dY (analytic, per instrument; square, block lower triangular)
dY/dq = J^{-1}
dPV/dq = (dPV/dY)^T J^{-1} bucketed DV01_k = 1bp * (J^{-T} dPV/dY)_k
J is built in closed form from each instrument's implied-quote
formula and the curve's interpolation weights dy(t)/dy_j: exact
for CurveInterpolation.LOG_LINEAR_DISCOUNT; for
CurveInterpolation.MONOTONE_CONVEX the instrument formulas stay
analytic but the interpolation weights are central differences of the
interpolant (no re-bootstrap). dPV/dY is a central difference in
the pillar values, because the PV function is a black box.
Worked example and check: on the test OIS + 3M curve set with
log-linear interpolation, the buckets match the bump-and-rebuild
MultiCurveRisk.bucketedDv01(LocalDate, List, List, CurveInterpolation, ToDoubleBiFunction) to about 1e-6 relative (the
difference is the second-order term of a 1bp central bump); the Jacobian
itself matches a finite difference of the implied quotes to 1e-6. With
monotone-convex interpolation it matches a 1e-7 quote-bump rebuild to
1e-4 of the largest bucket, while the 1bp rebuild of
MultiCurveRisk can be off by about 10% in single buckets, because
a 1bp move crosses the interpolant's shape-zone kinks. That is the
practical case for this class.
-
Method Summary
Modifier and TypeMethodDescriptionstatic double[]bucketedDv01(LocalDate valuationDate, List<CurveInstrument> oisInstruments, List<CurveInstrument> projectionInstruments, CurveInterpolation interpolation, ToDoubleBiFunction<DiscountCurve, DiscountCurve> pv) Per-quote DV01 with the same contract and ordering asMultiCurveRisk.bucketedDv01(LocalDate, List, List, CurveInterpolation, ToDoubleBiFunction): the PV change for +1bp in each quote, OIS quotes first, by the implicit-function Jacobian.static double[][]quoteJacobian(CurvePair curves, List<CurveInstrument> oisInstruments, List<CurveInstrument> projectionInstruments) dI_k/dY_j: rows are the OIS instruments then the projection instruments (input order), columns the OIS curve pillars then the projection curve pillars (pillar order).
-
Method Details
-
quoteJacobian
public static double[][] quoteJacobian(CurvePair curves, List<CurveInstrument> oisInstruments, List<CurveInstrument> projectionInstruments) dI_k/dY_j: rows are the OIS instruments then the projection instruments (input order), columns the OIS curve pillars then the projection curve pillars (pillar order). With an empty projection list the projection curve is the OIS curve and the matrix is OIS-only.- Parameters:
curves- curves built from these instruments (MultiCurveRisk.buildCurves(LocalDate, List, List, CurveInterpolation))oisInstruments- OIS curve instrumentsprojectionInstruments- projection curve instruments (may be empty)- Returns:
- the square Jacobian
-
bucketedDv01
public static double[] bucketedDv01(LocalDate valuationDate, List<CurveInstrument> oisInstruments, List<CurveInstrument> projectionInstruments, CurveInterpolation interpolation, ToDoubleBiFunction<DiscountCurve, DiscountCurve> pv) Per-quote DV01 with the same contract and ordering asMultiCurveRisk.bucketedDv01(LocalDate, List, List, CurveInterpolation, ToDoubleBiFunction): the PV change for +1bp in each quote, OIS quotes first, by the implicit-function Jacobian.- Parameters:
valuationDate- valuation dateoisInstruments- OIS curve instrumentsprojectionInstruments- projection curve instruments (may be empty)interpolation- curve interpolationpv- PV as a function of (discount, projection)- Returns:
- bucketed DV01s
-