Tutorial: iron butterfly option strategy

Beginner tutorial on creating a systematic strategy which is short volatility via a short at-the-money straddle and a long out-of-the-money strangle.

Introduction

The purpose of this tutorial is to show users that are new to the SigTech platform how to construct an Iron Butterfly Option Strategy – which is a popular investment strategy to profit from a low volatility environment. The strategy will short volatility and thus capture the volatility risk premium, whilst hedging against large movements in the underlying asset. This tutorial is specifically targeted towards new users.

A notebook containing all the code used in this page can be accessed via your research environment's File Browser. See Example notebooks.

To be able to run the related Jupyter notebook the appropriate data entitlements needs to be in place for your organisation. If you would like to access SigTech's Volatility data, please contactsales@Sigtech.com

Workflow overview

When creating an investment strategy on the SigTech platform, the workflow tends to follow these steps:

  1. Set up the environment

  2. Define the investment universe

  3. Create the strategy

  4. Construct the portfolio

  5. Generate the performance report

This tutorial will go through the above-mentioned steps, and explain each one in turn. Additionally, there will be links to more in-depth information to allow for further learning.

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
from sigtech.framework.schedules import SchedulePeriodic
import sigtech.framework.infra.cal as cal

import datetime as dtm
import seaborn as sns

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

Define the investment universe

In this step, the user will define the volatility product that will form the universe of the investment strategy. For further details on which products are available on the platform, please see the Market Data Browser.

In this example, the underlying asset in the strategy will be the S&P 500 Index (SPX). The options that form part of the strategy are cash settled, i.e. they will not convert into actual stock holdings if the investor is long a SPX option.

Below are some of the constants used in the strategy definition:

straddle_dir = 'SHORT'
strangle_dir = 'LONG'
maturity = '1M'
delta_strangle = 0.05
option_grp = sig.obj.get('SPX INDEX OTC OPTION GROUP')

Define the relevant start date to be used when creating the strategy.

start_date = dtm.datetime(2010, 1, 4)

Create the strategy

The Iron Butterfly Option Strategy is a strategy that tries to capture the volatility risk premium, i.e. the investor using the strategy can be considered short volatility. More concretely, the strategy consists of one strangle and one straddle. It's a short straddle at-the-money and a long strangle out-of-the-money. The idea is that the investor receives a net positive inflow of premiums, since the premium gains from the short straddle is higher than the premium cost of the long strangle. Furthermore, the strategy can be considered non-directional since from the point of the strikes of the strangles, the strategy is market neutral.

First, the Straddle is defined as per below code block:

atm_straddle = sig.Straddle(
    # Specify the currency the strategy will be denominated in
    currency='USD',
    
    # Start date of the strategy
    start_date=start_date,
    
    # Name of the option group to trade options for 
    group_name=option_grp.name,
    
    # Strike type set to ATM of the underlying
    strike_type='SPOT',
    
    # Maturity or tenor of underlying options
    maturity=maturity,

    # Set roll dates date of the strategy
    rolling_frequencies=[maturity],
    
    # Target Quantity to trade at each roll (denoted in contracts)
    target_quantity=-1 if straddle_dir == 'SHORT' else 1,
    
    # Name of strategy
    ticker=f'{straddle_dir} SPX OTC STRADDLE ATM'
)

The Strangle will be + / - 5% out-of-the-money on each leg:

oom_strangle = sig.Strangle(
    # Specify the currency the strategy will be denominated in
    currency='USD',

    # Start date of the strategy
    start_date=start_date,

    # Name of the option group to trade options for 
    group_name=option_grp.name,

    # Strike type of the underlying options 
    strike_type='Delta',

    # Strike of Call (in delta)
    call_strike=delta_strangle,

     # Strike of Put (in delta)
    put_strike=-1 * delta_strangle,

    # Maturity or tenor of underlying options
    maturity=maturity,

    # Set roll dates date of the strategy
    rolling_frequencies=[maturity],

    # Target Quantity to trade at wach roll (denoted in contracts)
    target_quantity=1 if strangle_dir == 'LONG' else -1,

    # Name of strategy
    ticker=f'{strangle_dir} SPX OTC STRANGLE {delta_strangle}',
)

Store both the straddle and the strangle strategy objects in a list.

strategies = [atm_straddle, oom_strangle]

Construct the portfolio

The strangle and straddle can be combined into one strategy with the BasketStrategy building block.

But prior to creating a BasketStrategy object, we need to create a custom roll table. The custom roll table is created for aligning the rebalancing of the BasketStrategy with the rolling of straddle and strangle options.

The custom roll table is created by using the SchedulePeriodic class as shown below:

roll_ds = SchedulePeriodic(
    # Start date of custom roll table
    start_date=start_date,
    
    # End date of custom roll table, which is
    # taken from the environment variable
    end_date=env.asofdate,
    
    # Holidays
    holidays=option_grp.holidays,
    
    # Business day count
    bdc=cal.BDC_FOLLOWING,
    
    # Frequency
    frequency='1M',
).all_data_dates()[1:]

The BasketStrategy object allows for creating long only basket strategies with fixed weights and rebalanced according to set frequency. For portfolio rebalancing, we would ideally like to coincide our basket rebalancing date with our option roll date. We can do this by passing a custom roll table to the BasketStrategy object.

basket_strategy = sig.BasketStrategy(
    # Specify the currency the strategy will be denominated in
    currency='USD',
    
    # List of constituent tickers
    constituent_names=[
        strategy.name for strategy in strategies
    ],
    
    # Start date of strategy
    start_date=start_date,
    
    # List of constituents weights expressed as floats.
    weights=[1/len(strategies)]*len(strategies),
    
    # List of customised roll dates
    rebalance_dates=roll_ds,
    
    # Name of strategy
    ticker=f'IRON BUTTERFLY'
)

Generate the performance report

After having created the strategy, the script below can be used to create a performance report which contains information on metrics, rolling performance charts and performance calendar. There are a wide range of different performance views and reports available for the user which might be relevant depending on the specific use case. See Performance Analytics for further information on different performance reports, views and metrics.

strategies.append(basket_strategy)
sig.PerformanceReport(
    strategies, 
    cash=sig.CashIndex.from_currency('USD')
).report()

Next steps

The following resources are available for continued learning:

Last updated

© 2023 SIG Technologies Limited