Quisiera usar QuantLib Python para calcular las tasas par de una curva de swap.
El código siguiente es lo que he hecho hasta ahora:
from QuantLib import *
# datos globales
calendar = TARGET()
todaysDate = Date(6,Noviembre,2001);
Settings.instance().evaluationDate = todaysDate
settlementDate = Date(8,Noviembre,2001);
# comillas de mercado
deposits = { (1,Semanas): 0.0382,
(1,Meses): 0.0372,
(3,Meses): 0.0363,
(6,Meses): 0.0353,
(9,Meses): 0.0348,
(1,Años): 0.0345 }
swaps = { (2,Años): 0.037125,
(3,Años): 0.0398,
(5,Años): 0.0443,
(10,Años): 0.05165,
(15,Años): 0.055175 }
# convertirlos a objetos Quote
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)])
# construir ayudantes de tasa
dayCounter = Actual360()
settlementDays = 2
depositHelpers = [ DepositRateHelper(QuoteHandle(deposits[(n,unit)]),
Period(n,unit), settlementDays,
calendar, ModifiedFollowing,
False, dayCounter)
for n, unit in [(1,Semanas),(1,Meses),(3,Meses),
(6,Meses),(9,Meses),(1,Años)] ]
fixedLegFrequency = Anual
fixedLegTenor = Period(1,Años)
fixedLegAdjustment = Unadjusted
fixedLegDayCounter = Thirty360()
floatingLegFrequency = Semiannual
floatingLegTenor = Period(6,Meses)
floatingLegAdjustment = ModifiedFollowing
swapHelpers = [ SwapRateHelper(QuoteHandle(swaps[(n,unit)]),
Period(n,unit), calendar,
fixedLegFrequency, fixedLegAdjustment,
fixedLegDayCounter, Euribor6M())
for n, unit in swaps.keys() ]
# manejadores de la estructura temporal
discountTermStructure = RelinkableYieldTermStructureHandle()
forecastTermStructure = RelinkableYieldTermStructureHandle()
# construcción de la estructura temporal
helpers = depositHelpers + swapHelpers
depoSwapCurve = PiecewiseFlatForward(settlementDate, helpers, Actual360())
ref_date = depoSwapCurve.referenceDate()
yc_day_count = depoSwapCurve.dayCounter()
tenor = Period(10, Años)
# 10Y Swap
nominal = 1000000
maturity = calendar.advance(settlementDate,10,Años)
fixedRate = 0.04
floatingLegFrequency = Semiannual
spread = 0.0
fixingDays = 2
index = Euribor6M(forecastTermStructure)
floatingLegDayCounter = index.dayCounter()
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.Receptor, nominal,
fixedSchedule, fixedRate, fixedLegDayCounter,
floatingSchedule, index, spread,
floatingLegDayCounter)
swap.setPricingEngine(swapEngine)
discountTermStructure.linkTo(depoSwapCurve)
forecastTermStructure.linkTo(depoSwapCurve)
print('tasa par del instrumento original:')
print(swaps[(10, Años)].value())
print
print('tasa par del swap calculada:')
print(swap.fairRate())
print
print('tasa par de la curva de rendimiento calculada:')
print(depoSwapCurve.forwardRate(ref_date, calendar.advance(ref_date, tenor), yc_day_count, Compounded ).rate())
Del código anterior podemos ver que swap.fairRate()
devuelve la tasa par del swap que es muy similar a la tasa original del swap utilizada para construir el objeto de la curva de rendimiento. Esto es lo que quiero. Sin embargo, este método de cálculo de la tasa par del swap es bastante engorroso, porque quiero calcular la tasa par del swap no solo para 10A, sino también para 11A, 12A, 13A, etc... Esto significa que tendré que crear un objeto VanillaSwap separado para 11A, 12A, 13A, etc...
Mi segunda forma de calcular la tasa par del swap es depoSwapCurve.forwardRate(...)
. Sin embargo, del código anterior podemos ver que el valor devuelto por la función forwardRate(...)
es bastante diferente de la tasa de swap original utilizada para construir el objeto de la curva de rendimiento.
¿Estoy utilizando correctamente la función forwardRate(...)
para calcular la tasa par? ¿O hay una mejor manera de calcular la tasa par a partir de un objeto de curva de rendimiento?