Applied Options
Bull Call Spread
Definition
Bull Call Spread is an options strategy involving two call option contracts with the same expiration but different strikes. The strategy buys one call option with a lower strike and sells another call option with a higher strike price.
This strategy creates a ceiling and floor for the profit. By purchasing a call and selling a call with higher strike simultaneously, traders can reduce the cost of just one long call option with the premium of a short call option. But the premium of ITM call is more expensive than the OTM call. The strategy limits the loss resulting from a drop in the price of the underlying stock but still creates a ceiling to the profit while the underlying price is increasing.
Take GOOG as an example. If the share price of GOOG is $950 at time 0, the premium of ITM call option is 20 with strike 900 and the premium of OTM call option is 2 with strike 1000. If we ignore the commission, dividends and other transaction fees, the payoff of Bull Call Spread strategy is as follows:
price = np.arange(800,1100,1) k_low = 900 # lower strike price for call k_high = 1000 # higher strike price for call premium_low = 20 # premium of call option with lower strike premium_high = 2 # premium of call option with higher strike # long call with lower strike payoff_long_call = [max(-premium, i-k_low-premium_low ) for i in price] # short call with higher strike payoff_short_call = [min(premium, -(i-k_high-premium_high)) for i in price] payoff = np.sum([payoff_long_call, payoff_short_call], axis=0) plt.figure(figsize=(20,11)) plt.plot(price, payoff_long_call, label = 'long call') plt.plot(price, payoff_short_call, label = 'short call') plt.plot(price, payoff, label = 'Bull Call Spread') plt.legend(fontsize = 20) plt.xlabel('Stock Price at Expiry',fontsize = 15) plt.ylabel('payoff',fontsize = 15) plt.title('Bull Call Spread Payoff at Expiration',fontsize = 20) plt.grid(True)

From the payoff plot we can see, the maximum payoff of the strategy is the difference between the option strike prices minus the difference between the premiums.
Implementation
Step 1: First, you need to initialize the algorithm including set the start date, end date and the cash required. Then use option.SetFilter(-6, 6, timedelta(30), timedelta(60))
to filter the candidate contracts which expire in 30 days to 60 days from now on. The strike price range involves both ITM and OTM options. Then we get the option chains of GOOG.
def Initialize(self): self.SetStartDate(2016, 5, 1) self.SetEndDate(2016, 10, 1) self.SetCash(200000) equity = self.AddEquity("GOOG", Resolution.Minute) option = self.AddOption("GOOG", Resolution.Minute) self.symbol = option.Symbol # set our strike/expiry filter for this option chain option.SetFilter(-6, 6, timedelta(30), timedelta(60)) # use the underlying equity GOOG as the benchmark self.SetBenchmark(equity.Symbol)
Step 2: Choose the contracts with the same expiration date. For demonstration purpose here we sorted the contracts by their expiration dates and choose the options with the furthest expiration date in the option chain.
def TradeOptions(self,optionchain): for i in optionchain: if i.Key != self.symbol: continue chain = i.Value # sorted the optionchain by expiration date and choose the furthest date expiry = sorted(chain,key = lambda x: x.Expiry, reverse=True)[0].Expiry
Step 3: Filter the call options from the contracts which expire on the furthest expiration date in the option chain.
call = [i for i in chain if i.Expiry == expiry and i.Right == OptionRight.Call]
Step 4: Sort the call options with the same expiration date according to their strike price. Then buy the call option with the lowest strike price and sell the call with the highest strike price.
call_contracts = sorted(call,key = lambda x: x.Strike) if len(call_contracts) == 0: continue # call option contract with lower strike self.call_low = call_contracts[0] # call option contract with higher strike self.call_high = call_contracts[-1] self.Buy(self.call_low.Symbol, 1) self.Sell(self.call_high.Symbol ,1)
Note here you need to add the following rules in OnData(self,slice)
method because you only need to trade options once and wait until the contracts expire. If you already had securities invested in the portfolio, then you do not need to trade new options.
if not self.Portfolio.Invested: self.TradeOptions(optionchain)
Summary
This strategy can be implemented when you have a moderate outlook on the stock because the payoff reaches its maximum when the price is between the strike price range of two traded options. The strategy protects the downside move of the stock price. But when the price is above the higher strike, the profit is capped.
You can also see our Documentation and Videos. You can also get in touch with us via Discord.
Did you find this page helpful?