|
From: <mat...@gm...> - 2021-07-24 11:33:03
|
Dear mailing list,
Apologies for the imprecise subject line. Cannot seem to summarize the matter less verbosely than the following:
I would like to price an instrument, say a Bond with the DiscountingBondEngine (using QuantLib’s Python bindings). This engine consumes e.g. a handle to a ZeroCurve or ZeroSpreadedTermStructure.
That is, the YieldTermStructure instance used here is built from a list of Dates and Rates (and potentially a spread). The reference date of the curve so constructed will be the first element in the list of Dates.
For example:
ref_date = ql.Date(2021, 7, 23)
zero_dates_t = [ref_date] + [ql.Date.from_date(d) for d in …]
zero_rates_t = [-0.001, -0.0009, …]
zero_curve_t = ql.NaturalCubicZeroCurve(zero_dates_t, zero_rates_t, day_count, calendar, ql.SplineCubic(), compounding, frequency)
shifted_curve_t = ql.ZeroSpreadedTermStructure(ql.YieldTermStructureHandle(zero_curve_t), spread_handle, compounding, zero_curve_t.dayCounter())
engine = ql.DiscountingBondEngine(ql.YieldTermStructureHandle(shifted_curve_t))
bond.setPricingEngine(engine)
Now imagine I also have a zero_curve_t0 with rates from a prior reference date, say 2021-6-23.
When I would like to price the bond as of 2021-7-23 (T), but using the rate curve of 2021-6-23 (T0) – thus playing the scenario that no change in yields occurred in 1 month – then I could for example use the composite zero curve as follows:
composite_zero = ql.CompositeZeroYieldStructure(
ql.YieldTermStructureHandle(zero_curve_t),
ql.YieldTermStructureHandle(zero_curve_t0),
lambda r1, r2: r2,
compounding,
frequency)
)
shifted_composite = ql.ZeroSpreadedTermStructure(ql.YieldTermStructureHandle(composite_zero), spread_handle)
Here, timeFromReference is calculated from the reference date of the first argument curve, zero_curve_t: 2021-7-23. But rates are picked from the second argument curve, zero_curve_t0.
It looks a bit like a hack, but it appears to work.
However, imagine now I would like to price the bond still as of 2021-7-23 (reference date of zero_curve_t), but using rates from 2021-6-23 *without* shifting zero_curve_t0 by a time offset of 1 month.
So let us say the first cash flow occurs on 2021-10-23, i.e. in three month from T (and four months from T0). Then it should be discounted with the 4-month zero rate of zero_curve_t0. The method described above would discount with the 3-month zero rate of zero_curve_t0.
Because the discounting engine uses as evaluation date the reference date of the yield curve supplied to the engine, one has to supply a curve with reference 2021-7-23 in order to price at T.
Now how would I shift the rates of zero_curve_t0 such that it attains a reference date of 2021-7-23, but the zero rate on t=3/12 would coincide with the zero rate of zero_curve_t0 on t=4/12?
I could maybe construct a new curve with, say, daily nodes beginning from 2021-7-23, going on for 40Y and its rates are evaluated per zero_curve_t0. But this looks like an even worse hack than the roll-down via composite curves and it sure is wasteful with respect to resources.
Is there any better way which I fail to see?
Thanks and kind regards,
Matthias
|