Having built a fixed rate bond object, and looking at here and here , is there any way of retrieving the NPV impact of a repriced bond by bucket/tenor of the Spot Curve instead of getting a simple NPV figure? The objective of this would be to have a baseline to apply a simple Value at Risk model to a portfolio of bonds, in which the key risk factors would be the -PV01 figures by tenor.
There is a way, although you will have to code the logic. I'm assuming you want the tenor DV01 (change of market value for a shift of 1 bp in the market rate for a given tenor) and not the PV01 (present value of 1 bp).
Also, bear in mind Luigi's warning on the interpolation between the curve tenor points in one of the posts you mentioned.
import QuantLib as ql import matplotlib.pyplot as plt today = ql.Date().todaysDate() ql.Settings.instance().evaluationDate = today yts = ql.YieldTermStructureHandle( ql.FlatForward(today, 0.01, ql.Actual365Fixed()) ) tenors = (1,2,3,4,5,6,7) quotes = [ql.SimpleQuote(0.00) for n in tenors] spreads = [ql.QuoteHandle(quote) for quote in quotes] dates = [today + ql.Period(y, ql.Years) for y in tenors] spreadedYts = ql.YieldTermStructureHandle( ql.SpreadedLinearZeroInterpolatedTermStructure(yts, spreads, dates) ) engine = ql.DiscountingBondEngine(spreadedYts) bond = ql.FixedRateBond(2, ql.TARGET(), 1e6, today, today + ql.Period(5, ql.Years), ql.Period('1Y'), [0.01], ql.ActualActual()) bond.setPricingEngine(engine) npv = bond.NPV() key_risk =  for quote in quotes: quote.setValue(0.0001) key_risk.append( npv - bond.NPV() ) quote.setValue(0.0) plt.bar(tenors, key_risk)
Which would output:
You might also want to calculate it as the average of the change of market value for an up shift and a down shift