1 votos

BootStrap con quantlib USD SOFR (vs. FIXED RATE) swap curve

Me cuesta entender por qué mis tipos de mercado no coinciden con mi modelo bootstrap. Así que me pregunto por qué la diferencia es tan alta entre el mercado y el modelo.

maturity |  market  |   model
   1W    | 0.050640 | 0.050626
   2W    | 0.050670 | 0.050631
   3W    | 0.050720 | 0.050655
   1M    | 0.051021 | 0.050916
   2M    | 0.051391 | 0.051178
   3M    | 0.051745 | 0.051415
   4M    | 0.051940 | 0.051493
   5M    | 0.051980 | 0.051424
   6M    | 0.051820 | 0.051149
   7M    | 0.051584 | 0.050821
   8M    | 0.051310 | 0.050454
   9M    | 0.050924 | 0.049979
   10M    | 0.050604 | 0.049582
   11M    | 0.050121 | 0.049026
   12M    | 0.049550 | 0.048386
   18M    | 0.045585 | 0.044806
   2Y    | 0.042631 | 0.041774
   3Y    | 0.038952 | 0.038230
   4Y    | 0.036976 | 0.036321
   5Y    | 0.035919 | 0.035297
   6Y    | 0.035350 | 0.034745
   7Y    | 0.034998 | 0.034403
   8Y    | 0.034808 | 0.034219
   9Y    | 0.034738 | 0.034151
   10Y    | 0.034712 | 0.034125
   12Y    | 0.034801 | 0.034210
   15Y    | 0.034923 | 0.034327
   20Y    | 0.034662 | 0.034075
   25Y    | 0.033750 | 0.033193
   30Y    | 0.032826 | 0.032298
   40Y    | 0.030835 | 0.030369
   50Y    | 0.028960 | 0.028548

Mi curva sólo contiene intercambio.

Pata fija :

  • Descuento OIS
  • Liquidación T+2 días
  • Semana del trimestre 2
  • Recuento de días ACT/360
  • Frecuencia de pago Anual
  • Bus Adj ModificadoSiguiente
  • Ajustar fechas de devengo y pago
  • Rollo Conv Hacia Atrás (EOM)
  • Calc Cal FD
  • Retraso en el pago 2 días laborables

Pata flotante

  • Recuento de días ACT/360
  • Frecuencia de pago Anual
  • Índice SOFRRATE Índice
  • Reajuste Frec Diario
  • Bus Adj ModificadoSiguiente

    self.swaps = {Period("1W"): 0.05064, Period("2W"): 0.05067, Period("3W"): 0.05072, Period("1M"): 0.051021000000000004, Period("2M"): 0.051391, Period("3M"): 0.051745, Period("4M"): 0.05194, Period("5M"): 0.051980000000000005, Period("6M"): 0.051820000000000005, Period("7M"): 0.051584000000000005, Period("8M"): 0.05131, Period("9M"): 0.050924, Period("10M"): 0.050603999999999996, Period("11M"): 0.050121, Period("12M"): 0.049550000000000004, Period("18M"): 0.04558500000000001, Period("2Y"): 0.042630999999999995, Period("3Y"): 0.038952, Period("4Y"): 0.036976, Period("5Y"): 0.035919, Period("6Y"): 0.03535, Period("7Y"): 0.034998, Period("8Y"): 0.034808, Period("9Y"): 0.034738000000000005, Period("10Y"): 0.034712, Period("12Y"): 0.034801, Period("15Y"): 0.034923, Period("20Y"): 0.034662, Period("25Y"): 0.03375, Period("30Y"): 0.032826, Period("40Y"): 0.030834999999999998, Period("50Y"): 0.02896}

A continuación se muestra cómo utilizo OISRateHelper

for tenor, rate in self.swaps.items():
            helper = ql.OISRateHelper(2, tenor, ql.QuoteHandle(ql.SimpleQuote(rate)), self.swap_underlying)
            rate_helpers.append(helper)

Y a continuación comparo las nuevas tarifas con las tarifas dadas :

self.curve = ql.PiecewiseSplineCubicDiscount(calculation_date, rate_helpers, self.swap_day_count_conv)
yts = ql.YieldTermStructureHandle(self.curve)

# Link index to discount curve
index = index.clone(yts)

# Create engine with yield term structure
engine = ql.DiscountingSwapEngine(yts)

# Check the swaps reprice

print("maturity |  market  |   model")
for tenor, rate in self.swaps.items():
    swap = ql.MakeVanillaSwap(tenor,
                            index, 0.01,
                            ql.Period('0D'),
                            fixedLegTenor=ql.Period('2D'),
                            fixedLegDayCount=self.swap_day_count_conv,
                            fixedLegCalendar=ql.UnitedStates(ql.UnitedStates.GovernmentBond),
                            floatingLegCalendar=ql.UnitedStates(ql.UnitedStates.GovernmentBond),
                            pricingEngine=engine)

    print(f"   {tenor}    | {rate:.6f} | {swap.fairRate():.6f}")

Tenga en cuenta también que :

self.swap_underlying = ql.OvernightIndex("USD Overnight Index", 2, ql.USDCurrency(), ql.UnitedStates(ql.UnitedStates.Settlement), ql.Actual360())

self.swap_day_count_conv = ql.Actual360()

¿Me he perdido algo? ¿Es correcta la aplicación que he hecho? ¿Hay discrepancias en los parámetros?

Nota Descripción de la curva :

enter image description here

Swap Descripcion :

enter image description here

enter image description here

2voto

Brad Tutterow Puntos 5628

Utilizando ql.MakeVanillaSwap En este caso, estás creando un swap que paga LIBOR frente a fijo, no un OIS como los que utilizaste para bootstrap la curva. Si realmente quieres utilizar swaps vainilla, necesitas utilizar SwapRateHelper no OISRateHelper . Si desea utilizar OIS en su lugar, tendrá que utilizar OvernightIndexedSwap para construir el swap y recuperar el tipo justo.

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