# Use QuantLib Python to calculate Swap DV01

I would want to use QuantLib Python to calculate DV01 of an interest rate swap.

Initially I was thinking of calculating the fixed leg DV01 and floating leg DV01 separately, then add both legs DV01 together to get the swap DV01. However, I don't know how to calculate the floating leg DV01 using QuantLib Python.

In the end I took a different approach to calculate interest rate swap DV01 using the following code:

from QuantLib import *

# global data
calendar = TARGET()
todaysDate = Date(6,November,2001);
Settings.instance().evaluationDate = todaysDate
settlementDate = Date(8,November,2001);

# market quotes
deposits = { (1,Weeks): 0.0382,
(1,Months): 0.0372,
(3,Months): 0.0363,
(6,Months): 0.0353,
(9,Months): 0.0348,
(1,Years): 0.0345 }

swaps = { (2,Years): 0.037125,
(3,Years): 0.0398,
(5,Years): 0.0443,
(10,Years): 0.05165,
(15,Years): 0.055175 }

# 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 [(1,Weeks),(1,Months),(3,Months),
(6,Months),(9,Months),(1,Years)] ]

fixedLegFrequency = Annual
fixedLegTenor = Period(1,Years)
fixedLegDayCounter = Thirty360()
floatingLegFrequency = Semiannual
floatingLegTenor = Period(6,Months)
swapHelpers = [ SwapRateHelper(QuoteHandle(swaps[(n,unit)]),
Period(n,unit), calendar,
fixedLegDayCounter, Euribor6M())
for n, unit in swaps.keys() ]

# term structure handles

# term-structure construction

helpers = depositHelpers + swapHelpers
depoSwapCurve = PiecewiseFlatForward(settlementDate, helpers, Actual360())

swapEngine = DiscountingSwapEngine(discountTermStructure)

# 5Y Swap

nominal = 1000000

fixedLegFrequency = Annual
fixedLegDayCounter = Thirty360()
fixedRate = 0.04

floatingLegFrequency = Semiannual
fixingDays = 2
index = Euribor6M(forecastTermStructure)
floatingLegDayCounter = index.dayCounter()

fixedSchedule = Schedule(settlementDate, maturity,
fixedLegTenor, calendar,
DateGeneration.Forward, False)
floatingSchedule = Schedule(settlementDate, maturity,
floatingLegTenor, calendar,
DateGeneration.Forward, False)

fixedSchedule, fixedRate, fixedLegDayCounter,
floatingLegDayCounter)
swap.setPricingEngine(swapEngine)

print('Fixed Leg DV01')
print(swap.fixedLegBPS())

shift = 0.0001

temp_fyc_handle = YieldTermStructureHandle(depoSwapCurve)
temp_dyc_handle = YieldTermStructureHandle(depoSwapCurve)
P_p = swap.NPV()

temp_fyc_handle = YieldTermStructureHandle(depoSwapCurve)
temp_dyc_handle = YieldTermStructureHandle(depoSwapCurve)
P_m = swap.NPV()

dv01 = (P_m - P_p) / 2.0
print('Swap DV01')
print(dv01)


Am I correct in how to use QuantLib Python to calculate interest rate swap DV01? The output of the code above shows that the fixed leg DV01 is smaller than the entire swap's DV01. Is that right?

No, I'm afraid you're comparing apples with oranges. Your calculation of the DV01 of the swap is correct (with a caveat, see below), but the figure returned from swap.fixedLegBPS is not comparable.

The DV01 tells you what happens to the NPV if the interest-rate curve change; in the case of the fixed leg, this affects the discount factors used to discount the coupon amounts, but not the amounts themselves which are fixed.

The BPS tells you what happens to the NPV if the rate of the fixed coupons increases by 1 bps and the interest rates (and thus the discount factors) stay the same. It's useful to calculate the fair rate, or while you're defining the deal, but probably not so much once the swap is built and its rate is fixed. So: different things.

If you want to calculate the DV01 of the fixed leg alone, you can do something like:

shift = 0.0001

temp_dyc_handle = YieldTermStructureHandle(depoSwapCurve)
P_p = CashFlows.npv(swap.fixedLeg(), discountTermStructure, False, settlementDate)

temp_dyc_handle = YieldTermStructureHandle(depoSwapCurve)
P_m = CashFlows.npv(swap.fixedLeg(), discountTermStructure, False, settlementDate)

dv01 = (P_m - P_p) / 2.0
print('Fixed Leg DV01')
print(dv01)


About the caveat I mentioned above: you're doing

discountTermStructure.linkTo(depoSwapCurve)