Skip to content
All library documents

Building an MXN TIIE Index for Vanilla Swap DV01 in QuantLib

Article Quant Q&A · Author: Pratikgcet

Summary

The document addresses how to construct the floating-rate index for an MXN TIIE vanilla swap when calculating DV01 with QuantLib. The example first defines a TIIE index for rate helpers, then needs a corresponding index linked to the forecast term structure for the swap itself. Reusing a different index, such as a six-month euro interbank index, would not represent the intended MXN floating leg.

The accepted answer says to create the same TIIE index with the forecast curve handle supplied as its term structure. A comment also suggests using a Mexico calendar instead of a null calendar in both index definitions. The example includes curve setup and a parallel-shift valuation approach for DV01, but the response focuses on index construction. It does not validate the market conventions, curve inputs, or numerical result, so those should be checked for the intended MXN contract.

Key ideas

  • The swap's floating index should match the MXN TIIE convention used in the rate helpers.
  • Pass the forecast term structure when constructing the index used by the vanilla swap.
  • A Mexico calendar may be more appropriate than a null calendar, subject to contract conventions.
  • The example estimates DV01 by repricing after shifting forecast and discount curves.

Tags

Full text
# Calculate DV01 for a vanilla swal for MXN index using quantlib


# Calculate DV01 for a vanilla swal for MXN index using quantlib












I am trying to calculate dv01 for a vanilla swap using quantlib. Its a MXN TIIE Swaps for built an index like

```
tiie_index = IborIndex('TIIE', Period(28, Days), 2, MXNCurrency(), NullCalendar(), Following, False, Actual360())
```

which I then pass in the swaphelpers. What I want to know how can I create the similar index for passing to the vanillaswap object. At the moment is Euribor6M(forecastTermStructure) but that doesnt seem right. if I do tiie_index(forecastTermStructure), then it throws an error.

```
index=Euribor6M(forecastTermStructure)
```

```
from QuantLib import *

# global data
calendar = TARGET()
todaysDate = Date(16, April, 2021)
Settings.instance().evaluationDate = todaysDate
settlementDate = Date(20, April, 2021)

# market quotes
deposits = {
    (1, Months): 0.04289,
    (3, Months): 0.04289,
    (6, Months): 0.04345,
    (9, Months): 0.04401,

}

swaps = {
    (1, Years): 0.04506,
    (2, Years): 0.04881,
    (3, Years): 0.05262,
    (4, Years): 0.05575,
    (5, Years): 0.05817,
    (7, Years): 0.06212,
    (10, Years): 0.06639,
    (15, Years): 0.07074,
    (20, Years): 0.07303,
    (30, Years): 0.0741}

# 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, Following,
                                    False, dayCounter)
                  for n, unit in [(1, Months), (3, Months),
                                  (6, Months), (9, Months)]]

fixedLegFrequency = EveryFourthWeek
fixedLegTenor = Period(28, Days)
fixedLegAdjustment = Following
fixedLegDayCounter = Actual360()
floatingLegTenor = Period(28, Days)
floatingLegAdjustment = Following
# create index
tiie_index = IborIndex('TIIE', Period(28, Days), 2, MXNCurrency(), NullCalendar(), Following, False, Actual360())
swapHelpers = [SwapRateHelper(QuoteHandle(swaps[(n, unit)]),
                              Period(n, unit), calendar,
                              fixedLegFrequency, fixedLegAdjustment,
                              fixedLegDayCounter, tiie_index)
               for n, unit in swaps.keys()]

# term structure handles

discountTermStructure = RelinkableYieldTermStructureHandle()
forecastTermStructure = RelinkableYieldTermStructureHandle()

# term-structure construction

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

swapEngine = DiscountingSwapEngine(discountTermStructure)

# 5Y Swap

nominal = 10000000
maturity = Date(10, June, 2026)
fixedRate = 0.05
spread = 0.0

#How to create the MX index here?
index = Euribor6M(forecastTermStructure)

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

swap = VanillaSwap(VanillaSwap.Receiver, nominal,
                   fixedSchedule, fixedRate, fixedLegDayCounter,
                   floatingSchedule, index, spread,
                   Actual360())
swap.setPricingEngine(swapEngine)

discountTermStructure.linkTo(depoSwapCurve)
forecastTermStructure.linkTo(depoSwapCurve)
print('NPV')
print(swap.NPV())
print('Rate')
print(swap.fairRate()
shift = 0.0001

temp_fyc_handle = YieldTermStructureHandle(depoSwapCurve)
temp_dyc_handle = YieldTermStructureHandle(depoSwapCurve)
shiftedForwardCurve = ZeroSpreadedTermStructure(temp_fyc_handle, QuoteHandle(SimpleQuote(shift)))
shiftedDiscountCurve = ZeroSpreadedTermStructure(temp_dyc_handle, QuoteHandle(SimpleQuote(shift)))
discountTermStructure.linkTo(shiftedDiscountCurve)
forecastTermStructure.linkTo(shiftedForwardCurve)
P_p = swap.NPV()

temp_fyc_handle = YieldTermStructureHandle(depoSwapCurve)
temp_dyc_handle = YieldTermStructureHandle(depoSwapCurve)
shiftedForwardCurve = ZeroSpreadedTermStructure(temp_fyc_handle, QuoteHandle(SimpleQuote(-shift)))
shiftedDiscountCurve = ZeroSpreadedTermStructure(temp_dyc_handle, QuoteHandle(SimpleQuote(-shift)))
discountTermStructure.linkTo(shiftedDiscountCurve)
forecastTermStructure.linkTo(shiftedForwardCurve)
P_m = swap.NPV()

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

## Answer by Luigi Ballabio (score 2)

https://quant.stackexchange.com/a/63467

Same as you did for the other instance of the index, except you'll also have to pass the term structure:

```
index = IborIndex('TIIE', Period(28, Days), 2, MXNCurrency(),
                  NullCalendar(), Following, False, Actual360(),
                  forecastTermStructure)
```

As Dimitri commented, you might also use `Mexico()` instead of `NullCalendar()` in both places.

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.