# Swaptions

### Introduction

A swaption is an option to enter an interest rate swap at some point in the future, on the swaption expiry date.

There are two types of swaption:

1) Payer swaption 2) Receiver swaption

A payer swaption is an option to enter into a swap as a fixed rate payer. A receiver swaption is an option to enter into a swap as a fixed-rate receiver.

The fixed rate of the swap is determined by the strike of the swaption.

Example: a 3Mx5Y 2% receiver swaption gives the holder the right to enter into a 5 year swap, starting 3 months after the swaption start date, and receiving a 2% fixed rate whilst paying a floating (LIBOR) rate according to the usual currency conventions.

### Settlement

A Swaption can be settled in cash, or in a physical swap. The style of the settlement is determined by the swaption currency. All currencies in the SigTech framework assume a physical settlement, with the exception of GBP and EUR.

Previously, cash settlement was calculated as a function of the swap par (forward) rate. As of 26 November 2018, EUR swaptions have been settled at the fair value for standard collateralised EUR swaps and are, as far as valuation is concerned, indistinguishable from physically settled swaptions.

If the swaption survives to the exercise date and is in the money, it is settled physically for USD but in cash for EUR. GBP swaptions continue to use the swap rate based formula.

### Modelling & pricing

Swaptions use the normal model. As rates are generally close to zero, and can even be negative, the log-normal assumption used for options is inappropriate.

Some market participants use a shifted log-normal model, where instead of an underlying rate of r, a shifted rate is applied, such as r+2%. Such an approach assumes that the process is log-normal.

### Environment

Setting up your environment takes three steps:

• Import the relevant internal and external libraries

• Configure the environment parameters

• Initialise the environment

``````import sigtech.framework as sig

import datetime as dtm
import pandas as pd
import seaborn as sns

sns.set(rc = {'figure.figsize': (18, 6)})

if not sig.config.is_initialised():
env = sig.init()``````

### SABR

The SABR model is a stochastic volatility model which attempts to capture the volatility smile in derivatives markets. The model is widely used by participants in interest rate derivative markets. The standard approach when interpolating swaption volatilities is to first calibrate the SABR parameters, keeping expiry and swap tenor constant, varying the strikes, and then using them to recover the volatilities.

To price an option with a tenor existing on the (SABR) volatility surface, the normal volatility from parameters is inferred, and is used as a Bachelier (normal) pricer. If the expiry is not part of the surface, the corresponding normal volatilities for neighbouring tenors is found on the surface and linearly interpolate between them.

To view all tenors for a particular currency, the following code block can be used:

``````single_surface = sig.obj.get('USD SWAPTION SABR VOLSURFACE').get_handle(dtm.date(2021,11,10))
single_surface.market_quotes['Tenor'].squeeze().unique()``````

The following call will give all the (currency) SABR parameters for a given date:

``single_surface.market_quotes``

### Framework functionality

A Swaption can be constructed directly from `sig.Swaption()` or by using a group `get_swaption()` function.

The group itself is easily obtainable via `sig.SwaptionGroup.get_group('USD')`. Expiry can be passed as a date or as a tenor. Strike can be numerical or offset in basis points from an at-the-money forward.

Note: ATM is the equivalent of forward. 'ATM+25bp' is forward plus 0.0025.

The following command can be used to retrieve the docstrings associated with the swaption class:

``sig.Swaption?``

To retrieve the `SwaptionGroup`, the `get_group` function is used:

``usd_swaption_group = sig.SwaptionGroup.get_group('USD')``

This group name can then be passed into `sig.Swaption()` when building your instrument:

``````s = sig.Swaption(
start_date=dtm.date(2019, 12, 19),
strike='ATM+10bp',
expiry='3M',
swap_tenor='5Y',
swaption_group=usd_swaption_group.name,
currency='USD'
)``````

The history for our swaption is then tabulated:

``s.history()``

All swaptions in the framework are modelled using spot premium as default. Spot premium refers to when payment occurs at the time of entering the contract. This can be contrasted with the forward premium which refers to when payment occurs at the time of exercising the option. A forward premium implies that no initial payment, or spot premium, for the swaption is made.

This can be modelled by setting `forward_premium` to `True`, which automatically infers a forward premium from the swaption value. Or, `forward_premium` can be set to the actual pre-agreed premium, so that it is taken into account when retrieving the resulting swaption’s present value and greeks.

``````s_fp = sig.Swaption(
start_date=dtm.date(2019, 12, 19),
strike='ATM+10bp',
expiry='3M',
swap_tenor='5Y',
swaption_group=usd_swaption_group.name,
currency='USD',
)``````

We can then comparatively plot the histories of both swaptions.

``````s.history().plot()
s_fp.history().plot()``````

#### Cash vs physical settlement

The swaption group determines whether the swaption is cash or swap settled. As mentioned above, all swaptions - apart from EUR and GBP - are swap settled. Resetting the `cash_settled` field of the swaption group resets this behaviour.

It is possible to cash settle EUR swaptions (or any other currency) by setting the `cash_settled_with_swap_rate` input of the Swaption class to `True`.

#### Metrics

The main valuation function is `swaption_metrics` which computes various metrics for required dates. By default, all history dates are used and if fields are omitted, all current possible metrics—`'NPV'`, `'Delta'`, `'Gamma'`, `'Theta'`, `'Vega'`, `'ParRate'` and `'ImpliedVolatility'`—are computed.

``s.swaption_metrics()``

To plot the time series for a particular metric by specifying a field:

``s.swaption_metrics(fields = 'ATMVol').plot()``

#### Greeks

• Vega is sensitivity to a 1bp change in volatility.

• Delta is sensitivity to a 1bp change in swap rate.

• Gamma is change in delta per 1bp change in swap rate.

``s.pnl_explain()``

To plot the time series for a particular value by specifying a field:

``s.pnl_explain(fields='Actual').plot()``

### Building blocks

Like for options, we support basic functionality for rolling swaptions, straddle and strangle with `sig.RollingSwaption`, `sig.SwaptionStraddle` and `sig.SwaptionStrangle`. The parameters are the same as those used in the corresponding option strategies, with the only differences being that swaption strategies require an underlying `swap_tenor` and don’t require a `group_name`—which can be obtained by default from `currency`.

The functionality for the option strategies—`option_position_greeks`, `portfolio_greeks`, `output_option_position_diagnostics`—is largely the same.

#### `RollingSwaption`

``from sigtech.framework.strategies.rolling_swaption_baskets import RollingSwaption``
``````usd_rolling_swaption  = RollingSwaption(
start_date=dtm.date(2016, 3, 5),
maturity='6M',
currency='USD',
group_name=sig.SwaptionGroup.get_group('USD').name,
rolling_frequencies=["3M"],
swaption_type='Payer',
target_type='Fixed',
target_quantity=1000,
total_return=False,
swap_tenor='30Y'
)``````
``usd_rolling_swaption.history().plot()``
``<matplotlib.axes._subplots.AxesSubplot at 0x7f2b02a34390>``
``usd_rolling_swaption.plot.timeline()``
``usd_rolling_swaption.option_position_greeks(dtm.datetime(2018,1,5),field = 'Vega')``

#### `sig.SwaptionStraddle`

``````usd_rolling_straddle = sig.SwaptionStraddle(
start_date=dtm.date(2016, 3, 5),
maturity='6M',
currency='USD',
group_name=sig.SwaptionGroup.get_group('USD').name,
rolling_frequencies=["3M"],
strike_type='SPOT',
close_out_at_roll=True,
total_return=False,
target_type = 'Fixed',
target_quantity= 10000,
swap_tenor='5Y'
)``````
``usd_rolling_straddle.history().plot()``
``usd_rolling_straddle.portfolio_greeks()``

#### `sig.SwaptionStrangle`

``````usd_rolling_strangle = sig.SwaptionStrangle(
start_date=dtm.date(2016, 3, 5),
maturity='6M',
currency='USD',
group_name=sig.SwaptionGroup.get_group('USD').name,
rolling_frequencies=["3M"],
payer_strike = 'ATM-10bp',
close_out_at_roll=True,
total_return=False,
target_type = 'Fixed',
target_quantity= 10000,
swap_tenor='5Y'
)``````
``usd_rolling_strangle.history().plot()``

#### Delta-hedging

Like with strategies inheriting from the `rolling_options_basket` class, all swaption strategies, including `SwaptionStraddle` and `SwaptionStrangle`, can use the `DeltaHedgingStrategy` as an input with `hedging_instrument_type` set to `'UNDERLYING'`.

If `include_option_strategy` is set to `False` it will produce an equivalent strategy obtained by trading the delta amounts of the underlying swap.

If `include_option_strategy` is set to `True` it will produce a delta hedge of the original strategy.

``sig.DeltaHedgingStrategy?``
``````usd_strangle_dh = sig.DeltaHedgingStrategy(
currency = 'USD',
start_date = dtm.date(2016,3,5),
option_strategy_name = usd_rolling_strangle.name,
hedging_instrument_type = 'UNDERLYING',
include_option_strategy = False,
rebalance_hedge_on_roll= False
# you can choose for hedge adjustments to occur only on dates when the options are rolled
)``````
``usd_strangle_dh.history().plot()``
``usd_strangle_dh.plot.portfolio_table()``
``usd_strangle_dh.plot.timeline()``

``from sigtech.framework.strategies.rolling_swaption_baskets import *``
``DynamicSwaptionsStrategy?``
``DynamicMultiSwaptionsStrategy?``

### Transaction costs

A vega-based transaction cost is used, with scaling parameters defined in the `SWAPTION_VOL_TCOST` dictionary of `sigtech/framework/transaction_cost/constants.py`. There is a default scale of 5 vega basis points, and a currency specific scale of 2bp for USD and EUR (i.e. t-cost is vega*0.0002).

``sig.TradePricer.get_tc_model(s.name)``

Last updated