Bootstrapping with QuantLib

Key words: Interest rates, Day-count basis, Quantlib, Bootstraping, IMM dates, Cash Rate, Eurodollars, Swaps, Interpolation, Curve constraction, Date adjustment, Spot curve, Forward curve, Discounts
QuantLib

In my previous article Continuously compounded linear interpolation of interest rates , I described the procedure of building spot and forward interest rate curves and a bootstrapping as a standard method of constructing the curve. However, bootstraping is not as easy as it seems, especially, when doing it manually in Excel. A lot of details needed to be taken into account:

Day-count conventions
• Interpolation methods
• Calendars
• Compounding methods

These features are realized and available in Quantlib, so I thought it would be nice to use Quantlib to show how bootstrapping can be done.
Our actual results we compare with market quotes. Also, I will provide example of how to derive discounts and forward rates from market instruments by using Quantlib.

Market Data part

A curve we going to deal with represents US-dollar interest rate swaps, YCSW0047 Index in Bloomberg terminal:

• The short end is cash rates with Actual/360 day-count
• In the middle are 6 contiguous 3 month IMM Eurodollar futures
• On the long end of the curve are fixed-rate vs. floating-rate swaps

Fixed rate leg is based on Annual, Act/360 day-count; floating rate leg has quarterly (for instance, the
benchmark floating index for the US swap market is the 3 month LIBOR), Act/360 day-count basis.

The rest of the market data are presented in the “Market Table” below, arranged by the traded instruments into increasing maturity with corresponding conventions.
The quotes in green are derived by using Quantlib and the rest of the article will show how to do this.
As we can see, these quotes can be compared with the column “Spot Rate” to see the difference between the Market and Quantlib.

Bootstrapping interest rate

Setup and Calculation part

1. Interpolation

First of all, we need to take care about an interpolation method, the generation of a complete yield curve from the market data that is available.
In practice, linear and non-linear (regression, spline etc.) are the most common interpolation practices used. We will stay with a simple linear technique.
A list of interpolation types in Quantlib, including two dimensional “bi” types:

• ql/math/interpolations/abcdinterpolation.hpp
• ql/math/interpolations/backwardflatinterpolation.hpp
• ql/math/interpolations/bicubicsplineinterpolation.hpp
• ql/math/interpolations/bilinearinterpolation.hpp
• ql/math/interpolations/convexmonotoneinterpolation.hpp
• ql/math/interpolations/cubicinterpolation.hpp
• ql/math/interpolations/extrapolation.hpp
• ql/math/interpolations/flatextrapolation2d.hpp
• ql/math/interpolations/forwardflatinterpolation.hpp
• ql/math/interpolations/interpolation2d.hpp
• ql/math/interpolations/kernelinterpolation.hpp
• ql/math/interpolations/kernelinterpolation2d.hpp
• ql/math/interpolations/linearinterpolation.hpp
• ql/math/interpolations/loginterpolation.hpp
• ql/math/interpolations/mixedinterpolation.hpp
• ql/math/interpolations/multicubicspline.hpp
• ql/math/interpolations/sabrinterpolation.hpp

2. Method of curve construction

We will use Piecewise yield curve constriction, i.e. we build the curve by using different market instrument.
In our case, these instruments are Cash, ED Futures and Swaps.
Quantlib allows building a yield curve as:
• InterpolatedDiscountCurve (discount factors are taken as input)
• InterpolatedZeroCurve (zero coupon bond rates are taken as input)
• FittedBondDiscountCurve (coupon bond prices are taken as input)
• InterpolatedForwardCurve (forward rates are taken as input)
• PiecewiseYieldCurve (a mixture of market instruments are taken as input)

3. Dates
Before wring the code, we need to know more details about specific dates.

3.1. Our calendar is

Calendar calendar = JointCalendar(UnitedKingdom(UnitedKingdom::Exchange),UnitedStates(UnitedStates::Settlement), JoinHolidays);

3.2 The default Spot date, aka Settlement Date is:

Date settlementDate(18, February, 2015);

3.3 Trade date is 2 days prior to the settlement day:

Date todaysDate = calendar.advance(settlementDate, -fixingDays, Days);

3.4 We need to set up our Trade date in the system for the future valuation:

Settings::instance().evaluationDate() = todaysDate;

Otherwise, you will probably have an error on the next day:

QL_FAIL(io::ordinal(iteration+1) << " iteration: failed at " << io::ordinal(i) << " alive instrument, " "maturity " << errors_[i]->helper()->latestDate()<< ", reference date " << ts_->dates_[0] <<": " << e.what());):

3.5 The function «advance» provides methods for determining whether a date is abusiness day or a holiday for a given market, and for incrementing/decrementing a date of a given number of business days:

Date todaysDate = calendar.advance(settlementDate, -fixingDays, Days);

3.6 Date adjustment are used whenever a transaction date falls on a date that is not a
business day: we use ModifiedFollowing roll convention.

Quantlib provides the following business day conventions:

ISDA

• Following, choose the first business day after the given holiday.
• ModifiedFollowing, choose the first business day after the given holiday unless it belongs to a different month, in which case choose the first business day before the holiday.
• Preceding, choose the first business day before the given holiday.
NONE ISDA

• ModifiedPreceding, choose the first business day before the given holiday unless it belongs to a different month, in which case choose the first business day after the holiday.
• Unadjusted, do not adjust.

3.7 Day-count basis

The last but not the least is Day-count basis that specifies the length of year for which the interest accrues. Quantlib offers the following Day-count conventions:

• ql/time/daycounters/actual360.hpp
• ql/time/daycounters/actual365fixed.hpp
• ql/time/daycounters/actual365nl.hpp
• ql/time/daycounters/actualactual.hpp
• ql/time/daycounters/business252.hpp
• ql/time/daycounters/one.hpp
• ql/time/daycounters/simpledaycounter.hpp
• ql/time/daycounters/thirty360.hpp

By using “dayCount” and “yearFraction” functions, it is possible to construct the other conventions in Quantlib.

4. Quotes set up
Now we are ready to input market quotes take from our previous “Market Table” above.

4.1 Cash Rates

Rate d1wQuote = 0.001375;
Rate d1mQuote = 0.001717;
Rate d2mQuote = 0.002112;
Rate d3mQuote = 0.002581;

Every day at 11:00 am London time, British bankers Association polls various dealers for cash deposit rates that are simple (without compounding) quoted on Act/360 basis. 1W, 1M, 2 M and 3M quotes are used in our bootstrapping process.

4.2 Eurodollars are traded in the International Money Market pit with an implied futures rate 100-price.

Real fut1Quote = 99.725; // 100-99.725=0.2750 is the future rate
Real fut2Quote = 99.585; // 0.4150
Real fut3Quote = 99.385; //0.6150
Real fut4Quote = 99.16; // 0.84
Real fut5Quote = 98.93; // 1.07
Real fut6Quote = 98.715; // 1.285

For simplicity purpose and taking into account the maturities of EDs, I skip convexity adjustment for futures; more details can be found in my article Interest rates: Futures and forward convexity adjustment.

If уou would like to play around with adjustment, you may set up the code this way (0.93% is Market rate volatility):

Rate T = depositDayCounter.yearFraction(settlementDate, imm);
Real convexityQuote= 0.5*0.00937*0.00937*3*T;
boost::shared_ptr&ltQuote> convexity(new SimpleQuote(convexityQuote));
boost::shared_ptr&ltRateHelper> fut5(new FuturesRateHelper(Handle&ltQuote>(fut5Price), imm, futMonths, calendar, ModifiedFollowing, true, depositDayCounter, Handle&ltQuote>(convexity)));

A very useful feature of Quantlib is IMM dates identifying the four quarterly dates of each year which ED contracts use as their scheduled maturity date:

Date imm = IMM::nextDate(settlementDate);

4.3 Par swap rates (a par swap is a swap whose market value today is zero and its par swap rate is the fixed rate of this swap) for the following maturities are used:

Rate s2yQuote = 0.0089268;
Rate s3yQuote = 0.0123343;
Rate s4yQuote = 0.0147985;
Rate s5yQuote = 0.0165843;
Rate s6yQuote = 0.0179191;

We also pay attention to the specification of our swaps as specified in the YCSW0047 Index:

Frequency swFixedLegFrequency = Annual;
BusinessDayConvention swFixedLegConvention = Unadjusted;
DayCounter swFixedLegDayCounter = Actual360();
boost::shared_ptr&ltIborIndex> swFloatingLegIndex(new USDLibor(Period(3, Months)));

5. The collection of interest rates for all different terms is the term structure or simply the curve:

DayCounter termStructureDayCounter = Actual360();
boost::shared_ptr&ltYieldTermStructure> depoFutSwapTermStructure(new PiecewiseYieldCurve&ltDiscount,Linear>(settlementDate, depoFutSwapInstruments, termStructureDayCounter, 1.0e-15));

6. Now we are ready to extract the curve.

6.1 Zero rates by using the function:

depoFutSwapTermStructure->zeroRate(matDate1, depositDayCounter, Simple) << std::endl;

6.2 Discount by using the function:

depoFutSwapTermStructure->discount(matDate14) << std::endl;

6.3 Forward rates by using the function:

depoFutSwapTermStructure->forwardRate(matDate13,matDate14,FutDayCounter,Simple)

The output is the window where:

• The first number is taken in the column “Spot rate” from the “Market Table” with market data in the beginning of the article.

• The second number is our zero rate that we compare with the first number to ensure we received more or less the same results as market quoted.

• Discount rate and forward rate are also computed for the matDate13(19, February, 2019) and matDate14(18, February, 2020) dates.

Bootstrapping IR

One Picture is Worth a Thousand Words:

Spot rate bootstraping

Quantlib code is here


Leave a Reply

Your email address will not be published. Required fields are marked *

22 thoughts on “Bootstrapping with QuantLib

  1. Hi Rafael!
    The market curve I used in my article assumes Linear interpolation and that is why I did Linear in my example to compare both of them. Of cause, there is cubic interpolation in Quantlib but I need market curve to compare my results with the market.

    Longer periods are an easy task, can be added in the same manner as I added swaps points.

    Regards, Alexander )

  2. Hi Alexander,
    thanks for a very entertaining article=)

    Haven\’t you tried to create cubic splined piecewise curve as well, and compare the results of the two? And why not to take longer time span: 5 years seem to be just too short for USD

  3. Joy, EuroDollar future is a 3 month deposit in USD. This is not the same as eur/USD future. Interest rate swap based on Labor USD has the the currency, USD. Use search function to find more about Eurodollar futures on my site

  4. Your article does much good on me. Great thanks!\nI have a question about the currency matter.\nThe second instrument is Eurodollar futures and the third instrument is US dollar interest rate swap. Two instruments are denominated in two different currencies. I know that the curve is constructed based on the traded contracts that reference the same rate whose term structure we want to build. Does the Currency difference matter or is there sth that I missed?\nThank you once more!\n

  5. Hi,Alexander! I have just read your other articles. Sorry I misunderstood the basic concepts about these instruments. Thank you for your timely response! Best regards, Joy

  6. Flora,\nI would like but such projects like Quantlib take too much time. And the main problem is – what is the purpose?

  7. Flora, \nin my opinion you shouldn\’t use Quatlib if you just want to make simple interpolation. Check BBG, there are a lot of curves already available to download.\nBut if you want to do practice with interpolation, it\’s better to start programming from scratch. Use books like Richard Flavell @Swaps and other derivatives\” and Amir Sadr \”Interest rate swaps and their derivatives\”. They might be helpful. Regards

  8. Thank you! Our market data loading interface from Bloomberg is C#, so I want to have the curve interpolation in C# as well. Do you know if we can use SWIG to translate your code in C to C# easily? Thank you!!!!!!\n

  9. Thank you so much!!!! I see! We don\’t want to download from BBG cuz we are trying to import 30 curves with all information on a daily basis, it will crash our database given the amount of data points… I will try program from scratch, thank you!

  10. Can you give me some advice about using Quantlib in Python? I want to create Monte Carlo simulation for two Hull_White processes for correlated short rates.

  11. Andrey,\nUnfortunatelly, I haven\’t used Python at all. I think it is not worth to use Quantlib only for this purpose. May be it is better to write your own code?

  12. As for me, quantlib is a complex library made for serious tasks. And it takes a long time to understand how it works because of complexity. I had a task to analyze and revalue swaps and I find it easier to use BBG. You don\’t need to input a lot of parameters and think about accuracy \’cause BBG has already done it for you. Well, it\’s up to you my friend)

  13. Aleksander, thanks for the answer! I create Monte_Carlo_Simulation for Hull-White process using Python and Quantlib and I want to reuse this tools. New code – it takes long time)))

  14. Андрей, BBG – Bloomberg. Для QuantLib моделей нужны входные данные, в том числе для калибровки и настройки кривых. все это есть в BBG, и если я не ошибаюсь, калькулятор, который ты хочешь сделать на QuantLib. Так вот, проще в BBG все смотреть и прайсить. Но если ты хочешь реализовывать амбициозные задачи в части прайсинга финансовых инструментов, то тогда наверное стоит уделить внимание QuantLib, но это минимум года 2.

  15. Александр, моей задачаей как раз и является разработка механизма для прайсинга опционов. И Quantlib я выбрал как библиотеку, на которой уже много чего реализовано и не нужно уделять много внимания техническим мелочам…Хотя не всегда так получается))\n\nМожете ли Вы порекомендовать наиболее эффективный подход к изучению Quantlidba. Какие-небудь ресурсы или книги? Изучаю его уже где-то пол года, но, в основном, вся информация – примеры решения тех или иных задач и мало структурированного описания. \nСпасибо за помощь и участие))\n\n\n\n\n

  16. Андрей,\nименно по причине того, что QuantLib очень слабо освещен, мало ресурсов и не очень понятно как он будет поддерживаться в будущем, я перестал его изучать. Но в самом начале изучения, все сводилось к чтению кода. \nПоэтому я перешел на BBG, в котором теперь есть специальные возможности написания своего кода и как большой плюс сразу же подкачиваются необходимые рыночные данные, такие как кривые, поверхность волатильности, котировки и т.д.

  17. Александр, а как называется этот инструмент в BBG? Хочу тоже посмотреть, раз рекомендуете

  18. Hi Thierry,
    Look here:http://billiontrader.com/post/97
    and here: http://billiontrader.com/post/157

    Also, use BBG functions to build interest rate curves. You may find some USD curves. They are built using different methods. One of the method is by using futures and another is by using forwards. The diff is convexity adjustment. If I remember correct – there is a box “Convexity adjustment”. You may play with this box to see the difference as well.