Options

This page shows how individual options and volatility surfaces work on the platform.

Learn more: Example notebooks

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)})
sig.config.init()

Vanilla Options

Overview

To create a vanilla option on the platform, the user needs to perform the following steps:

1) Get option group

The available option groups can be viewed in the Market Data Browser. To retrieve an option group the following syntax is used, where the user inserts the relevant option group name:

option_group = sig.obj.get('<Insert Relevant Option Group Name>')

2) Create option

The option is then retrieved by calling the .get_option() method on the option group object. Below is an example of such script:

option = option_group.get_option(
    option_type='Call', 
    strike=1100, 
    start_date=dtm.date(2010, 4, 6), 
    maturity=dtm.date(2011, 4, 6)
)

If you're getting an option for a futures group (such as CO COMDTY OTC OPTION GROUP) the maturity date must match an expiration date of one of the futures in the group. To find a valid maturity date that is closest to a given a date, use the following method: option.available_maturity(dtm.date(2011,4,6)).

Example: Index OTC option

# Step 1) Getting the option group
equity_option_group = sig.obj.get('SPX INDEX OTC OPTION GROUP')

# Step 2) Creating the option
spx_call_option = equity_option_group.get_option(
    option_type='Call', 
    strike=1100, 
    start_date=dtm.date(2010, 4, 6), 
    maturity=dtm.date(2011, 4, 6)
)
spx_call_option

We can also plot the valuation of each option. This is compared below to the underlying minus the strike.

pd.concat({
    'Spot - strike (1100)': spx_call_option.underlying_object.history() - 1100,
    'Option price': spx_call_option.history()
}, axis=1).dropna().plot();

Example: FX OTC option

# Step 1) Getting the option group
eur_usd_group = sig.FXOTCOptionsGroup.get_group('USDEUR')

# Step 2) Creating the option
eurusd_call_option = eur_usd_group.get_option('Call', 1.3, dtm.date(2010, 4, 6), 
                                              dtm.date(2011, 4, 6))
pd.concat({
    'Spot - strike (1.3)': eurusd_call_option.underlying_object.history() - 1.3,
    'Option price': eurusd_call_option.history()
}, axis=1).dropna().plot();

Alternative way of creating options

Options can also be created explicitly from an option class without using the option group. Some of the option classes available:

  • EquityIndexOTCOption

  • FXOTCOption

  • CommodityFutureOTCOption

equity_option = sig.EquityIndexOTCOption(
    currency='USD',
    maturity_date=dtm.date(2011, 4, 6),
    option_type='Call',
    start_date=dtm.date(2010, 4, 6),
    strike=1100,
    underlying='SPX INDEX',
)
equity_option

Exotic options

Overview

When dealing with other options apart from vanilla options, it's easy to modify the .get_options() method depending on use case. The available exotic options are:

  • Digital

  • Barriers (KO & KI)

  • One-touch & No-touch

Digital

# Step 2)
digital = eur_usd_group.get_option('Call', 1.3, dtm.date(2010, 4, 6), 
                                   dtm.date(2011, 4, 6), digital=True)
pd.concat({
    'Spot - strike (1.3)': digital.underlying_object.history() - 1.3,
    'Option price': digital.history()
}, axis=1).dropna().plot(subplots=True);

Barriers: KO & KI

ki_barrier_1 = eur_usd_group.get_option('Call', 1.3,
                                        dtm.date(2010, 4, 6), dtm.date(2011, 4, 6),
                                        barrier_type='KI', barrier=1.5)
ki_barrier_2 = eur_usd_group.get_option('Call', 1.3,
                                        dtm.date(2010, 4, 6), dtm.date(2011, 4, 6),
                                        barrier_type='KI', barrier=1.4)
pd.concat({
    'Spot - strike (1.3)': ki_barrier_1.underlying_object.history() - 1.3,
    'Option price (1.4 barr.)': ki_barrier_2.history(),
    'Option price (1.5 barr.)': ki_barrier_1.history()
}, axis=1).dropna().plot(subplots=True);
ko_barrier_1 = eur_usd_group.get_option('Call', 1.3,
                                        dtm.date(2010, 4, 6), dtm.date(2011, 4, 6),
                                        barrier_type='KO', barrier=1.5)
ko_barrier_2 = eur_usd_group.get_option('Call', 1.3,
                                        dtm.date(2010, 4, 6), dtm.date(2011, 4, 6),
                                        barrier_type='KO', barrier=1.4)
pd.concat({
    'Spot - strike (1.3)': ko_barrier_1.underlying_object.history() - 1.3,
    'Option price (1.4 barr.)': ko_barrier_2.history(),
    'Option price (1.5 barr.)': ko_barrier_1.history()
}, axis=1).dropna().plot(subplots=True);

One-touch & no-touch

ot_barrier = eur_usd_group.get_option('Call', 1.4,
                                      dtm.date(2010, 4, 6), dtm.date(2011, 4, 6),
                                      barrier_type='OT', digital=True)
nt_barrier = eur_usd_group.get_option('Call', 1.4,
                                      dtm.date(2010, 4, 6), dtm.date(2011, 4, 6),
                                      barrier_type='NT', digital=True)
pd.concat({
    'Spot - strike (1.3)': ot_barrier.underlying_object.history() - 1.3,
    'Option price (One-touch 1.4)': ot_barrier.history(),
    'Option price (No-touch 1.4)': nt_barrier.history()
}, axis=1).dropna().plot(subplots=True);

Greeks

The greeks for each option can be queried in the following way:

equity_option.option_metrics().head()

The vol can be overwritten in the greek calculation. This override can be specified as a float or time series of vols.

equity_option.option_metrics(
    fields=['Delta', 'ImpliedVolatility'], vol_override=0.12).head()

Vol surface

Retrieve vol surface object

vs = sig.obj.get('EURUSD VOLSURFACE')
vs
vs.plot_surface(d=vs.history_dates_actual()[-1], z_name='Vol')

get_vol based on the effective date, expiry date and strike.

vs.get_vol(dtm.date(2019, 3, 29), dtm.date(2019, 4, 28), 1.34)

Vol surface iterator

A FXVolSurfaceIterator class is available to simplify the retrieval of a set of volatility surfaces for a selection of currencies and associated data.

vol_iterator = sig.FXVolSurfaceIterator(['USD', 'EUR', 'GBP'])
list(vol_iterator.iterate_surfaces())

A list of all available surfaces can be generated using the iterator class:

sig.FXVolSurfaceIterator.get_all_available_surfaces_names()[:5]

Using the FXVolSurfaceIterator instance, you can obtain the historical implied ATM volatilities and risk reversals:

implied_1m_vol_history_df = vol_iterator.atm_vols_for_tenor('1M')
implied_1m_vol_history_df.plot(title='Historical Implied Volatilities');
rr_history_df = vol_iterator.risk_reversal('1M', 25)
rr_history_df.plot(title='Historical Risk Reversal (25 Delta)');

The available tenors can be listed with the get_all_available_tenors method:

vol_iterator.get_all_available_tenors()[:10]

Last updated

© 2023 SIG Technologies Limited