|
From: Shaun V. <svi...@ve...> - 2023-01-04 18:39:20
|
Thank you for the explanation here. Is there a simple way to push the settlement date out on an existing swap once created? Or would I need to create an additional swap?
From: Arkadiy Naumov <ark...@gm...>
Sent: Monday, December 19, 2022 10:57 PM
To: Shaun Viguerie <svi...@ve...>
Cc: qua...@li...
Subject: Re: [Quantlib-users] Aging a swap without changing the curve producing unexpected results
This Message originated outside your organization.
________________________________
Hi Shaun,
From what I can see in the script, you've moved your evaluation date forward, but kept swap settlement the same, so your forward rates that drive floating leg cash flows are now different. Before it was a series of 3M forwards starting 1Y out, and now it's forwards starting 345 days out. In order to keep the cash flows unchanged, you'd need to account for the 20-days "roll" down the curve or push the settlement out.
On Mon, Dec 19, 2022 at 6:14 PM Shaun Viguerie <svi...@ve...<mailto:svi...@ve...>> wrote:
Hi All,
First, I want to thank Luigi & the community for all of the work on QuantLib. I’m a new user so apologies if my question is stupid…
I’ve been trying to get a feel for the mechanics of library—specifically around TermStructures and Interest Rate Swaps. In doing so, I wanted to test a base case:
* Create a simple YieldCurve instance using a 3M Short Rate future + 1Y-10Y Swap Rates
* Create a VanillaSwap on top of this structure
* Evaluate the NPV of this swap & examine the cashflows
* Advance the calendar 10 days [without changing the curve at all]
* Evaluate the NPV of the swap & examine the cashflows]
In the above experiment, given that I am not changing the curve, I would expect the cashflows to remain the same [while the NPVs would change]. However, I am unable get this working, despite running through several tutorials online (DIMA’s slides, a couple of Luigi’s videos). I have gleaned that this might have something to do with adding fixing days to the indices? But I’m not sure I understand the mechanics of why that would be or how I should think about managing fixings as I advance time in the library.
I’m happy to provide more information…. A messy version of the code is attached below:
import pandas as pd
import QuantLib as ql
from QuantLib import *
def show_cashflows(leg):
for c in leg:
print ('%20s | %s | %.4f%%' % (c.date(), c.amount(),
as_coupon(c).rate()*100))
calendar = TARGET()
tddt = pd.to_datetime('today').date()
todaysDate = ql.Date(tddt.day, tddt.month, tddt.year)
Settings.instance().evaluationDate = todaysDate
settlementDate = calendar.advance(todaysDate, 12, ql.Months)
# market quotes
deposits = { (3,Months): 0.047245}
swaps = {
(1,Years): 0.05876,
(2,Years): 0.045986,
(4,Years): 0.038589,
(5,Years): 0.036954,
(6,Years): 0.035925,
(7,Years): 0.0352,
(8,Years): 0.034683,
(9,Years): 0.03437,
(10,Years): .034186
}
# convert them 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) ]]
swapHelpers = [ SwapRateHelper(QuoteHandle(swaps[(n,unit)]),
Period(n,unit), calendar,
Annual, Unadjusted,
Actual360(), Euribor6M())
for n, unit in swaps.keys() ]
# term-structure construction
helpers = depositHelpers + swapHelpers
# term structure handles...why do I need both?
discountTermStructure = RelinkableYieldTermStructureHandle()
forecastTermStructure = RelinkableYieldTermStructureHandle()
depoSwapCurve = PiecewiseLogCubicDiscount(settlementDays, TARGET(), helpers, Actual360())
depoSwapCurve.enableExtrapolation()
swapEngine = DiscountingSwapEngine(discountTermStructure)
# 5Y Swap
nominal = 1000000
maturity1 = calendar.advance(settlementDate,5,Years)
fixedRate = 0.036954
spread = 0.0
index = ql.USDLibor(ql.Period(3, ql.Months), forecastTermStructure)
floatingLegAdjustment = ModifiedFollowing
floatingLegDayCounter = index.dayCounter()
fixedSchedule1 = Schedule(settlementDate, maturity1,
Period(1, Years), calendar,
Unadjusted, Unadjusted,
DateGeneration.Forward, False)
floatingSchedule1 = Schedule(settlementDate, maturity1,
Period(6,Months), calendar,
ModifiedFollowing, ModifiedFollowing,
DateGeneration.Forward, False)
# when I create the swap using this method, the cashflows remain fixed upon advancing the day
spot1 = VanillaSwap(VanillaSwap.Receiver, nominal,
fixedSchedule1, fixedRate, Actual360(),
floatingSchedule1, index, spread,
floatingLegDayCounter)
spot1.setPricingEngine(swapEngine)
discountTermStructure.linkTo(depoSwapCurve)
forecastTermStructure.linkTo(depoSwapCurve)
Settings.instance().evaluationDate = todaysDate
print ('Fair Rate: {}'.format(spot1.fairRate()))
print('NPV: {}'.format(spot1.NPV()))
print('fixed cashflows:')
show_cashflows(spot1.fixedLeg())
print('floating cashflows:')
show_cashflows(spot1.floatingLeg())
## AFTER DOING THIS THE FLOATING CASHFLOWS CHANGE AND I WOULD NOT EXPECT THEM TO
Settings.instance().evaluationDate = calendar.advance(todaysDate, 20, Days)
print (spot1.fairRate())
print(spot1.NPV())
print ('Fair Rate: {}'.format(spot1.fairRate()))
print('NPV: {}'.format(spot1.NPV()))
print('fixed cashflows:')
show_cashflows(spot1.fixedLeg())
print('floating cashflows:')
show_cashflows(spot1.floatingLeg())
_______________________________________________
QuantLib-users mailing list
Qua...@li...<mailto:Qua...@li...>
https://lists.sourceforge.net/lists/listinfo/quantlib-users
|