Module pnl
Expand description
P&L attribution between two markets, in parameter space.
Three verbs over the same move Δ = after − before, one lifted input at a
time:
market_diff— the move itself, under a layout guard: two markets are comparable only if their lifted input sequences are identical, and a mismatch names the first input that differs rather than attributing a hazard move to a rates pillar.predicted_pnl— first order from the risk vector atbefore, plus the quadratic term from one second-order valuation seeded along the whole move:lift_directionalputsΔon aJet2tangent, and the second derivative that comes back is exactlyΔᵀ H Δ. No Hessian is assembled, nothing is bumped, and the term is exact rather than a diagonal guess. The same pass along the move restricted to one axis group, and to two, splits it exactly by the groups that moved (GammaTerms): an own gamma per group and one symmetric cross gamma per pair, by the polarisation identityd_aᵀ H d_b = ½[q(d_a + d_b) − q(d_a) − q(d_b)]. That is1 + m + m(m − 1)/2passes formmoved groups, a handful on a daily move, and still no matrix: the split is by axis pair, which is what a reconciliation reads, not by input.explain— the sequential revaluation ladder: inputs move frombeforetoafterone axis group at a time, each step a full valuation. A step takes the axis’s curves asafterholds them — a scenario’s shock transform, which carries no parameter, included — and its parameters atafter’s values. The final step isnpv(after)bit for bit, checked, and the legs close to the actual P&L within the round-off of summing them.
Both attributions refuse a move they cannot see
(PnlError::MoveOutsideParameters): the prediction reads the risk vector
at before, whose coordinates a shock transform is not in, and the ladder
moves only what an axis holds.
reconcile aligns the two attributions by axis and names what each
leg’s difference is made of: the leg’s own gamma, its cross gamma with the
axes the ladder moved before it — the step-order effect, as a number — and
the residual neither explains. The differences sum to the prediction’s
quadratic-plus-residual, the own and cross columns to its second-order
terms.
What became known comes first. A print the ending market holds and the
starting market does not is not a move of a parameter the starting market
has: it is a new parameter. The layout guard relaxes in exactly that one
way — a MarketInputId::Fixing present on the after side alone is
lifted out as a newly published print, and every other difference is still
refused — and both attributions begin by publishing those prints onto the
starting market: the ExplainLeg::Resets leg of the ladder, the resets term
of the prediction. reset_pnl is the same step read per print, the way a
desk reads it: the forecast the print replaced, the print, the move, the
sensitivity, the P&L. Both markets must be valued on the same day; the
overnight move — yesterday’s close to today’s — re-dates every pillar and
is a carry-and-roll step, not this one.
Across days the ladder starts with two legs of its own
(explain_across_days): the ExplainLeg::Cash the book was paid
between the dates, and the ExplainLeg::Carry — the book on the
starting market’s quotes rebuilt at the ending date, less its starting
value. From that rolled market to the ending one is a same-day move, which
the ladder above explains.
Structs§
- Explain
Report - A step-revaluation explain.
- Gamma
Terms - The second-order term split exactly by the axis groups that moved.
- Layout
Mismatch - Where two markets’ lifted input sequences first diverge.
- Market
Diff - The move between two markets, one entry per lifted input, in lift order, and the prints the ending market has that the starting market lacks.
- Move
- One lifted input’s move.
- Predicted
Pnl - A predicted explain: first order per input, second order along the move.
- Published
- One print the ending market holds that the starting market does not.
- Reconciliation
- The two attributions aligned by axis.
- Reconciliation
Row - One leg of a reconciliation, its terms named.
- Reset
Pnl - The reset step read per print.
- Reset
Print 🔒 - One print of the reset step: what the coupon applied before it, and the print itself.
- Reset
Row - One published print’s contribution to the reset step.
- Reset
Step 🔒 - The reset step. A market that lacks a print the book has accrued refuses
to value, so the step does not start from
beforeas given: it starts frombeforewith each new print standing at the forecast it replaced — the value the book carried while the print was projected, andbefore’s own value to round-off where it prices without the print — and ends atbeforewith every print published.diffis the move from there toafter, whose layouts now agree.Nonewhenafterpublishes nothing new.
Enums§
- Explain
Leg - What a ladder step moved: the prints that became known, one axis, or everything no axis holds.
- PnlError
- An attribution that could not be produced.
Functions§
- default_
order - The default ladder order: the axes as declared.
- explain
- The step-revaluation explain of
bookfrombeforetoafter: first the printsafterholds thatbeforedoes not, published ontobeforeas theExplainLeg::Resetsleg (present only when there are any), then one axis group at a time inorder: at its step an axis takesafter’s rate, repo, security-spread, credit or inflation curves (shock transforms included) andafter’s value of every parameter on it. Axes absent fromorder, and inputs on no axis, move together in the final leg, so the last step isafter. - explain_
across_ 🔒days - The explain of
bookacross days:cash, what the book was paid afterbefore’s date and up toafter’s, as theExplainLeg::Cashleg; theExplainLeg::Carryleg, frombeforetorolled—before’s quotes rebuilt atafter’s date, each print the book reads in between at the forecastbeforeprojected it at; and fromrolledtoafter, a same-day move, the ladder ofexplain. The legs sum tonpv(after) − npv(before) + cash. - forecast_
of 🔒 - The rate the coupon applied to
datewhile the print was projected: the index’s own window, simple on its day count, offmarket’s projection curve for that index — not the curve’s continuously compounded forward. A curve reaches no date before its reference, and a print that needs attributing is usually dated before it; for such a date the forecast is the index’s forecast at the reference date, the front of the curve read flat backward, which is the rate the curve projects an unprinted day at. - gamma_
terms 🔒 - The split of
quadratic—½ dᵀ H dalong the whole ofdiff— by the groups that moved, perGammaTerms. With one moved group the whole move is that group’s move, so its own term isquadraticitself and no pass is repeated. - group_
label 🔒 - The group a slot labels: the axis, or
Nonefor the off-axis group. - group_
slot 🔒 - The slot of an input’s group: its axis’s position in
RiskAxis::ALL, or one past the end for an input on no axis. - leg_
groups 🔒 - The groups a ladder leg moves: none for the resets, one axis for an axis leg, and for the final leg every axis the ladder did not take plus the inputs on no axis.
- lift_
out_ 🔒new_ prints - The prints in
ids_afterthatids_beforelacks, taken out of the sequence with their values, when the markets share a day. - lifted_
layout 🔒 - The lifted values and input identifiers of a market, passively.
- market_
diff - The move from
beforetoafter, under the layout guard — with one relaxation. AMarketInputId::Fixingthatafterholds andbeforedoes not is a newly published print, not a move: it is lifted out intoMarketDiff::publishedand the remaining inputs are compared position by position as ever. A printbeforeholds andafterdoes not is refused — a print does not un-publish — and so is every other difference. Markets on different valuation days get no relaxation: their prints are compared like any other input. - predicted_
pnl - The predicted explain of
bookbetweenbeforeandafter. Printsafterholds andbeforedoes not are published first — theresetsterm, an exact step, since the risk vector atbeforehas no row for a print it does not hold — and the first and second order are read from the market with them. - reconcile
- Aligns a predicted explain with a ladder explain over the same move, and decomposes each leg’s difference. A leg moves a set of groups — one axis, or for the final leg every axis the ladder did not take plus the inputs on no axis; its own gamma is those groups’ own terms and the cross terms among them, its cross gamma the cross terms between them and every group an earlier leg moved, and its residual the rest. Each second-order term lands on exactly one leg, so the columns sum to the prediction’s terms.
- reset_
pnl - The reset P&L of
bookfrombeforetoafter: one row per printafterholds andbeforedoes not, or holds at another value, each the exact revaluation from the forecast the print replaced to the print, the earlier prints already published, beside the move and the sensitivity. The walk starts frombeforewith every new print standing at its forecast, since a market lacking a print the book has accrued does not value. - reset_
prints 🔒 - Every print
afterholds thatbeforedoes not, or holds at another value, in date order then by index. - reset_
step 🔒 - same_
day 🔒 - Whether the two markets are valued on the same day.
- second_
along 🔒 vᵀ H vfrom one second-order pass ofbookonmarketalongv.- value_
at 🔒 - The book’s value against
marketwith every inputmovedatdiff’s ending value and the rest at its starting value. - value_
of 🔒 - The passive value of
bookagainstmarket. - with_
axis_ 🔒from marketwithaxis‘s curves taken fromafter: its rate, repo and security-spread curves, its credit curves or its inflation curves, each asafterholds it — a scenario’s shock transform included, which is a move no parameter carries. The other axes’ inputs are parameters alone (FX spots, vol surfaces, correlation, recovery), moved byvalue_at.- with_
prints 🔒 marketwith each ofprintspublished atat(print)— a print already held is restated.