Options
This page shows how individual options and volatility surfaces work on the platform.
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()
To create a vanilla option on the platform, the user needs to perform the following steps:
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>')
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))
.
Input
Output
# 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
SPX 20110406 CALL 1100 604506EC INDEX <class 'sigtech.framework.instruments.options.EquityIndexOTCOption'>[4534898352]
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();

# 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();

Options can also be created explicitly from an option class without using the option group. Some of the option classes available:
- EquityIndexOTCOption
- FXOTCOption
- CommodityFutureOTCOption
Input
Output
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
SPX 20110406 CALL 1100 A6D17D99 INDEX <class 'sigtech.framework.instruments.options.EquityIndexOTCOption'>[5966872832]
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
# 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);

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);

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);

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()
%20(1)%20(2).png?alt=media)
Input
Output
vs = sig.obj.get('EURUSD VOLSURFACE')
vs
EURUSD VOLSURFACE <class 'sigtech.framework.infra.vol_surfaces.vol_surface.FXVolSurface'>[5572896224]
vs.plot_surface(d=vs.history_dates_actual()[-1], z_name='Vol')

get_vol
based on the effective date, expiry date and strike.Input
Output
vs.get_vol(dtm.date(2019, 3, 29), dtm.date(2019, 4, 28), 1.34)
0.05693914182317497
A
FXVolSurfaceIterator
class is available to simplify the retrieval of a set of volatility surfaces for a selection of currencies and associated data.Input
Output
vol_iterator = sig.FXVolSurfaceIterator(['USD', 'EUR', 'GBP'])
list(vol_iterator.iterate_surfaces())
[EURUSD VOLSURFACE <class 'sigtech.framework.infra.vol_surfaces.vol_surface.FXVolSurface'>[5572896224],
GBPUSD VOLSURFACE <class 'sigtech.framework.infra.vol_surfaces.vol_surface.FXVolSurface'>[5973002656],
EURGBP VOLSURFACE <class 'sigtech.framework.infra.vol_surfaces.vol_surface.FXVolSurface'>[5981535392]]
A list of all available surfaces can be generated using the iterator class:
Input
Output
sig.FXVolSurfaceIterator.get_all_available_surfaces_names()[:5]
['AUDBRL VOLSURFACE',
'AUDCAD VOLSURFACE',
'AUDCHF VOLSURFACE',
'AUDCNH VOLSURFACE',
'AUDHKF VOLSURFACE']
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:Input
Output
vol_iterator.get_all_available_tenors()[:10]
['-', 'O/N', 'ON', '1W', '1WK', '2WK', '2W', '3WK', '3W', '1M']
Last modified 3mo ago