Option Strategies
Short Call Butterfly
Introduction
The short call butterfly strategy is the combination of a bull call spread and a bear call spread. In the call butterfly, all of the calls should have the same underlying Equity, the same expiration date, and the same strike price distance between the ITM-ATM and OTM-ATM call pairs. The short call butterfly consists of a short ITM call, a short OTM call, and 2 long ATM calls. This strategy profits from high volatility in the underlying Equity price.
Implementation
Follow these steps to implement the short call butterfly strategy:
- In the
initialize
method, set the start date, end date, cash, and Option universe. - In the
on_data
method, select the contracts of the strategy legs. - In the
on_data
method, place the orders.
def initialize(self) -> None: self.set_start_date(2017, 2, 1) self.set_end_date(2017, 3, 5) self.set_cash(500000) self.universe_settings.asynchronous = True option = self.add_option("GOOG", Resolution.MINUTE) self._symbol = option.symbol option.set_filter(lambda universe: universe.include_weeklys().call_butterfly(30, 5))
The call_butterfly
filter narrows the universe down to just the three contracts you need to form a short call butterfly.
def on_data(self, slice: Slice) -> None: if self.portfolio.invested: return # Get the OptionChain chain = slice.option_chains.get(self._symbol, None) if not chain: return # Get the furthest expiry date of the contracts expiry = max([x.expiry for x in chain]) # Select the call Option contracts with the furthest expiry calls = [i for i in chain if i.expiry == expiry and i.right == OptionRight.CALL] if len(calls) == 0: return # Select the ATM, ITM and OTM contracts from the remaining contracts atm_call = sorted(calls, key=lambda x: abs(x.strike - chain.underlying.price))[0] itm_call = sorted(calls, key=lambda x: x.strike)[1] otm_call = [x for x in calls if x.strike == atm_call.strike * 2 - itm_call.strike][0]
Approach A: Call the OptionStrategies.short_butterfly_call
method with the details of each leg and then pass the result to the buy
method.
option_strategy = OptionStrategies.short_butterfly_call(self._symbol, otm_call.strike, atm_call.strike, itm_call.strike, expiry) self.buy(option_strategy, 1)
Approach B: Create a list of Leg
objects and then call the combo_market_order, combo_limit_order, or combo_leg_limit_order method.
legs = [ Leg.create(atm_call.symbol, 2), Leg.create(itm_call.symbol, -1), Leg.create(otm_call.symbol, -1) ] self.combo_market_order(legs, 1)
If the Option is American Option, there is a risk of early assignment on the contracts you sell.
Strategy Payoff
The short call butterfly is a limited-reward-limited-risk strategy. The payoff is
COTMT=(ST−KOTM)+CITMT=(ST−KITM)+CATMT=(ST−KATM)+PT=(2×CATMT−COTMT−CITMT−2×CATM0+CITM0+COTM0)×m−fee whereCOTMT=OTM call value at time TCITMT=ITM call value at time TCATMT=ATM call value at time TST=Underlying asset price at time TKOTM=OTM call strike priceKITM=ITM call strike priceKATM=ATM call strike pricePT=Payout total at time TCITM0=ITM call value at position opening (credit received)COTM0=OTM call value at position opening (credit received)CATM0=ATM call value at position opening (debit paid)m=Contract multiplierT=Time of expirationThe following chart shows the payoff at expiration:

The maximum profit is the net credit received: CITM0+COTM0−2×CATM0. It occurs when the underlying price is less than ITM strike or greater than OTM strike at expiration.
The maximum loss is KATM−KITM+CITM0+COTM0−2×CATM0. It occurs when the underlying price is at the same level as when you opened the trade.
If the Option is American Option, there is a risk of early assignment on the contracts you sell.
Example
The following table shows the price details of the assets in the short call butterfly:
Asset | Price ($) | Strike ($) |
---|---|---|
OTM call | 4.90 | 767.50 |
ATM call | 15.00 | 800.00 |
ITM call | 41.00 | 832.50 |
Underlying Equity at expiration | 829.08 | - |
Therefore, the payoff is
COTMT=(ST−KOTM)+=(767.50−829.08)+=0CITMT=(ST−KITM)+=(832.50−829.08)+=3.42CATMT=(ST−KATM)+=(800.00−829.08)+=0PT=(−COTMT−CITMT+2×CATMT−2×CATM0+CITM0+COTM0)×m−fee=(−0−3.42+0×2+4.90+41.00−15.00×2)×100−1.00×4=−1252So, the strategy gains $1,244.
The following algorithm implements a short call butterfly Option strategy:
class LongCallButterflyStrategy(QCAlgorithm): def initialize(self) -> None: self.set_start_date(2017, 2, 1) self.set_end_date(2017, 3, 6) self.set_cash(500000) option = self.add_option("GOOG", Resolution.MINUTE) self.symbol = option.symbol option.set_filter(self.universe_func) def universe_func(self, universe: OptionFilterUniverse) -> OptionFilterUniverse: return universe.include_weeklys().call_butterfly(30, 5) def on_data(self, data: Slice) -> None: # avoid extra orders if self.portfolio.invested: return # Get the OptionChain of the self.symbol chain = data.option_chains.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 option_strategy = OptionStrategies.short_butterfly_call(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)
Other Examples
For more examples, see the following algorithms: