Estoy usando Quantlib para obtener el valor de la opción incrustado en un bono convertible. Puedo crear una opción americana de la siguiente manera:
strike_price = redemption / conversion_ratio
option_type = ql.Option.Call
payoff = ql.PlainVanillaPayoff(option_type, strike_price)
settlement = calculation_date
am_exercise = ql.AmericanExercise(settlement, maturity_date)
american_option = ql.VanillaOption(payoff, am_exercise)
flat_vol_ts = ql.BlackVolTermStructureHandle(ql.BlackConstantVol(calculation_date, calendar, volatility, day_count))
bsm_process = ql.BlackScholesMertonProcess(spot_price_handle,
dividend_ts_handle,
yield_ts_handle,
volatility_ts_handle)
binomial_engine = ql.BinomialVanillaEngine(bsm_process, "crr", time_steps)
american_option.setPricingEngine(binomial_engine)
option_position1 = round(american_option.NPV(),4)
delta_position1 = round(american_option.delta(),4)
gamma_position1 = round(american_option.gamma(),4)
Quiero obtener el ejercicio de la probabilidad como esta es una medida de cómo de capital o de deuda, como un bono convertible es. (por ejemplo, >60% ejercicios de probabilidad está etiquetado como de capital). Es allí función dentro de quantlib que me va a proporcionar el ejercicio de probabilidad (ejercicio probabilidad no es el mismo que el del delta)?
Edit 1: Enfoque de la obtención de la equidad o de la debtness de la obligación convertible:
Edit 2: he tratado de incorporar una doble delta en el código. Tengo que calcular el doble delta mediante la recuperación de dos separar los valores de la opción con algo un poco diferente precio de huelga. Sin embargo, los primeros resultados muestran una gran diferencia entre el delta y el doble delta, delta 2-3x tan alto, así que debo estar haciendo algo mal. ¿Mi código, ya que actualmente se tiene sentido calcular manualmente el doble delta?
strike_price_up = strike_price + 0.0001
strike_price_down = strike_price - 0.0001
payoff_up = ql.PlainVanillaPayoff(option_type, strike_price_up)
payoff_down = ql.PlainVanillaPayoff(option_type, strike_price_down)
american_option_up = ql.VanillaOption(payoff_up, am_exercise)
flat_vol_ts = ql.BlackVolTermStructureHandle(ql.BlackConstantVol(calculation_date, calendar, volatility, day_count))
bsm_process = ql.BlackScholesMertonProcess(spot_price_handle,
dividend_ts_handle,
yield_ts_handle,
flat_vol_ts)
binomial_engine = ql.BinomialVanillaEngine(bsm_process, "crr", time_steps)
american_option_up.setPricingEngine(binomial_engine)
dd_u = american_option_up.NPV()
american_option_down = ql.VanillaOption(payoff_down, am_exercise)
flat_vol_ts = ql.BlackVolTermStructureHandle(ql.BlackConstantVol(calculation_date, calendar, volatility, day_count))
bsm_process = ql.BlackScholesMertonProcess(spot_price_handle,
dividend_ts_handle,
yield_ts_handle,
flat_vol_ts)
binomial_engine = ql.BinomialVanillaEngine(bsm_process, "crr", time_steps)
american_option_down.setPricingEngine(binomial_engine)
dd_d = american_option_down.NPV()
dualdelta = (dd_d - dd_u)/(2*0.0001)
dualdelta_position1 = round(dualdelta,4)
Edit 3: yo creo que la fórmula correcta debería ser: dualdelta = (dd_u - dd_d)/(2*0.0001)
. Esto devuelve un negativo doble delta..?