Re: one factor GSR model in QuantLib

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

Re: one factor GSR model in QuantLib

Peter Caspers-4
Hi Yuhong,

thank you for your message. I cc in the dev list, since the topic might be of broader interest. In the GSR model the zero bond price at t (maturity T) conditional on x(t) is (as you can see in the code you copied below)

d * exp(-x * gtT - 0.5 * p->y(t) * gtT * gtT);

with d = today's forward discount factor P(0,t,T) = P(0,T) / P(0,t). Thus I can "recalibrate" the model to another initial yield curve just by exchanging d with the new forward discount factor. This is exactly what is done in the mehod in case the optional parameter yts is non-empty (otherwise the model's default curve is taken). 

This is the same as saying that different curves in the model have a deterministic instantaneous forward basis spread. This is clear, isn't it?

Now it does not really matter which curve exactly is modelled in the Gsr class, because whenever a discount factor or a forward rate estimation is needed, an appropriate curve should replace the model curve. For example, if a forwarding curve is attached to an ibor index, this curve is taken to estimate forward rates in swaption engines instead of the model's default curve. If you look at Gaussian1dModel::forwardRate(...) you can see how it works, the forwarding curve is extracted from the ibor index and then the zerbond method (eventually calling the code you copied again) is used together with this curve to estimate the forward rate.

Only in case, no "better" discounting or forwarding curve is known (i.e. no curve is attached to an interest rate index or no discounting curve is explicitly given in a pricing engine), we fall back on the model curve.

So basically you have to make sure, that appropriate curves are attached to ibor and swap indices relevant for pricing and an appropriate discounting curve is specified in the pricing engine. Or if no curve is attached to an index or given in the pricing engine, the model curve should be appropriate to take over.

This way you can do quite complex things, like estimating a CMS coupon on an Euribor 6M forwarding curve with OIS (Eonia) flat discounting while discounting back the flows on Eonia+10bp (because say the collateral account behind has an interest rate of Eonia+10bp) in the float float swaption engine (well, let's not discuss if the GSR model is the right model for CMS in the first place, but you get my point ...).

In the Markov functional model the situation is a bit different, because the curve tweaking doesn't work as smoothly as in the GSR case. Actually here the recommendation is to use the "main risk curve" as the default model curve, which usually is the most relevant forwarding curve for the deal (like Euribor 6M for a swaption fix vs. Euribor 6M), and do the static spread adjustment for the other curves relative to this curve (which is then again an automatism in QuantLib).

Does that help?


On 6 January 2016 at 11:43, XU Yuhong <[hidden email]> wrote:

Hi Peter,


This is Xu Yuhong, a quant from UOB bank of Singapore. I am studying the code of one factor Gaussian short rate model in QuantLib, together with your short note on its implementation from SSRN. I am specifically interested in how you deal with multi-curve setup in the calibration.


From the example code, I can see the implementation deals with multi-curves. I was trying to step through the code, but find it is difficult to follow. It seems the forward curve is main object of modelling, while the discounting curve is merely an input and is not associated to any stochastic dynamics. Particularly, I don’t understand the bond reconstruction formula below if discounting curve is provided


const Real Gsr::zerobondImpl(const Time T, const Time t, const Real y,

                             const Handle<YieldTermStructure> &yts) const {




    if (t == 0.0)

        return yts.empty() ? this->termStructure()->discount(T, true)

                           : yts->discount(T, true);


    boost::shared_ptr<GsrProcess> p =



    Real x = y * stateProcess_->stdDeviation(0.0, 0.0, t) +

             stateProcess_->expectation(0.0, 0.0, t);

    Real gtT = p->G(t, T, x);


    Real d = yts.empty()

                 ? termStructure()->discount(T, true) /

                       termStructure()->discount(t, true)

                 : yts->discount(T, true) / yts->discount(t, true);


    return d * exp(-x * gtT - 0.5 * p->y(t) * gtT * gtT);



My understanding is that the output of this function is the discounting zero bond from t to T, but  GsrProcess is a description of forward dynamics. How can a forward curve dynamics produce discounting zero bond? Any model assumption between the dynamics of forward curve and discounting curve, eg. constant spread, which leads to the above result in code? Generally I want to know how you deal with multi-curve setup in GSR model.


Your reply on the above questions would be greatly appreciated.  If necessary, we may move the topic to QuantLib user group for large audience. Thank you.










Any person receiving this email and any attachment(s) contained,
shall treat the information as confidential and not misuse, copy,
disclose, distribute or retain the information in any way that
amounts to a breach of confidentiality. If you are not the intended
recipient, please delete all copies of this email from your computer
system. As the integrity of this message cannot be guaranteed,
neither UOB nor any entity in the UOB Group shall be responsible for
the contents. Any opinion in this email may not necessarily represent
the opinion of UOB or any entity in the UOB Group.


QuantLib-dev mailing list
[hidden email]