lballabio / QuantLib

The QuantLib C++ library
http://quantlib.org
Other
5.26k stars 1.78k forks source link

Why is the forwardStart parameter necessary in the bonds example? #2002

Closed oelhammouchi closed 2 months ago

oelhammouchi commented 3 months ago

I suspect this is more a conceptual question rather than one about the library code, but in the example about bond valuation, the swap quotes used to bootstrap the yield curve have a forwardStart parameter set to 1 day. I'm struggling to wrap my head around why this is necessary. Here's the sample:

const Period forwardStart(1*Days);

auto s2y = ext::make_shared<SwapRateHelper>(
       Handle<Quote>(s2yRate), 2*Years,
       calendar, swFixedLegFrequency,
       swFixedLegConvention, swFixedLegDayCounter,
       swFloatingLegIndex, Handle<Quote>(), forwardStart);

Here's my theory: because fixingDays is set to 3 in the deposit quotes, and the spot lag convention for Euribor6M is 2 days, it is necessary to add a forward start of 1 day to the swap quotes in order to align the reference date for all the nodes used in the bootstrap. Indeed, I've tested out running the file with forwardStart set to 0, and the bootstrap fails.

Conceptually, however, it seems problematic to add an artificial forward start to the swap quotes just to reconcile the reference dates. In reality, these are quotes with 2 days' spot lag. Am I misunderstanding something here?

boring-cyborg[bot] commented 3 months ago

Thanks for posting! It might take a while before we look at your issue, so don't worry if there seems to be no feedback. We'll get to it.

lballabio commented 3 months ago

Hello—I suspect the example should be revised. It's very old (it was written in 2008) and we might not have everything clear at the time. I'll try to modify it so it makes more sense; I think the problem is that it's setting the reference date of the curve to the settlement date of the bonds, which puts the natural start of the swaps before the start of the curve, hence the shift.

The start of the curve should be either today or spot (both will work).

oelhammouchi commented 3 months ago

Thanks for the quick response, and apologies for my delay, I didn't get a notification for some reason. If I understand you correctly, than you're confirming my suspicion. But in that case, how to set the start of the curve to spot? The deposit rates have a spot that's 3 days after todaysDate, as seen from

 auto d1w = ext::make_shared<DepositRateHelper>(
         Handle<Quote>(d1wRate),
         1*Weeks, fixingDays,
         calendar, ModifiedFollowing,
         true, depositDayCounter);

whereas it's 2 days for the swaps because of the Euribor convention. I'm having trouble how these can be reconciled even conceptually.

lballabio commented 3 months ago

The deposit rates should have 2 settlement days. I'll change the example.

However, it's not impossible to have helpers that settle on different days, as long as their settlement date is on or after the start of the curve. For instance, on the very short end of the curve we used to have the overnight, tomorrow-next and spot-next rates. They all have a 1-day tenor, and they have 0, 1 and 2 settlement days, respectively. When the reference date of the curve is set to today, they can all be repriced on the curve: the first is a zero rate and the others are forward rates. The bootstrap process matches the quotes with the rates from the curve being bootstrapped. The same goes, for instance, when helpers are FRA (and the underlying is a forward rate) or swaps (that need a whole sequence of forward rates as well as zero rates for discounting).

You can find a more detailed example of bootstrapping at https://www.implementingquantlib.com/2023/09/ametrano-bianchetti.html; it's a bit dated, since it reproduces the Ametrano-Bianchetti paper from 2013, but still useful.

lballabio commented 3 months ago

Ok, I've reworked the example a bit: https://github.com/lballabio/QuantLib/blob/master/Examples/Bonds/Bonds.cpp

oelhammouchi commented 3 months ago

Thanks so much for the quick work (and the amazing library, probably should have led with that 😅). I think I understand things more clearly now. Essentially, the spot lag means that swap quotes can be treated as 2 day forward quotes (in the case of Euribor6M) with respect to the global evaluation date. Hence, a yield curve that uses such quotes can have a reference no later than global evaluation date + 2 days, otherwise you get a negative time error. Correct?

lballabio commented 2 months ago

Something like that. The swap quotes are a bit more complicated—their calculation uses a forward rate for each floating coupon; the first is a 2-days forward rate and the others are a number of months after. But the general idea is correct.

oelhammouchi commented 2 months ago

Thanks a lot for your help and the amazing library!