I use quantlib to bootstrap yield curve from deposit rate, future price and swap rate. But after I get curve, the date in curve.nodes() doesn't match the date of swap.

Here is the code:

ql.Settings.instance().evaluationDate = calc_date
calendar = ql.UnitedStates()
settlementDays = 2
buss_convention = ql.ModifiedFollowing
mkt_data = pd.read_csv('mkt_data.csv')
depo_rate = mkt_data.iloc[:9,:]
future_rate = mkt_data.iloc[9:17,:]
swap_rate = mkt_data.iloc[17:,:]
depo_rate.iloc[0,0] = '1D'
depo_rate.iloc[1,0] = '1D'
depo_rate.iloc[2,0] = '1D'

depo_rate['Rate'] = depo_rate['Rate']*0.01
swap_rate['Rate'] = swap_rate['Rate']*0.01

settle_time = [ql.Date(17,6,2020), ql.Date(16,9,2020),ql.Date(16,12,2020),ql.Date(17,3,2021),ql.Date(16,6,2021),\
future_rate.loc[:,'Tenor'] = settle_time

for i in [depo_rate,future_rate,swap_rate]:
   i['Rate'] = i['Rate'].apply(ql.SimpleQuote)
depo_dayCounter = ql.Actual360()

depositHelpers = []
depositHelpers.append(ql.DepositRateHelper(ql.QuoteHandle(depo_rate.loc[0,'Rate']),ql.Period(depo_rate.loc[0,'Tenor']), \
                                          0,calendar, buss_convention,False, depo_dayCounter))
depositHelpers.append(ql.DepositRateHelper(ql.QuoteHandle(depo_rate.loc[1,'Rate']),ql.Period(depo_rate.loc[1,'Tenor']), \
                                          1,calendar, buss_convention,False, depo_dayCounter))
depositHelpers.append(ql.DepositRateHelper(ql.QuoteHandle(depo_rate.loc[2,'Rate']),ql.Period(depo_rate.loc[2,'Tenor']), \
                                          2,calendar, buss_convention,False, depo_dayCounter))
depositHelpers = depositHelpers + [ql.DepositRateHelper(ql.QuoteHandle(depo_rate.loc[i,'Rate']),ql.Period(depo_rate.loc[i,'Tenor']), \
                                          settlementDays,calendar, buss_convention,False, depo_dayCounter) for i in range(3,len(depo_rate))]

future_dayCounter = ql.Actual360()
months = 3
futuresHelpers = [ ql.FuturesRateHelper(ql.QuoteHandle(row['Rate']),
                                    row['Tenor'], months,
                                    calendar, buss_convention,
                                    True, future_dayCounter,
                  for _,row in future_rate.iterrows() ]

fixedLegFrequency = ql.Semiannual
fixedLegDayCounter = ql.Thirty360()
fixedLegAdjustment = ql.ModifiedFollowing

swapHelpers = [ ql.SwapRateHelper(ql.QuoteHandle(row['Rate']),
                              ql.Period(row['Tenor']), calendar,
                              fixedLegFrequency, fixedLegAdjustment,
                              fixedLegDayCounter, ql.USDLibor(ql.Period('3M')))
               for _,row in swap_rate.iterrows() ]

helpers = [depositHelpers[6],depositHelpers[8]] + futuresHelpers + swapHelpers
depoFuturesSwapCurve = ql.PiecewiseLogLinearDiscount(calc_date, helpers,depo_dayCounter)

Here is the node in depoFuturesSwapCurve

((Date(3,4,2020), 1.0),
(Date(7,5,2020), 0.9994808093846632),
(Date(7,7,2020), 0.996613537585222),
(Date(17,9,2020), 0.9939711099817702),
(Date(16,12,2020), 0.9903528102781002),
(Date(16,3,2021), 0.9863826202316677),
(Date(17,6,2021), 0.9821580155124806),
(Date(16,9,2021), 0.9776810270922704),
(Date(15,12,2021), 0.9728854145806802),
(Date(15,3,2022), 0.9676119295645534),
(Date(16,6,2022), 0.9617853248262576),
(Date(11,4,2023), 0.9412966524570305),
(Date(8,4,2024), 0.9120125569930791),
(Date(7,4,2025), 0.8809279129552777),
(Date(7,4,2026), 0.8499139922097416),
(Date(7,4,2027), 0.8191409122567342),
(Date(7,4,2028), 0.7894300580352771),
(Date(9,4,2029), 0.76058975808144),
(Date(8,4,2030), 0.7330282687994317),
(Date(7,4,2032), 0.678916115276019),
(Date(9,4,2035), 0.6059459638985687),
(Date(9,4,2040), 0.5158558171872417),
(Date(11,4,2045), 0.442323362422574),
(Date(7,4,2050), 0.3764502885959702))

Here is the data: enter image description here

I think for 3Y and 25Y swap, the date should be around April 7th. But in my result, the date is April 11th. Why is this happen?


1 Answer 1


You have weekend and holidays so the end date adjusts forward... Check 2023 calendar for United States. You have good Friday and Easter Monday

  • $\begingroup$ The problem (with QuantLib) is that there is no such thing as "U.S. calendar" in reality. It's different for stocks and bonds. It would be better to specify SIFMA or NYSE (Good Friday is a settlement day in one, but not the other). Or just follow Bloomberg calendars. I don't think Easter Monday is a holiday in any U.S. holiday, but it is in London. The holidays for a USD IR swap are usually Londin and US SIFMA. $\endgroup$ Jun 14, 2020 at 18:46
  • $\begingroup$ Thanks for the answer! Calculate date is April 3th, 2020, shouldn’t the end date of the three-year swap be on April 7rd, 2023? It's a Friday $\endgroup$
    – aicer
    Jun 15, 2020 at 8:16
  • $\begingroup$ You can in fact specify the calendar you want.. For example, to get the NYSE, just use ql.UnitedStates(ql.UnitedStates.NYSE) $\endgroup$ Jun 18, 2020 at 11:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.