4 votos

Quantlib Valoración lenta de ois_swap en varios días de evaluación

He creado una curva a partir de varios tipos de depo y swap e intento utilizarla para obtener el VAN de un swap a lo largo de un período de tiempo. La generación de precios iterativamente a través del tiempo es increíblemente lento. Teniendo en cuenta que sólo estoy tarificando un periodo de 4 meses, no esperaría que tardara 30 minutos. ¿Estoy haciendo algo tonto aquí? Vi un post anterior comentando un bug en el wrapper de SWIG de python a c++, pero según uno de los mantenedores del proyecto fue parcheado hace años. Ver lo siguiente:

test_curve.referenceDate() == Date(4,1,2023)

Creación de motores

ts = ql.RelinkableYieldTermStructureHandle()
yts.linkTo(test_curve)
engine = ql.DiscountingSwapEngine(yts)

Definición y creación de swaps

swapTenor = ql.Period('1Y')
overnightIndex = ql.Sofr(yts)
fixedRate = 0.01
ois_swap = ql.MakeOIS(swapTenor, overnightIndex, fixedRate, pricingEngine=engine, discountingTermStructure=yts)

Generación de VAN

    new_prices = []

instance = ql.Settings.instance()

start_date = ql.Date(1,1,2024)
success_counter = 0

while date < start_date:
    # Update eval date in sim
    instance.evaluationDate = date
    price = ois_swap.NPV()
    new_prices.append(price)

    # Increment date forward
    date += ql.Period('1D')
    new_curve = test_model.get_curve_by_date(date.to_date().strftime('%Y-%m-%d'))

    count = 0

    # Check for new_curve to exist
    while new_curve is None:
        date += ql.Period('1D')
        new_curve = test_model.get_curve_by_date(date.to_date().strftime('%Y-%m-%d'))

        count += 1
        if count == 100:
            break
    yts.linkTo(new_curve)
    engine = ql.DiscountingSwapEngine(yts)
    overnightIndex = ql.Sofr(yts)
    ois_swap = ql.MakeOIS(swapTenor, overnightIndex, fixedRate, pricingEngine=engine, discountingTermStructure=yts, effectiveDate=ql.Date(2,1,2024))

La fecha de vencimiento del swap está fijada en mayo de 2024. Gracias.

3voto

Mastafoo Puntos 153

Tras leer la documentación más detenidamente y realizar algunas pruebas de escenario, pude determinar que ql.Settings.instance().evaluationDate = date era el culpable. Parece que la actualización del evaluationdate provoca una actualización de TODOS objetos instanciados dentro de QuantLib que estén relacionados con esa evaluationDate. Yo había instanciado un marco de datos dentro de mi test_model y pre-construí todas las curvas bootstrapped que pretendía utilizar, lo que resultó en la creación de muchos objetos swap y depo helper, todos los cuales se actualizarían en la clase evaluationDate cambiar.

Para añadir color: Python destruye los objetos cuando su contador de referencia llega a 0. Por lo tanto, simplemente hice todos estos objetos transitorios dentro del bucle de eventos de modo que estoy incrementando, como máximo, 1 curva y 1 objeto de intercambio en cada paso adelante. La solución no es la velocidad del rayo, ya que estoy bootstrapping una curva en cada paso, pero está trabajando.

while date < effectiveDate:
    instance.evaluationDate = date

    curve = bootstrap_model.get_curve_by_date(date.to_date().strftime('%Y-%m-%d'), depo=True, swaps=True)

    if curve is None:
        date += ql.Period('1D')
    else:
        yts = ql.RelinkableYieldTermStructureHandle()
        yts.linkTo(curve)
        engine = ql.DiscountingSwapEngine(yts)

        overnightIndex = ql.Sofr(yts)

        ois_swap = ql.MakeOIS(swapTenor, overnightIndex, fixedRate, pricingEngine=engine, discountingTermStructure=yts, effectiveDate=effectiveDate)
        swap_price = ois_swap.NPV()
        new_prices.append(swap_price)

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