Option Strategies

Call Butterfly

Introduction

Call butterfly is the combination of a bull call spread and a bear call spread. All calls have the same underlying stock and the same expiration date, and the strike price distance of ITM-ATM and OTM-ATM call pairs are the same.

Long Call Butterfly

It consists of buying an ITM call & an OTM call, while selling 2 ATM calls. It is a option strategy profitting from a low volatility.

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

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

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

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

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

The maximum profit is the range of 1 strike spread (ATM strike - ITM strike) minus net debit paid when opening the trade after commission, if the underlying price is staying the same as the trade opened at expiration, where combined bull and bear call spreads' payouts at its maximum.

Maximum loss is the net debit paid after commission when opening the trade, where the underlying price is less than ITM strike or greater than OTM strike.

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

Short Call Butterfly

It consists of selling an ITM call & an OTM call, while buying 2 ATM calls. It is a option strategy profitting from a drastic change in underlying price.

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

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

The maximum profit is the net credit received after commission when opening the trade, if the underlying price less than ITM strike or greater than OTM strike at expiration.

Maximum loss is the range of 1 strike spread (ATM strike - ITM strike) minus net credit received when opening the trade after commission, where the underlying price is at the same level when the trade opened.

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 call 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, 2, 1);
        SetEndDate(2017, 3, 5);
        SetCash(500000);
    
        var option = AddOption("GOOG", Resolution.Minute);
        _symbol = option.Symbol;
        option.SetFilter(universe => universe.IncludeWeeklys()
                                                .Strikes(-15, 15)
                                                .Expiration(TimeSpan.FromDays(0), TimeSpan.FromDays(31)));
    }
    def Initialize(self) -> None:
        self.SetStartDate(2017, 2, 1)
        self.SetEndDate(2017, 3, 5)
        self.SetCash(500000)
    
        option = self.AddOption("GOOG", Resolution.Minute)
        self.symbol = option.Symbol
        option.SetFilter(self.UniverseFunc)
    
    def UniverseFunc(self, universe: OptionFilterUniverse) -> OptionFilterUniverse:
        return universe.IncludeWeeklys().Strikes(-15, 15).Expiration(timedelta(0), timedelta(31))
  3. In the OnData method, select the Option contracts.
  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;
    
        // sorted the optionchain by expiration date and choose the furthest date
        var expiry = chain.OrderByDescending(x => x.Expiry).First().Expiry;
        
        // filter the call options from the contracts which expire on the furthest expiration date in the option chain.
        var calls = chain.Where(x => x.Expiry == expiry && x.Right == OptionRight.Call);
        if (calls.Count() == 0) return;
    
        // sort the call options with the same expiration date according to their strike price.
        var callStrikes = calls.Select(x => x.Strike).OrderBy(x => x);
    
        // get at-the-money strike
        var atmStrike = calls.OrderBy(x => Math.Abs(x.Strike - chain.Underlying.Price)).First().Strike;
    
        // Get the distance between lowest strike price and ATM strike, and highest strike price and ATM strike. 
        // Get the lower value as the spread distance as equidistance is needed for both side.
        var spread = Math.Min(Math.Abs(callStrikes.First() - atmStrike), Math.Abs(callStrikes.Last() - atmStrike));
    
        // select the strike prices for forming the option legs
        var itmStrike = atmStrike - spread;
        var otmStrike = atmStrike + spread;
    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
    
        # sorted the optionchain by expiration date and choose the furthest date
        expiry = sorted(chain, key = lambda x: x.Expiry, reverse=True)[0].Expiry
        
        # filter the call options from the contracts which expire on the furthest expiration date in the option chain.
        calls = [i for i in chain if i.Expiry == expiry and i.Right == OptionRight.Call]
        if len(calls) == 0: return
    
        # sort the call options with the same expiration date according to their strike price.
        call_strikes = sorted([x.Strike for x in calls])
    
        # get at-the-money strike
        atm_strike = sorted(calls, key=lambda x: abs(x.Strike - chain.Underlying.Price))[0].Strike
    
        # Get the distance between lowest strike price and ATM strike, and highest strike price and ATM strike. 
        # Get the lower value as the spread distance as equidistance is needed for both side.
        spread = min(abs(call_strikes[0] - atm_strike), abs(call_strikes[-1] - atm_strike))
    
        # select the strike prices for forming the option legs
        itm_strike = atm_strike - spread
        otm_strike = atm_strike + spread
  5. In the OnData method, call the OptionStrategies.CallButterfly method and then submit the order.
  6.     var optionStrategy = OptionStrategies.CallButterfly(_symbol, otmStrike, atmStrike, itmStrike, expiry);
        // We open a position with 1 unit of the option strategy
        Buy(optionStrategy, 1);    // if long call butterfly
        Sell(optionStrategy, 1);   // if short call butterfly
    }
    option_strategy = OptionStrategies.CallButterfly(self.symbol, otm_strike, atm_strike, itm_strike, expiry)
    # We open a position with 1 unit of the option strategy
    self.Buy(option_strategy, 1)    # if long call butterfly
    self.Sell(option_strategy, 1)   # if short call butterfly

Summary

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

ItemsPrice
Price of OTM call$ 4.90
Price of ITM call$ 41.00
Price of ATM call$ 15.00
Strike of OTM call$ 767.50
Strike of ITM call$ 832.50
Strike of ATM call$ 800.00
Price of underlying at expiration$ 829.08
Commission per trade$ 1.00
$Payoff_{OTM\ call}=(767.50-829.08)^{+}=0$

$Payoff_{ITM\ call}=(832.50-829.08)^{+}=3.42$

$Payoff_{ATM\ call}=(800.00-829.08)^{+}=0$

$Profit/Loss=(0+3.42-0\times2-4.90-41.00+15.00\times2)\times100-1.00\times4=-1252$

So, the strategy losses $1252.

Algorithm

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: