2 votos

Las tasas de descuento de Quantlib OIS USD no coinciden con las tasas de descuento de Bloomberg

Los factores de descuento de Bloomberg USD OIS para el 01-03-2024 no coinciden con los valores calculados utilizando Quantlib más allá del tenor de 18M. ¿Qué debo hacer para que coincidan?

Lo siento, no puedo pegar una captura de pantalla desde el terminal de Bloomberg.

Mi código es el siguiente:

import typing
import datetime
import math
import pandas
import QuantLib

if __name__ == "__main__":
    day_counter: QuantLib.DayCounter = QuantLib.Actual360()
    calendar: QuantLib.Calendar = QuantLib.UnitedStates(QuantLib.UnitedStates.FederalReserve)
    reference_date: QuantLib.Date = QuantLib.Date(1, 3, 2024)
    settlement_date: QuantLib.Date = calendar.advance(reference_date, QuantLib.Period(2, QuantLib.Days))
    QuantLib.Settings.instance().evaluationDate = reference_date
    overnightIndex: QuantLib.FedFunds = QuantLib.FedFunds()

    # Tasas de Swap de Bloomberg USD OIS
    swaps: typing.Mapping[QuantLib.Period, float] = {
        QuantLib.Period("1W"): 5.33000,
        QuantLib.Period("2W"): 5.33260,
        QuantLib.Period("3W"): 5.33300,
        QuantLib.Period("1M"): 5.33535,
        QuantLib.Period("2M"): 5.34110,
        QuantLib.Period("3M"): 5.33440,
        QuantLib.Period("4M"): 5.30550,
        QuantLib.Period("5M"): 5.27900,
        QuantLib.Period("6M"): 5.24035,
        QuantLib.Period("9M"): 5.12030,
        QuantLib.Period("1Y"): 4.98700,
        QuantLib.Period("18M"): 4.65575,
        QuantLib.Period("2Y"): 4.43105,
        QuantLib.Period("3Y"): 4.13593,
        QuantLib.Period("4Y"): 3.97872,
        QuantLib.Period("5Y"): 3.88900,
        QuantLib.Period("6Y"): 3.83837,
        QuantLib.Period("7Y"): 3.80548,
        QuantLib.Period("8Y"): 3.78547,
        QuantLib.Period("9Y"): 3.77427,
        QuantLib.Period("10Y"): 3.76773,
        QuantLib.Period("12Y"): 3.76733,
        QuantLib.Period("15Y"): 3.77146,
        QuantLib.Period("20Y"): 3.73336,
        QuantLib.Period("25Y"): 3.64168,
        QuantLib.Period("30Y"): 3.54345,
        QuantLib.Period("40Y"): 3.33623,
        QuantLib.Period("50Y"): 3.11935
    }
    ois_helpers: typing.List[QuantLib.OISRateHelper] = [
        QuantLib.OISRateHelper(
            settlementDays=2,
            tenor=tenor,
            rate=QuantLib.QuoteHandle(QuantLib.SimpleQuote(rate / 100)),
            index=overnightIndex,
        )
        for tenor, rate in swaps.items()
    ]

    curve: QuantLib.PiecewiseLogLinearDiscount = QuantLib.PiecewiseLogLinearDiscount(0, calendar, ois_helpers, QuantLib.Actual360())
    tenors: typing.List[QuantLib.Period] = []
    rates: typing.List[float] = []
    maturity_dates: typing.List[datetime.date] = []
    zero_rates: typing.List[float] = []
    discount_factors: typing.List[float] = []
    for tenor, rate in swaps.items():
        tenors.append(tenor)
        rates.append(rate)
        maturity_date: QuantLib.Date = calendar.advance(settlement_date, tenor, QuantLib.ModifiedFollowing, True)
        maturity_dates.append(datetime.date(maturity_date.year(), maturity_date.month(), maturity_date.dayOfMonth()))
        discount_factor: float = curve.discount(maturity_date)
        discount_factors.append(discount_factor)
        zero_rate: float = -100.0 * math.log(discount_factor) * 365.0 / (maturity_date - reference_date)
        zero_rates.append(zero_rate)

    result: pandas.DataFrame = pandas.DataFrame(
        data={
            "Tenor": tenors,
            "Maturity Date": maturity_dates,
            "Market Rate": rates,
            "Zero Rate": zero_rates,
            "Discount": discount_factors,
            "Bloomberg Discount": [
                0.998374,
                0.997340,
                0.996309,
                0.994838,
                0.990299,
                0.985967,
                0.981757,
                0.977478,
                0.973338,
                0.961789,
                0.951308,
                0.932241,
                0.915541,
                0.884058,
                0.853814,
                0.824673,
                0.795974,
                0.768084,
                0.740793,
                0.714084,
                0.688356,
                0.638668,
                0.570186,
                0.477321,
                0.409793,
                0.357900,
                0.288171,
                0.250724
            ]
        }
    )
    result["Discount Difference"] = round(result["Discount"] - result["Bloomberg Discount"], 6)
    print(result.to_string(index=False))

La salida es la siguiente:

Tenor Maturity Date  Market Rate  Zero Rate  Discount  Bloomberg Discount  Discount Difference
   1W    2024-03-12      5.33000   5.401229  0.998374            0.998374            -0.000000
   2W    2024-03-19      5.33260   5.401102  0.997340            0.997340            -0.000000
   3W    2024-03-26      5.33300   5.399085  0.996309            0.996309            -0.000000
   1M    2024-04-05      5.33535   5.397540  0.994838            0.994838            -0.000000
   2M    2024-05-06      5.34110   5.391176  0.990299            0.990299            -0.000000
   3M    2024-06-05      5.33440   5.373175  0.985967            0.985967             0.000000
   4M    2024-07-05      5.30550   5.333618  0.981757            0.981757            -0.000000
   5M    2024-08-05      5.27900   5.295914  0.977478            0.977478            -0.000000
   6M    2024-09-05      5.24035   5.246586  0.973338            0.973338             0.000000
   9M    2024-12-05      5.12030   5.096887  0.961789            0.961789             0.000000
   1Y    2025-03-05      4.98700   4.937667  0.951308            0.951308            -0.000000
  18M    2025-09-05      4.65575   4.631071  0.932241            0.932241             0.000000
   2Y    2026-03-05      4.43105   4.388100  0.915538            0.915541            -0.000003
   3Y    2027-03-05      4.13593   4.092998  0.884053            0.884058            -0.000005
   4Y    2028-03-06      3.97872   3.935097  0.853806            0.853814            -0.000008
   5Y    2029-03-05      3.88900   3.845092  0.824662            0.824673            -0.000011
   6Y    2030-03-05      3.83837   3.794754  0.795961            0.795974            -0.000013
   7Y    2031-03-05      3.80548   3.762279  0.768070            0.768084            -0.000014
   8Y    2032-03-05      3.78547   3.743008  0.740777            0.740793            -0.000016
   9Y    2033-03-07      3.77427   3.732890  0.714067            0.714084            -0.000017
  10Y    2034-03-06      3.76773   3.727594  0.688339            0.688356            -0.000017
  12Y    2036-03-05      3.76733   3.730669  0.638652            0.638668            -0.000016
  15Y    2039-03-07      3.77146   3.739299  0.570172            0.570186            -0.000014
  20Y    2044-03-07      3.73336   3.692611  0.477288            0.477321            -0.000033
  25Y    2049-03-05      3.64168   3.565595  0.409681            0.409793            -0.000112
  30Y    2054-03-05      3.54345   3.423741  0.357667            0.357900            -0.000233
  40Y    2064-03-05      3.33623   3.112584  0.287588            0.288171            -0.000583
  50Y    2074-03-05      3.11935   2.773300  0.249608            0.250724            -0.001116

2voto

dotnetcoder Puntos 1262

Creo que este puede ser un problema con Bloomberg que redondea sus valores y no muestra exactamente lo que está utilizando como entrada, o posiblemente que el "Paso adelante de Bloomberg (Cont)" hace algo que no es exactamente igual a la interpolación log-lineal de los factores de descuento en las fechas de madurez.

Tu problema publicado en Rateslib https://github.com/attack68/rateslib/issues/145 muestra que Quantlib y Rateslib, que están implementando interpolaciones log-lineales en los mismos datos de mercado, son casi iguales.

Así que aquí el valor atípico parece ser Bloomberg, si dos fuentes independientes convergen en la misma respuesta.

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