|
From: Abhishek K. <kan...@gm...> - 2018-07-30 07:49:06
|
HI Peter,
Thank you for your response.
I set telescopicValueDates to true, which sped up things considerably :)
Thank you again.
Could you let me know what telescopicValueDates does?
Best,
sonderak
On Fri, Jul 27, 2018 at 9:35 PM, Peter Caspers <pca...@gm...>
wrote:
> Hi Sonderak,
>
> 1. that’s because it creates a schedule with lots of dates; this is not
> really necessary for the purpose of curve bootstrapping and you can avoid
> it by setting the parameter telescopicValueDates to true which will speed
> up things (without changing the resulting curve of course)
>
> 2. I don’t think so; the rate helper will be rebuild the next time the
> curve building is triggered and that will be time consuming again for the
> reason given in 1. - however this is not what you are observing, right, so
> I don’t know; does that observation persist with telescopicValueDates set
> to true?
>
> Best Regards
> Peter
>
> On 27 Jul 2018, at 11:17, Abhishek KANNUR <kan...@gm...> wrote:
>
> Hello,
> I have been working on valuation of interest rate swaps using dual curve
> bootstrapping. And for this I use OISRateHelper to create a discount term
> structure using OIS rates. The entire code below :
>
> import QuantLib as ql
>> ql.IndexManager.instance().clearHistories()
>> import math
>> import numpy as np
>> import pandas as pd
>> import datetime as dt
>> #### INPUTS
>> date0 = dt.datetime.strptime("2012-07-05", "%Y-%m-%d")
>> date1 = dt.datetime.strptime("2012-07-06", "%Y-%m-%d")
>> calculation_dates = [ql.Date(date0.day,date0.month,date0.year),
>> ql.Date(date1.day,date1.month,date1.year)]
>> fwd_start = 0
>> ois_mat = [ql.Period(x) for x in ['1D', '2W', '1M', '2M', '3M', '4M',
>> '5M', '6M',
>> '7M', '8M', '9M', '10M', '11M', '12M',
>> '18M', '2Y',
>> '30M', '3Y', '4Y', '5Y', '6Y', '7Y',
>> '8Y', '9Y', '10Y',
>> '11Y', '12Y', '15Y', '20Y', '25Y',
>> '30Y', '35Y', '40Y',
>> '50Y']]
>> ois_rates0 = [0.331, 0.162, 0.1525, 0.138, 0.136, 0.134, 0.133, 0.132,
>> 0.135, 0.133, 0.134, 0.133, 0.134, 0.135, 0.146, 0.168, 0.197, 0.263,
>> 0.419, 0.622, 0.8364, 1.006, 1.1625, 1.302, 1.429, 1.544, 1.64, 1.839,
>> 1.93, 1.964, 1.999, 2.0465, 2.097, 2.1675]
>> ois_rates1 = [0.329, 0.145, 0.134, 0.129, 0.13, 0.1235, 0.125, 0.145,
>> 0.126, 0.12, 0.127, 0.122, 0.123, 0.125, 0.141, 0.165, 0.192, 0.253, 0.402,
>> 0.595, 0.795, 0.976, 1.131, 1.27, 1.4049, 1.517, 1.611, 1.811, 1.901, 1.94,
>> 1.963, 2.0265, 2.091, 2.173]
>> ois_dict0 = dict(zip(ois_mat, [x/100 for x in ois_rates0]))
>> ois_dict1 = dict(zip(ois_mat, [x/100 for x in ois_rates1]))
>> list_ois_rates_dict = [ois_dict0, ois_dict1]
>> deposit_mat = [ql.Period(1, ql.Months), ql.Period(3, ql.Months),
>> ql.Period(6, ql.Months)]#, ql.Period(12, ql.Months)]
>> deposit_rates0 = [0.00362, 0.00641, 0.0092]
>> deposit_rates1 = [0.00255, 0.00549, 0.00831]
>> deposit_dict0 = dict(zip(deposit_mat, deposit_rates0))
>> deposit_dict1 = dict(zip(deposit_mat, deposit_rates1))
>> list_deposit_rates_dict = [deposit_dict0, deposit_dict1]
>> swap_mats = [ql.Period(x, ql.Years) for x in
>> [1,2,3,4,5,6,7,8,9,10,12,15,20,25,30]]
>> swap_rates0 = [0.00515, 0.00806, 0.00883, 0.01029, 0.01213, 0.0139,
>> 0.01544, 0.01677, 0.01793, 0.01897, 0.02073, 0.02232, 0.02279, 0.02293,
>> 0.02307]
>> swap_rates1 = [0.00465, 0.00744, 0.00802, 0.00931, 0.01104, 0.01288,
>> 0.0145, 0.01591, 0.01713, 0.01824, 0.02006, 0.0217, 0.02229, 0.02246,
>> 0.02263]
>> swap_dict0 = dict(zip(swap_mats, swap_rates0))
>> swap_dict1 = dict(zip(swap_mats, swap_rates1))
>> list_swap_curve_rates_dict = [swap_dict0, swap_dict1]
>> libor_rates_dict = deposit_dict0.copy()
>> swap_rates_dict = swap_dict0.copy()
>> swap_libor_tenors = [ql.Period(x, ql.Months) for x in
>> [6,6,6,6,6,6,6,6,6,6,6,6,6,6,6]]
>> settlement_days = 0
>> face_value = 100
>> fixed_day_count = ql.Thirty360()
>> float_day_count = ql.Actual360()
>> ois_day_count = ql.Actual360()
>> calendar = ql.TARGET()
>> list_fixed_coupon_frequency = [ql.Annual for x in
>> range(len(swap_libor_tenors))]
>> currency = ql.EURCurrency()
>> spread = 0
>> business_convention = ql.ModifiedFollowing
>> date_generation = ql.DateGeneration.Forward
>> end_of_month = False
>>
>>
>>
>> ### CALCULATIONS
>> fixed_npv = []
>> float_npv = []
>> swap_npv = []
>> swap_fair_rate = []
>> ql.IndexManager.instance().clearHistories()
>> date_t0 = calculation_dates[0]
>> ql.Settings.instance().evaluationDate = date_t0
>> effective_start_date = calendar.advance(date_t0, settlement_days +
>> fwd_start, ql.Days)
>> discount_term_structure = ql.RelinkableYieldTermStructureHandle()
>> forecast_term_structure = ql.RelinkableYieldTermStructureHandle()
>> oindex = ql.OvernightIndex("", settlement_days, currency, calendar,
>> ois_day_count, discount_term_structure)
>> ######################
>> t5 = dt.datetime.now()
>> ######################
>> ois_quote_map = {}
>> ois_helpers_t0 = []
>> for r,m in zip(list_ois_rates_dict[0].values(),
>> list_ois_rates_dict[0].keys()):
>> quote = ql.SimpleQuote(r)
>> helper= ql.OISRateHelper(settlement_days, m, ql.QuoteHandle(quote),
>> oindex)
>> ois_helpers_t0.append(helper)
>> ois_quote_map[m]=quote
>> ######################
>> t6 = dt.datetime.now()
>> ######################
>> deposit_quote_map = {}
>> deposit_helpers_t0 = []
>> for r,m in zip(list_deposit_rates_dict[0].values(),
>> list_deposit_rates_dict[0].keys()):
>> quote = ql.SimpleQuote(r)
>> helper = ql.DepositRateHelper(ql.QuoteHandle(quote),m,settlement_
>> days,calendar,
>> business_convention,end_of_mon
>> th,float_day_count)
>> deposit_helpers_t0.append(helper)
>> deposit_quote_map[m] = quote
>> swap_ibor_indices = [ ql.IborIndex("", x, settlement_days, currency,
>> calendar, business_convention, False, float_day_count,
>> forecast_term_structure) for x in
>> swap_libor_tenors]
>> for sib in swap_ibor_indices:
>> sib.addFixing(date_t0, libor_rates_dict[sib.tenor()])
>>
>> swap_quote_map = {}
>> swap_helpers_t0 = []
>> for r,m, ibor_index,f in zip(list_swap_curve_rates_dict[0].values(),
>> list_swap_curve_rates_dict[0].keys(),
>> swap_ibor_indices,
>> list_fixed_coupon_frequency):
>> quote = ql.SimpleQuote(r)
>> helper = ql.SwapRateHelper(ql.QuoteHandle(quote),m,calendar,f,
>> business_convention,fixed_day_count, ibor_index,
>> ql.QuoteHandle(ql.SimpleQuote(0)),ql.Period(0,
>> ql.Days), discount_term_structure,
>> settlement_days)
>> swap_helpers_t0.append(helper)
>> swap_quote_map[m] = quote
>> ######################
>> t10 = dt.datetime.now()
>> ######################
>>
>> helpers_t0 = deposit_helpers_t0 + swap_helpers_t0
>> swap_curve_t0 = ql.PiecewiseLogCubicDiscount(settlement_days, calendar,
>> helpers_t0, fixed_day_count)
>> discount_curve_t0 = ql.PiecewiseLogCubicDiscount(settlement_days,
>> calendar, ois_helpers_t0, fixed_day_count)
>> swap_curve_t0.enableExtrapolation()
>> discount_curve_t0.enableExtrapolation()
>> discount_term_structure.linkTo(discount_curve_t0)
>> forecast_term_structure.linkTo(swap_curve_t0)
>> swap_engine = ql.DiscountingSwapEngine(discount_term_structure)
>> list_irs = []
>> for i in range(len(swap_mats)):
>> swap_rate = list(swap_rates_dict.values())[i]
>> fixed_tenor = ql.Period(list_fixed_coupon_frequency[i])
>> float_tenor = swap_ibor_indices[i].tenor()
>> fixed_schedule = ql.Schedule(effective_start_date,
>> calendar.advance(effective_start_date, list(swap_rates_dict.keys())[i]),
>> fixed_tenor, calendar,
>> business_convention, business_convention,
>> date_generation, end_of_month)
>> float_schedule = ql.Schedule(effective_start_date,
>> calendar.advance(effective_start_date, list(swap_rates_dict.keys())[i]),
>> float_tenor, calendar,
>> business_convention, business_convention,
>> date_generation, end_of_month)
>> irs_temp = ql.VanillaSwap(ql.VanillaSwap.Receiver, face_value,
>> fixed_schedule, swap_rate, fixed_day_count,
>> float_schedule, swap_ibor_indices[i],
>> spread, float_day_count)
>> irs_temp.setPricingEngine(swap_engine)
>> if fwd_start > 0:
>> fair_swap_rate = irs_temp.fairRate()
>> irs = ql.VanillaSwap(ql.VanillaSwap.Receiver, face_value,
>> fixed_schedule, fair_swap_rate, fixed_day_count,
>> float_schedule, swap_ibor_indices[i],
>> spread, float_day_count)
>> irs.setPricingEngine(swap_engine)
>> list_irs.append(irs)
>> else:
>> list_irs.append(irs_temp)
>>
>>
>> fixed_npv.append([x.fixedLegNPV() for x in list_irs])
>> float_npv.append([x.floatingLegNPV() for x in list_irs])
>> swap_npv.append([x.NPV() for x in list_irs])
>> swap_fair_rate.append([x.fairRate() for x in list_irs])
>>
>>
>> print("ois helpers on date0: " + str((t6 - t5)))
>> print("other helpers on date0: " + str((t10 - t6)))
>>
>> ######################
>> t19 = dt.datetime.now()
>> ######################
>> tdelta = dt.timedelta()
>> if len(calculation_dates) > 1:
>> for i in range(1, len(calculation_dates)):
>> ######################
>> t19_1 = dt.datetime.now()
>> ######################
>> date_ti = calculation_dates[i]
>> ql.Settings.instance().evaluationDate = date_ti
>> ######################
>> t19_2 = dt.datetime.now()
>> ######################
>> for k in list_ois_rates_dict[i].keys():
>> ois_quote_map[k].setValue(list_ois_rates_dict[i][k])
>>
>> for k in list_deposit_rates_dict[i].keys():
>> deposit_quote_map[k].setValue(list_deposit_rates_dict[i][k])
>> for k in list_swap_curve_rates_dict[i].keys():
>> swap_quote_map[k].setValue(list_swap_curve_rates_dict[i][k])
>> fixed_npv.append([x.fixedLegNPV() for x in list_irs])
>> float_npv.append([x.floatingLegNPV() for x in list_irs])
>> swap_npv.append([x.NPV() for x in list_irs])
>> swap_fair_rate.append([x.fairRate() for x in list_irs])
>>
>> ######################
>> tdelta = tdelta + (t19_2 - t19_1)
>> ######################
>> ######################
>> t20 = dt.datetime.now()
>> ######################
>> print("Calculations for other dates: " + str((t20 - t19)))
>> print("Setting evaluation dates for other dates: " + str(tdelta))
>
>
>
> I have calculated execution time for creating an instance of
> OISRateHelpers and compared them to execution time for creating instances
> of DepositRateHelpers and SwapRateHelpers.
>
> ois helpers on date0: 0:00:00.299389
>> other helpers on date0: 0:00:00.000999
>
>
> The output shows that there is a major difference between.
>
> Also, when recalculating the swaps, on other dates (other than date0),
> it's the ql.Settings.instance().evaluationDate which takes up more time.
>
> Calculations for other dates: 0:00:09.596271
>> Setting evaluation dates for other dates: 0:00:09.554356
>
>
> From this thread
> <https://quant.stackexchange.com/questions/39671/why-we-should-specify-the-evaluation-date-when-using-quantlib-yield-curve-and-w/40158>,
> I have come to understand that setting new dates changes reference dates
> for all the instances declared before.
>
> I am trying to understand :
>
> 1. Why creating instances of OISRateHelpers takes longer than creating
> instances of SwapRateHelpers/DepositRateHelpers?
>
> 2. The fact that changing evaluation dates is time consuming, is it
> possible that OISRateHelper is creating 'redundant' dependencies which
> require notifications for changes in evaluation dates as well? Thus making
> it time consuming when resetting evaluation dates in ql.Settings?
>
> Thank you!
>
> PS: I have posted this question on Quant.StackExchange.com
> <https://quant.stackexchange.com/questions/40939/quantlib-in-python-execution-time-with-oisratehelper-compared-to-swap-deposit>
> <http:/> as well.
>
>
> Best,
> Sonderak
>
> ------------------------------------------------------------
> ------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, Slashdot.org <http://slashdot.org>!
> http://sdm.link/slashdot_______________________________________________
> QuantLib-users mailing list
> Qua...@li...
> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>
>
>
|