Approximating FX Risk-Reversal Value with ATM Vega
Summary
The document examines a common first-order approximation for the premium of an FX risk reversal: multiply at-the-money option vega by the risk reversal in volatility points. It explains that the approximation should compare the market-priced call and put with a baseline risk reversal valued at a flat at-the-money volatility, because delta-defined strikes can produce a nonzero premium even when both options use the same volatility. The example uses EUR/USD market inputs and option valuations to illustrate this baseline adjustment.
A worked put example compares the actual repricing from a volatility change with estimates using vega alone and vega plus vomma. The first-order estimate has a noticeable error, while the second-order estimate is closer in that example. The discussion also questions the assumption that call and put vegas at the baseline volatility are equal. Accuracy depends on the size of the volatility difference, and the numerical example does not establish a universal error bound or validate every market convention.
Key ideas
- A risk-reversal value approximation starts with ATM vega multiplied by the volatility difference between the call and put wings.
- The flat-volatility baseline risk reversal can have a nonzero premium because delta-based strikes differ from the forward ATM strike.
- A first-order vega estimate becomes less reliable as wing volatility moves farther from ATM volatility.
- Adding vomma can improve the illustrated put valuation, though the example does not establish general accuracy.
- Call and put vegas at the baseline volatility need not be equal when their strikes reflect different market volatilities.
Tags
Full text
# FX risk reversal approximation
# FX risk reversal approximation
i see this risk reversal approximation in Uwe Wystup's
https://www.mathfinance.com/wp-content/uploads/2020/09/wystup_vannavolga_eqf.pdf
in which the approximation of a risk reversal is given by:
vega of ATM x risk reversal in volatility terms
as of today, i see the following market pricing:
- FX spot 1.0727
- FX 3m fwd 1.0775,
- usd 3m depo 5.51,
- eur 3m depo 3.77,
- risk reversal 3 months exp/del 20/24 Sep, 25d, call strike 1.0998, put strike 1.0504, bid/offer 0.097% / 0.113% EUR, EUR 1 mio notional
- vanilla 3 months exp/del 20/24 Sep, call strike atms 1.0728, vol 6.7%/6.8%, bid/offer 1.55/1.57% eur, vega in eur is 1912, EUR 1 mio notional
off bloomberg, i see 3months, atm mid 6.6, 25d rr, -1.5 call 6.12 put 7.621
questions:
- how is the cost of the risk reversal (in EUR%) approximated when its mentioned:
"cost of the risk reversal is approximated by the vega of the at-the-money vanilla times the risk reversal in terms of volatility"
- are these approximations valid?
## Answer by Attack68 (score 2)
https://quant.stackexchange.com/a/79845
The approximation (15) begins with the quantity:
$$ \underbrace{c(\sigma^+_\Delta) - p(\sigma_\Delta^-)}_{\text{mkt risk reversal premium}} - \underbrace{ \left(c(\sigma_0) + p(\sigma_0)\right )}_{\text{baseline risk reversal premium atm vol}} $$
The baseline risk reveral premium is required because an X-delta risk reversal does not have zero premium even for a flat curve, and the reason for that is that ATM-delta strike and the ATM-forward strike are not the same. That difference grows with vol and with time to expiry.
I will put some numbers on this for demonstration. First I will use your EUR, USD interest rates to construct interest rate curves and add your FX forward price to configure everything in a consistent framework:
```
# 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
```
Now we can get some option values. These are the FX points premium values (in USD) for each option in the 25D Risk Reversal. Notice that they do not net to zero, even though the RR price in vol points is zero (since both are priced with 6.6% 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)
# <Dual: 52.273662, .., ..>
FXPut(strike="-25d", **fx_option_args).rate(vol=6.6, fx=fxf)
# <Dual: 54.042099, ..,..>
```
Next the assumption is to approximate with first order the value of the calls and puts relative to their equivalent prices.
$$ 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) $$
Plugging this in gets you the second line of (15). Since it is first order its accuracy deteriates as the market vol price diverge further from the ATM vol.
Is this a reasonable approximation in your case? Lets explore the Put which has the greatest discrepancy. The -25D Put with vol at 7.621% has the quantities:
```
FXPut(strike="-25d", **fx_option_args).rate(vol=7.621, fx=fxf)
# <Dual: 62.565252, .., ..>
FXPut(strike="-25d", **fx_option_args).analytic_greeks(vol=7.621, fx=fxf)
# strike: 1.0511201224444822
# vega_usd: <Dual: 1702.692382, .., ..>
```
The same option as priced with 6.6% vol gives the values:
```
FXPut(strike=1.0511201224444822, **fx_option_args).rate(vol=6.60, fx=fxf)
# <Dual: 45.732276, .., ..>
FXPut(strike=1.0511201224444822, **fx_option_args).analytic_greeks(vol=6.60, fx=fxf)
# vega_usd: <Dual: 1587.730467, .., ..>
# vomma_usd: <Dual: 134.5585, .., ..>
```
So now, to first order: $$ 45.732276 + 15.877304 * 1.021 = 61.943 $$ Whilst to second order, including vomma: $$ 45.732276 + 15.877304 * 1.021 + 1.345585 * 1.021^2 / 2 = 62.644 $$
So even this reasonably small deviation produces enough error to negate some processes. I suppose it depends what you are doing.
The additional assumption that is used in (15) to derive the final lines is that $c_\sigma(\sigma_0)$ and $p_\sigma(\sigma_0)$ are the same. It is not clear to me the author's intention with notion but, to me, to be consistent with the linear approximation in the first step, $c(.)$ and $p(.)$ must have strikes that are determined with the correct market volatilities. When the strikes are determined in this manner the vega quantities are symmetric, i.e. $c_\sigma(\sigma^+_\Delta) = p_\sigma(\sigma_\Delta^-)$ but it is not true that $c_\sigma(\sigma_0) = p_\sigma(\sigma_0)$
```
FXCall(strike=1.1003294194069992, **fx_option_args).analytic_greeks(vol=6.6, fx=fxf)
# vega_usd: <Dual: 1759.13, .., ..>
FXPut(strike=1.0511201224444822, **fx_option_args).analytic_greeks(vol=6.60, fx=fxf)
# vega_usd: <Dual: 1587.73, .., ..>
```
So I too struggle with the validity of the claim.Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.