Option Strategies

Iron Butterfly

Introduction

The Iron Butterfly is an option strategy which involves four option contracts, where all options have the same underlying stock and expiration. The order of strike prices for the four contracts is $A>B>C$.

PositionStrike
1 OTM call $A$
1 ATM call $B$
1 ATM put $B$
1 OTM put $C=B-(A-B)$

Long Iron Butterfly

It consists of selling an OTM call, selling an OTM put, buying an ATM call and buying an ATM put. It is a option strategy profitting from an decrease in price movement (implied volatility).

This is a limited-reward-limited-risk strategy. The payoff is as follows:

$Payoff_{OTM\ call}=(Price_{underlying}-Strike_{OTM\ call})^{+}$

$Payoff_{ATM\ call}=(Price_{underlying}-Strike_{ATM\ call})^{+}$

$Payoff_{ATM\ put}=(Strike_{ATM\ put}-Price_{underlying})^{+}$

$Payoff_{OTM\ put}=(Strike_{OTM\ put}-Price_{underlying})^{+}$

$$Profit/Loss=(Payoff_{ATM\ call}+Payoff_{ATM\ put}-Payoff_{OTM\ call}-Payoff_{OTM\ put}\\ \quad+credit\ received_{OTM\ call}+credit\ received_{OTM\ put}-debit\ paid_{ATM\ call}-debit\ paid_{ATM\ put})\\ \quad\times multiplier-commissions$$

The maximum profit is $Strike_{OTM\ call}-Strike_{ATM\ call}$ minus net debit paid when opening the trade, where the underlying price fell below the OTM put strike or above the OTM call strike price at expiration.

Maximum loss is the net debit paid after commission when opening the trade, where the underlying price stays the same as the trade opens.

If the option is American option, there will be a risk of early assignment on the shorted option.

Short Call Butterfly

It consists of buying an OTM call, buying an OTM put, selling an ATM call and selling an ATM put. It is a option strategy profitting from an increase in price movement (implied volatility), as well as time decay value since ATM options decay sharper.

This is a limited-reward-limited-risk strategy. The payoff is as follows:

$$Profit/Loss=(Payoff_{OTM\ call}+Payoff_{OTM\ put}-Payoff_{ATM\ call}-Payoff_{ATM\ put}\\ \quad+credit\ received_{ATM\ call}+credit\ received_{ATM\ put}-debit\ paid_{OTM\ call}-debit\ paid_{OTM\ put})\\ \quad\times multiplier-commissions$$

The maximum profit is the net credit received after commission when opening the trade, where the underlying price stays the same as the trade opens.

Maximum loss is $Strike_{OTM\ call}-Strike_{ATM\ call}$ minus net credit received when opening the trade, where the underlying price fell below the OTM put strike or above the OTM call strike price at expiration.

If the option is American option, there will be a risk of early assignment on the shorted option.

Implementation

Follow these steps to implement the Short Iron Butterfly strategy.

  1. In the Initialize method, set the start date, end date, cash, and Option universe.
  2. private Symbol _symbol;
    
    public override void Initialize()
    {
        SetStartDate(2017, 4, 1);
        SetEndDate(2017, 5, 10);
        SetCash(100000);
    
        var option = AddOption("GOOG", Resolution.Minute);
        _symbol = option.Symbol;
        option.SetFilter(universe => universe.Strikes(-10, 10)
                                                .Expiration(TimeSpan.FromDays(0), TimeSpan.FromDays(30)));
    }
    def Initialize(self) -> None:
        self.SetStartDate(2017, 4, 1)
        self.SetEndDate(2017, 5, 10)
        self.SetCash(100000)
    
        option = self.AddOption("GOOG", Resolution.Minute)
        self.symbol = option.Symbol
        option.SetFilter(-10, 10, timedelta(0), timedelta(30))
  3. Break the candidate contracts into the call and put options.
  4. public override void OnData(Slice slice)
    {
        if (Portfolio.Invested) return;
    
        // Get the OptionChain of the symbol
        var chain = slice.OptionChains.get(_symbol, null);
        if (chain == null || chain.Count() == 0) return;
    
        // filter the call options from the contracts which is ATM in the option chain.
        var calls = chain.Where(x => x.Right == OptionRight.Call);
        var puts = chain.Where(x => x.Right == OptionRight.Put);
        if (calls.Count() == 0 || puts.Count() == 0) return;
    def OnData(self, slice: Slice) -> None:
        # avoid extra orders
        if self.Portfolio.Invested: return
    
        # Get the OptionChain of the self.symbol
        chain = slice.OptionChains.get(self.symbol, None)
        if not chain: return
    
        # filter the call and put options from the contracts
        call = [i for i in chain if i.Right == 0]
        put = [i for i in chain if i.Right == 1]
        if len(call) == 0 or len(put) == 0 : continue
  5. Find the specific contracts to trade. At the money options have the minimum absolute difference between the underlying price and the strike price.
  6.     // get at-the-money strike
        var atmStrike = chain.OrderBy(x => Math.Abs(x.Strike - chain.Underlying.Price)).First().Strike;
    
        // Get the furthest OTM contracts by strike prices
        var otmCallContract = calls.OrderBy(x => x.Strike).Last();
        var otmPutContract = puts.OrderBy(x => x.Strike).First();
    
        // Get ATM contracts
        var atmCallContract = calls.Where(x => x.Strike == atmStrike).First();
        var atmPutsContract = puts.Where(x => x.Strike == atmStrike).First();
    
        // Sell 1 ATM Put
        Sell(atmPutsContract.Symbol, 1);
        // Sell 1 ATM Call
        Sell(atmCallContract.Symbol, 1);
        // Buy 1 OTM Call
        Buy(otmCallContract.Symbol, 1);
        // Buy 1 OTM Put
        Buy(otmPutContract.Symbol, 1);
    }
    call_contracts = sorted(call, key = lambda x: x.Strike)
    put_contracts = sorted(put, key = lambda x: x.Strike)
    
    # Sell 1 ATM Put
    self.atm_put = sorted(put_contracts, key = lambda x: abs(chain.Underlying.Price - x.Strike))[0]
    self.Sell(self.atm_put.Symbol, 1)
    # Sell 1 ATM Call
    self.atm_call = sorted(call_contracts, key = lambda x: abs(chain.Underlying.Price - x.Strike))[0]
    self.Sell(self.atm_call.Symbol, 1)
    # Buy 1 OTM Call
    self.otm_call = call_contracts[-1]
    self.Buy(self.otm_call.Symbol, 1)
    # Buy 1 OTM Put
    self.otm_put = put_contracts[0]
    self.Buy(self.otm_put.Symbol, 1)

Summary

In this algorithm, we've realised the below payout at expiration (2017-4-22).

ItemsPrice
Price of OTM call$ 1.85
Price of OTM put$ 2.75
Price of ATM call$ 8.10
Price of ATM put$ 7.40
Strike of OTM call$ 857.50
Strike of OTM put$ 810.00
Strike of ATM call$ 832.00
Strike of ATM put$ 832.00
Price of underlying at expiration$ 851.20
Commission per trade$ 1.00
$Payoff_{OTM\ call}=(851.20-857.50)^{+}=0$

$Payoff_{ATM\ call}=(851.20-832.00)^{+}=19.20$

$Payoff_{ATM\ put}=(832.00-851.20)^{+}=0$

$Payoff_{OTM\ put}=(810.00-851.20)^{+}=0$

$Profit/Loss=(0+0-19.20-0+8.10+7.40-1.85-2.75)\times100-1\times4=-834$

So, the strategy losses $834.

Algorithm

Backtest using SetFilter

Backtest using OptionChainProvider

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: