import pandas as pd import numpy as np import QuantLib as ql import datetime as dt calendar = ql.SouthAfrica() bussiness_convention = ql.Following day_count = ql.Actual365Fixed() interpolation = ql.Linear() compounding = ql.Compounded compoundingFrequency = ql.Annual calc_date = ql.Date(18, 9, 2015) curve_date = dt.datetime(2015,9,18) today = calc_date#ql.Date(8,ql.October, 2014) #ql.Settings.instance().evaluationDate = calc_date def to_datetime(d): return dt.datetime(d.year(),d.month(), d.dayOfMonth()) #the data from predefined curve curve_data=pd.DataFrame(np.array([(0L, 1442534400000000000L, 1L, 0.05968943361108825, 'DAY', 1L), (1L, 1442534400000000000L, 3L, 0.06008360555190584, 'DAY', 3L), (2L, 1442534400000000000L, 7L, 0.061003962665558964, 'WEEK', 1L), (3L, 1442534400000000000L, 14L, 0.061629138095260494, 'WEEK', 2L), (4L, 1442534400000000000L, 21L, 0.06246539834717324, 'WEEK', 3L), (5L, 1442534400000000000L, 30L, 0.063080497435273, 'MONTH', 1L), (6L, 1442534400000000000L, 61L, 0.0640837249655406, 'MONTH', 2L), (7L, 1442534400000000000L, 91L, 0.06458932758091618, 'MONTH', 3L), (8L, 1442534400000000000L, 122L, 0.06460602877745236, 'MONTH', 4L), (9L, 1442534400000000000L, 153L, 0.06490097928752325, 'MONTH', 5L), (10L, 1442534400000000000L, 182L, 0.06562196294577327, 'MONTH', 6L), (11L, 1442534400000000000L, 213L, 0.06559317254771013, 'MONTH', 7L), (12L, 1442534400000000000L, 243L, 0.06615484763684432, 'MONTH', 8L), (13L, 1442534400000000000L, 274L, 0.06687832021278495, 'MONTH', 9L), (14L, 1442534400000000000L, 304L, 0.06683739890814766, 'MONTH', 10L), (15L, 1442534400000000000L, 335L, 0.06722706850014037, 'MONTH', 11L), (16L, 1442534400000000000L, 366L, 0.06799498188697228, 'MONTH', 12L), (17L, 1442534400000000000L, 457L, 0.06903328142506937, 'MONTH', 15L), (18L, 1442534400000000000L, 547L, 0.07012859614243028, 'MONTH', 18L), (19L, 1442534400000000000L, 639L, 0.0711421402251855, 'MONTH', 21L), (20L, 1442534400000000000L, 731L, 0.07215610320058774, 'MONTH', 24L), (21L, 1442534400000000000L, 822L, 0.07306913034489537, 'MONTH', 27L), (22L, 1442534400000000000L, 912L, 0.07390974864236854, 'MONTH', 30L), (23L, 1442534400000000000L, 1004L, 0.0746912071699184, 'MONTH', 33L), (24L, 1442534400000000000L, 1096L, 0.07543012070847732, 'MONTH', 36L), (25L, 1442534400000000000L, 1187L, 0.07612842034647893, 'MONTH', 39L), (26L, 1442534400000000000L, 1277L, 0.07679447188377297, 'MONTH', 42L), (27L, 1442534400000000000L, 1369L, 0.07744248361696626, 'MONTH', 45L), (28L, 1442534400000000000L, 1461L, 0.07805149575772585, 'MONTH', 48L), (29L, 1442534400000000000L, 1552L, 0.07862397558955214, 'MONTH', 51L), (30L, 1442534400000000000L, 1643L, 0.07917584728234361, 'MONTH', 54L), (31L, 1442534400000000000L, 1735L, 0.079709603821418, 'MONTH', 57L), (32L, 1442534400000000000L, 1827L, 0.08021643040257698, 'MONTH', 60L), (33L, 1442534400000000000L, 1918L, 0.08069118300778322, 'MONTH', 63L), (34L, 1442534400000000000L, 2008L, 0.08114184287539494, 'MONTH', 66L), (35L, 1442534400000000000L, 2100L, 0.08159085035229752, 'MONTH', 69L), (36L, 1442534400000000000L, 2192L, 0.08204424485907724, 'MONTH', 72L), (37L, 1442534400000000000L, 2283L, 0.08249064630693725, 'MONTH', 75L), (38L, 1442534400000000000L, 2373L, 0.08292334366174559, 'MONTH', 78L), (39L, 1442534400000000000L, 2465L, 0.08336529417751093, 'MONTH', 81L), (40L, 1442534400000000000L, 2557L, 0.0837551643848149, 'MONTH', 84L), (41L, 1442534400000000000L, 2648L, 0.08409983640404173, 'MONTH', 87L), (42L, 1442534400000000000L, 2738L, 0.08441573153982995, 'MONTH', 90L), (43L, 1442534400000000000L, 2830L, 0.08472115832909055, 'MONTH', 93L), (44L, 1442534400000000000L, 2922L, 0.08503216237171274, 'MONTH', 96L), (45L, 1442534400000000000L, 3013L, 0.08535856504021955, 'MONTH', 99L), (46L, 1442534400000000000L, 3104L, 0.08568946114081943, 'MONTH', 102L), (47L, 1442534400000000000L, 3196L, 0.08601312798025784, 'MONTH', 105L), (48L, 1442534400000000000L, 3288L, 0.08631201206897576, 'MONTH', 108L), (49L, 1442534400000000000L, 3379L, 0.08657921856932438, 'MONTH', 111L), (50L, 1442534400000000000L, 3469L, 0.08682568429113857, 'MONTH', 114L)], dtype=[('index', '<i8'), ('valDate', '<M8[ns]'), ('tDays', '<i8'), ('SWAP', '<f8'), ('Period', 'O'), ('Periods', '<i8')])) #We must make QuantLib date objects dicPeriod={'DAY':ql.Days,'WEEK':ql.Weeks,'MONTH':ql.Months,'YEAR':ql.Years} curve_data['qlvalDate']= curve_data.apply(lambda row :ql.DateParser.parseISO(pd.to_datetime(row['valDate']).strftime('%Y-%m-%d')),axis=1) curve_data['qlQuote']= curve_data.apply(lambda row :ql.SimpleQuote(row['SWAP']),axis=1) curve_data['qlDate']=curve_data.apply(lambda row :row['qlvalDate'] + ql.Period(int(row['Periods']),dicPeriod[row['Period']]),axis=1) curve_data['Date']=curve_data.apply(lambda row :to_datetime(row['qlDate']),axis=1) #Create Curve as a QuantLib object zc = ql.ZeroCurve(curve_data.qlDate.values,curve_data.SWAP.values,ql.Actual365Fixed(),calendar, interpolation,compounding, compoundingFrequency) # write back into the dataframe curve_data['qlRates']=zc.zeroRates()
curve_data.set_index('Date')[['SWAP','qlRates']].plot()
The Plot
We can see that the QuantLib curve is below our input curve as it is a continuous rate. We can check this by running the following code, and we now see that they are the same.
curve_data['qlRates']=(np.exp(curve_data.qlRates)-1) curve_data.set_index('Date')[['SWAP','qlRates']].plot()
Final Plot