2 votos

Quantlib bootstraping falla en el swap 5y

Estoy tratando de construir una curva de intercambio de euros con datos reales actualizados. Debo decir que los ejemplos proporcionados en github funcionan bien. En cuanto añado el swap 5y, me sale el siguiente error :

RuntimeError: 1st iteration: failed at 14th alive instrument, maturity September 28th, 2020, reference date September 28th, 2015: root not bracketed: f[-1,1] -> [3.260558e-001,5.904525e-002]

editar (error con líneas de error) :

RuntimeError: void __thiscall QuantLib::IterativeBootstrap<class QuantLib::PiecewiseYieldCurve<struct QuantLib::ForwardRate,class QuantLib::BackwardFlat,class QuantLib::IterativeBootstrap> >::calculate(void) const: 
  d:\PycharmProjects\quantlib\QuantLib\ql/termstructures/iterativebootstrap.hpp(217): 
1st iteration: failed at 14th alive instrument, maturity September 28th, 2020, reference date September 28th, 2015: double __thiscall QuantLib::Solver1D<class QuantLib::Brent>::solve<class QuantLib::BootstrapError<class QuantLib::PiecewiseYieldCurve<struct QuantLib::ForwardRate,class QuantLib::BackwardFlat,class QuantLib::IterativeBootstrap> >>(const class QuantLib::BootstrapError<class QuantLib::PiecewiseYieldCurve<struct QuantLib::ForwardRate,class QuantLib::BackwardFlat,class QuantLib::IterativeBootstrap> > &,double,double,double,double) const: 
  d:\PycharmProjects\quantlib\QuantLib\ql/math/solver1d.hpp(202): 
root not bracketed: f[-1,1] -> [3.260558e-001,5.904525e-002]

Tengo que decir que no me da error si quito el swap 5y. Tengo QL_NEGATIVE_RATES en userconfig.hpp que no está comentado.

el trozo de código que estoy usando está aquí.

gracias

import QuantLib as ql
import datetime

calendar = ql.TARGET()
settlementDays = 2
now = datetime.datetime.now()
today = calendar.adjust(ql.Date(now.day, now.month, now.year))
ql.Settings.instance().evaluationDate = today
settlementDate = calendar.advance(today, settlementDays, ql.Days)

# market quotes
deposits = {(1, ql.Weeks): -0.141,
            (1, ql.Months): -0.107,
            (2, ql.Months): -0.066,
            (3, ql.Months): -0.039,
            (6, ql.Months): 0.033,
            (9, ql.Months): 0.083,
            (12, ql.Months): 0.147}

futures = {ql.Date(16, 3, 2016): 100.045,
           ql.Date(15, 6, 2016): 100.055,
           ql.Date(21, 9, 2016): 100.06,
           ql.Date(21, 12, 2016): 100.055,
           ql.Date(15, 3, 2017): 100.04}

swaps = {(2, ql.Years): 0.0557,
         (3, ql.Years): 0.1275,
         (4, ql.Years): 0.2331,
         #(5, ql.Years): 0.3523
         }

# convert them to Quote objects
for n, unit in deposits.keys():
    deposits[(n, unit)] = ql.SimpleQuote(deposits[(n, unit)])
for d in futures.keys():
    futures[d] = ql.SimpleQuote(futures[d])
for n, unit in swaps.keys():
    swaps[(n, unit)] = ql.SimpleQuote(swaps[(n, unit)])

dayCounter = ql.Actual360()

depositHelpers = [
    ql.DepositRateHelper(ql.QuoteHandle(deposits[(n, unit)]), ql.Period(n, unit), settlementDays, calendar,
                         ql.ModifiedFollowing, False, dayCounter) for n, unit in sorted(deposits.iterkeys())]

dayCounter = ql.Actual360()

futuresHelpers = [
    ql.FuturesRateHelper(ql.QuoteHandle(futures[d]), d, 3, calendar, ql.ModifiedFollowing, True, dayCounter,
                         ql.QuoteHandle(ql.SimpleQuote(0.0))) for d in sorted(futures.keys())]

settlementDays = 2
fixedLegFrequency = ql.Annual
fixedLegTenor = ql.Period(1, ql.Years)
fixedLegAdjustment = ql.Unadjusted
fixedLegDayCounter = ql.Thirty360()
floatingLegFrequency = ql.Semiannual
floatingLegTenor = ql.Period(6, ql.Months)
floatingLegAdjustment = ql.ModifiedFollowing

swapHelpers = [ql.SwapRateHelper(ql.QuoteHandle(swaps[(n, unit)]), ql.Period(n, unit), calendar, fixedLegFrequency,
                                 fixedLegAdjustment, fixedLegDayCounter, ql.Euribor6M()) for n, unit in
               swaps.keys()]

# term structure handles

discountTermStructure = ql.RelinkableYieldTermStructureHandle()
forecastTermStructure = ql.RelinkableYieldTermStructureHandle()

def printHelper(x):
    print('{} | {}'.format(x.latestDate(), x.quote().value()))

def printH(t):
    print('\n======')
    print t
    for i in list(t):
        printHelper(i)

printH(depositHelpers)
printH(futuresHelpers)
printH(swapHelpers)

helpers = depositHelpers[:-2] + futuresHelpers + swapHelpers
printH(helpers)

depoFuturesSwapCurve = ql.PiecewiseFlatForward(settlementDate, helpers, ql.Actual360())

print depoFuturesSwapCurve.dates()

for c in depoFuturesSwapCurve.dates():
    print depoFuturesSwapCurve.discount(c)

0 votos

Volví a compilar con líneas de error para poder entender mejor, pero sigo sin ver por qué falla el bootstraping.

0 votos

Como señala la respuesta de @Luigi Ballabio, ya no se deberían construir curvas de canje de esta manera... Por favor, lea sobre los enfoques modernos de múltiples curvas para la construcción de la curva de rendimiento.

0 votos

@haginile ¿a qué te refieres más precisamente con eso? Solo veo un problema de "formato" en la respuesta de Luigi pero usando la aplicación de Android.

6voto

Brad Tutterow Puntos 5628

No eres el primero en tropezar con esto, y desgraciadamente el hecho de que el ejemplo proporcionado sea de otra época no ayuda.

Sencillamente, no estás escribiendo los tipos correctamente. El tipo swap a 5 años, 0,3523%, debe escribirse en forma decimal como 0,003523. Lo mismo ocurre con los tipos de depósito.

Tal y como está tu código ahora, estás escribiendo que la tasa de 4 años es del 23,31% y la de 5 años es del 35,23%, y el código bootstrap no consigue encontrar una solución que dé cuenta de la variación extrema.

Si se escriben los índices correctamente, se podrá realizar el bootstrap de la curva como se espera.

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X