La aproximación (15) comienza con la cantidad:
$$ \underbrace{c(\sigma^+_\Delta) - p(\sigma_\Delta^-)}_{\text{prima de inversión de riesgo del mercado}} - \underbrace{ \left(c(\sigma_0) + p(\sigma_0)\right )}_{\text{prima de inversión de riesgo base atm vol}} $$
La prima de inversión de riesgo base es necesaria porque una inversión de riesgo de X-delta no tiene prima cero incluso para una curva plana, y la razón de eso es que la huelga delta del ATM y la huelga forward del ATM no son iguales. Esa diferencia crece con la volatilidad y con el tiempo hasta la expiración.
Pondré algunos números en esto para demostración. Primero usaré sus tasas de interés EUR, USD para construir curvas de interés y agregar su precio forward de FX para configurar todo en un marco consistente:
# PYTHON: rateslib >= 1.3.0
from rateslib import *
eur = Curve({dt(2024, 6, 20): 1.0, dt(2024, 9, 28): 1.0}, calendar="tgt")
usd = Curve({dt(2024, 6, 20): 1.0, dt(2024, 9, 28): 1.0}, calendar="nyc")
eurusd = Curve({dt(2024, 6, 20): 1.0, dt(2024, 9, 28): 1.0})
fxr = FXRates({"eurusd": 1.0727}, settlement=dt(2024, 6, 24))
fxf = FXForwards(
fx_rates=fxr,
fx_curves={"eureur": eur, "eurusd": eurusd, "usdusd": usd}
)
pre_solver = Solver(
curves=[eur, usd, eurusd],
instruments=[
IRS(dt(2024, 6, 24), "3m", spec="eur_irs", curves=eur),
IRS(dt(2024, 6, 24), "3m", spec="usd_irs", curves=usd),
FXExchange(pair="eurusd", settlement=dt(2024, 9, 24), curves=[None, eurusd, None, usd])
],
s=[3.77, 5.51, 1.0775], # <- YOUR RATES
fx=fxf,
)
SUCCESS: `func_tol` reached after 8 iters, `f_val`: 3.92e-13, `time`: 0.0102s
Ahora podemos obtener algunos valores de opciones. Estos son los valores de prima de puntos de FX (en USD) para cada opción en el Riesgo Reversal 25D. Observe que no se cancelan, a pesar de que el precio de RR en puntos de volatilidad es cero (ya que ambos se cotizan con 6.6% de vol):
fx_option_args = dict(
pair="eurusd",
expiry=dt(2024, 9, 20),
curves=[None, eurusd, None, usd],
delivery_lag=2,
payment_lag=dt(2024, 6, 20),
calendar="tgt|nyc",
)
FXCall(strike="25d", **fx_option_args).rate(vol=6.6, fx=fxf)
#
FXPut(strike="-25d", **fx_option_args).rate(vol=6.6, fx=fxf)
#
A continuación, la suposición es aproximar con primer orden el valor de las calls y los puts en relación con sus precios equivalentes.
$$ c(\sigma_\Delta^+) \approx c(\sigma_0) + c_\sigma(\sigma_0) (\sigma_\Delta^+ - \sigma_0) $$ $$ p(\sigma_\Delta^-) \approx p(\sigma_0) + p_\sigma(\sigma_0) (\sigma_\Delta^- - \sigma_0) $$
Al introducir esto se obtiene la segunda línea de (15). Dado que es de primer orden, su precisión se deteriora a medida que el precio de volatilidad de mercado diverge más del volatilidad ATM.
¿Es esta una aproximación razonable en su caso? Vamos a explorar el Put que tiene la mayor discrepancia. El Put de -25D con volatilidad del 7.621% tiene las cantidades:
FXPut(strike="-25d", **fx_option_args).rate(vol=7.621, fx=fxf)
#
FXPut(strike="-25d", **fx_option_args).analytic_greeks(vol=7.621, fx=fxf)
# huelga: 1.0511201224444822
# vega_usd:
La misma opción con una volatilidad del 6.6% da los valores:
FXPut(strike=1.0511201224444822, **fx_option_args).rate(vol=6.60, fx=fxf)
#
FXPut(strike=1.0511201224444822, **fx_option_args).analytic_greeks(vol=6.60, fx=fxf)
# vega_usd:
# vomma_usd:
Entonces, de primer orden ahora: $$ 45.732276 + 15.877304 * 1.021 = 61.943 $$ Mientras que de segundo orden, incluyendo el vomma: $$ 45.732276 + 15.877304 * 1.021 + 1.345585 * 1.021^2 / 2 = 62.644 $$
Por lo tanto, incluso esta desviación razonablemente pequeña produce suficiente error para anular algunos procesos. Supongo que depende de lo que estás haciendo.
La suposición adicional que se utiliza en (15) para derivar las líneas finales es que $c_\sigma(\sigma_0)$ y $p_\sigma(\sigma_0)$ son iguales. No me queda claro la intención del autor con la noción, pero, para ser consistente con la aproximación lineal en el primer paso, $c(.)$ y $p(.)$ deben tener huelgas que se determinen con las volatilidades de mercado correctas. Cuando las huelgas se determinan de esta manera, las cantidades de vega son simétricas, es decir, $c_\sigma(\sigma^+_\Delta) = p_\sigma(\sigma_\Delta^-)$ pero no es cierto que $c_\sigma(\sigma_0) = p_\sigma(\sigma_0)$
FXCall(strike=1.1003294194069992, **fx_option_args).analytic_greeks(vol=6.6, fx=fxf)
# vega_usd:
FXPut(strike=1.0511201224444822, **fx_option_args).analytic_greeks(vol=6.60, fx=fxf)
# vega_usd:
Así que también tengo dificultades con la validez de la afirmación.