• C++ Programming for Financial Engineering
    Highly recommended by thousands of MFE students. Covers essential C++ topics with applications to financial engineering.
    Python for Finance with Intro to Data Science
    Gain practical understanding of Python to read, understand, and write professional Python code for your first day on the job. Coming soon.
    An Intuition-Based Options Primer for FE
    Ideal for entry level positions interviews and graduate studies, specializing in options trading arbitrage and options valuation models.

Moratorium/Delayed Cash Flows for IRS Valuation in QuantLib

Dear All,

I have created a simple IRS swap pricer that values my swap and returns the NPV and irs.fairRate() using existing code from other QuantLib users.

The code works fine. A problem arises when I have a special cash in which a swap contract is entered into today but cash flows do not occur for a given period(moratorium). In my special case the first cash flow is after 18 months.

Below the code:

from QuantLib import *
#globals
nominal = 1000000
calendar = UnitedStates()
todayDate = Date(5, June, 2020)
settlementDate = calendar.advance(todayDate, 2, Days)
Settings.instance().evaluationDate = todayDate
maturity_date = calendar.advance(todayDate, 5, Years)
#market quotes
deposits = { (3,Months): 0.003129,
(6,Months): 0.004813,
(1,Years): 0.00634 }
swaps = { (2,Years): 0.00288,
(3,Years): 0.00333,
(4,Years): 0.00409,
(5,Years): 0.00498,
(10, Years): 0.00864}
#convert to Quote objects
for n,unit in deposits.keys():
deposits[(n,unit)] = SimpleQuote(deposits[(n,unit)])
for n,unit in swaps.keys():
swaps[(n,unit)] = SimpleQuote(swaps[(n,unit)])
# build rate helpers
dayCounter = Actual360()
settlementDays = 2
depositHelpers = [ DepositRateHelper(QuoteHandle(deposits[(n,unit)]),
Period(n,unit), settlementDays,
calendar, ModifiedFollowing,
False, dayCounter)
for n, unit in [(3,Months),(6,Months),(1,Years)] ]
fixedLegFrequency = Quarterly
fixedLegTenor = Period(3,Months)
fixedLegAdjustment = Unadjusted
fixedLegDayCounter = Actual360()
floatingLegFrequency = Quarterly
floatingLegTenor = Period(3,Months)
floatingLegAdjustment = ModifiedFollowing
swapHelpers = [ SwapRateHelper(QuoteHandle(swaps[(n,unit)]),
Period(n,unit), calendar,
fixedLegFrequency, fixedLegAdjustment,
fixedLegDayCounter, Euribor3M())
for n, unit in swaps.keys() ]
# term structure handles
discountTermStructure = RelinkableYieldTermStructureHandle()
forecastTermStructure = RelinkableYieldTermStructureHandle()
# term-structure construction
helpers = depositHelpers + swapHelpers
depoFutureSwapCurve = PiecewiseFlatForward(settlementDate, helpers, Actual360())
swapEngine = DiscountingSwapEngine(discountTermStructure)
#Swap pricer
fixedLegFrequency = Quarterly
fixedLegAdjustment = Unadjusted
fixedLegDayCounter = Actual360()
fixedRate = 0.004972128760695568
floatingLegFrequency = Quarterly
spread = 0
fixingDays = 0
index = Euribor3M(forecastTermStructure)
floatingLegAdjustment = ModifiedFollowing
floatingLegDayCounter = Actual360()
fixedSchedule = Schedule(settlementDate, maturity_date,
fixedLegTenor, calendar,
fixedLegAdjustment, fixedLegAdjustment,
DateGeneration.Forward, False)
floatingSchedule = Schedule(settlementDate, maturity_date,
floatingLegTenor, calendar,
floatingLegAdjustment, floatingLegAdjustment,
DateGeneration.Forward, False)
irs = VanillaSwap(VanillaSwap.Payer, nominal,
fixedSchedule, fixedRate, fixedLegDayCounter,
floatingSchedule, index, spread,
floatingLegDayCounter)
irs.setPricingEngine(swapEngine)

discountTermStructure.linkTo(depoFutureSwapCurve)
forecastTermStructure.linkTo(depoFutureSwapCurve)
print(depoFutureSwapCurve.dates())
for c in depoFutureSwapCurve.dates():
print(depoFutureSwapCurve.discount(c))
print(" IRS NPV :", irs.NPV())
for i, cf in enumerate(irs.leg(0)):
print("%2d %-18s %10.2f"%(i+1, cf.date(), cf.amount()))
print('-------------')
for i, cf in enumerate(irs.leg(1)):
print("%2d %-18s %10.2f"%(i+1, cf.date(), cf.amount()))
print(" IRS FAIR RATE", irs.fairRate())



As you can see in the above code, I have taken the settlement date to be 2 days after the evaluation date. I tweaked this date and instead put:
settlementDate = calendar.advance(todayDate, 18, Months),
To reflect that the first payment would be after 18 months but received the following error:

RuntimeError: 1st iteration: failed at 1st alive instrument, pillar June 9th, 2022, maturity June 9th, 2022, reference date December 6th, 2021: 2nd leg: negative time (-0.244444) given


I want to know where my thinking is wrong and whether it is possible to include a moratorium function as well in my IRS valuation.

Thank You,
Best,
Goutham
 
Top