This page shows how individual options and volatility surfaces work on the platform.
Environment
Setting up your environment takes three steps:
Import the relevant internal and external libraries
Configure the environment parameters
Initialise the environment
Copy 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:
Copy 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:
Copy 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
Input Output
Copy # 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
Copy 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.
Copy 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
Copy # 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 ))
Copy 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:
Input Output
Copy 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
Copy SPX 20110406 CALL 1100 A6D17D99 INDEX <class 'sigtech.framework.instruments.options.EquityIndexOTCOption'>[5966872832]
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
Copy # Step 2)
digital = eur_usd_group . get_option ( 'Call' , 1.3 , dtm. date ( 2010 , 4 , 6 ),
dtm. date ( 2011 , 4 , 6 ), digital = True )
Copy 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
Copy 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 )
Copy 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 ) ;
Copy 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 )
Copy 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
Copy 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 )
Copy 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:
Copy 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.
Copy equity_option . option_metrics (
fields = [ 'Delta' , 'ImpliedVolatility' ], vol_override = 0.12 ). head ()
Vol surface
Retrieve vol surface object
Input Output
Copy vs = sig . obj . get ( 'EURUSD VOLSURFACE' )
vs
Copy EURUSD VOLSURFACE <class 'sigtech.framework.infra.vol_surfaces.vol_surface.FXVolSurface'>[5572896224]
Copy 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
Copy 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.
Input Output
Copy vol_iterator = sig . FXVolSurfaceIterator ([ 'USD' , 'EUR' , 'GBP' ])
list (vol_iterator. iterate_surfaces ())
Copy [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
Copy sig . FXVolSurfaceIterator . get_all_available_surfaces_names () [ : 5 ]
Copy ['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:
Copy implied_1m_vol_history_df = vol_iterator . atm_vols_for_tenor ( '1M' )
implied_1m_vol_history_df . plot (title = 'Historical Implied Volatilities' ) ;
Copy 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
Copy vol_iterator.get_all_available_tenors()[:10]
Copy [ '-' , 'O/N' , 'ON' , '1W' , '1WK' , '2WK' , '2W' , '3WK' , '3W' , '1M' ]