2 votos

QuantLib Inexacto - Opción Put americana con dividendos discretos

Estoy tratando de usar la biblioteca QuantLib para determinar el precio de opciones americanas que pagan dividendos discretos.

Las opciones de compra tienen un precio con buena precisión (generalmente, un error <0,1%), sin embargo, los mismos datos de entrada para una opción de venta presentan una gran discrepancia (>50% de error) en comparación con los valores esperados (obtenidos del software de Excel de Hoadley), especialmente para opciones de venta muy fuera del dinero.

La función que estoy utilizando está definida de la siguiente manera:

import QuantLib as ql

def get_option_price(
    valuation_date = [1,7,2021],
    expiry_date = [1,7,2022],
    strike_price = 70,
    underlying_price = 100,
    volatility = 0.30,
    risk_free_rate = 0.06,
    dividends = [],
    is_american = True,
    is_call = True
    ):

    div_dates = []
    div_values = []
    for div in dividends:
        date = div[0]
        value = div[1]
        div_dates.append(ql.Date(*date))
        div_values.append(value)

    # Reformat dates from list into QL date format
    valuation_date = ql.Date(*valuation_date)
    expiry_date = ql.Date(*expiry_date)
    ql.Settings.instance().setEvaluationDate(valuation_date)
    day_count = ql.Actual365Fixed()
    calendar = ql.Australia()

    # Reformat prices and rates from list into QL format
    underlying_price = ql.QuoteHandle(ql.SimpleQuote(underlying_price))
    risk_free_rate = ql.YieldTermStructureHandle(
        ql.FlatForward(valuation_date, risk_free_rate, day_count))
    volatility = ql.BlackVolTermStructureHandle(
        ql.BlackConstantVol(valuation_date, calendar, volatility, day_count))

    # Create option
    if is_call:
        payoff = ql.PlainVanillaPayoff(ql.Option.Call, strike_price)
    else:
        payoff = ql.PlainVanillaPayoff(ql.Option.Put, strike_price)
    if is_american:
        exercise = ql.AmericanExercise(valuation_date, expiry_date)
    else:
        exercise = ql.EuropeanExercise(expiry_date)
    option = ql.DividendVanillaOption(payoff, exercise, div_dates,
                                          div_values)

    # Black Scholes process
    process = ql.BlackScholesProcess(underlying_price,
                                          risk_free_rate,
                                          volatility)

    # Create option's pricing engine
    precision_steps = 500
    engine = ql.FdBlackScholesVanillaEngine(process, precision_steps, precision_steps - 1)
    option.setPricingEngine(engine)

    # Precio de la opción
    return option.NPV()

Aquí tienes algunos ejemplos de datos de entrada/salida para opciones de compra que generalmente se comportan como espero:

price = get_option_price(dividends = [[[1,7,2021], 30]], is_call = True)
print(price)
>> 29.999999999999044
# (Esperado: 30.0004)

price = get_option_price(dividends = [[[1,1,2022], 30]], is_call = True)
print(price)
>> 32.32516446072868
# (Esperado: 32.3034)

price = get_option_price(dividends = [[[30,6,2022], 30]], is_call = True)
print(price)
>> 34.969800332368024
# (Esperado: 34.9839)

Aquí tienes ejemplos de datos de entrada/salida para opciones de venta que no son precisos:

price = get_option_price(dividends = [[[1,7,2021], 30]], is_call = False)
print(price)
>> 6.670681910486139
# (Esperado: 6.6734)

price = get_option_price(dividends = [[[1,1,2022], 30]], is_call = False)
print(price)
>> 8.262009670450684
# (Esperado: 6.2855)

price = get_option_price(dividends = [[[30,6,2022], 30]], is_call = False)
print(price)
>> 8.882930513922709
# (Esperado: 5.6245)

La falta de precisión generalmente empeora a medida que la fecha de dividendo se acerca al vencimiento, o si el valor del dividendo aumenta.

  1. ¿Hay algo mal en mi implementación, o es una limitación del motor de fijación de precios que estoy utilizando? En caso de que sea lo último:
  2. ¿Existen otros motores de fijación de precios alternativos que puedan manejar dividendos discretos? (hasta donde sé, el BinomialVanillaEngine de QuantLib no admite programación de dividendos discretos)

3voto

Tarrant Puntos 1202

El motor de precios FdBlackScholesVanillaEngine admite dos tipos de modelos de dividendos discretos, el llamado modelo de spot y el modelo de dividendos en garantía. El predeterminado es el modelo de dividendos en spot. Tengo que admitir que no conozco en detalle tu referencia "software de Excel de Hoadley", pero al ver los resultados parece que este software está utilizando el modelo de dividendos en garantía. Puedes cambiar a este último en QuantLib con

engine = ql.FdBlackScholesVanillaEngine.make(
    process,
    tGrid=precision_steps,
    xGrid=precision_steps - 1,
    cashDividendModel=ql.FdBlackScholesVanillaEngine.Escrowed
)

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