|
From: Arkadiy N. <ark...@gm...> - 2022-12-20 03:57:40
|
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...>
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...
> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>
|