Hi,

I’m experimenting with option vertical spreads. I’m using the code sample from the tutorial - https://www.quantconnect.com/tutorials/applied-options/bull-call-spread

I’ve encountered the following.

  1. The AddOption method seems to return only monthly contracts, even after I’ve removed all the filters. Should I do something differently, to get weekly contracts as well?

2. I’ve also tested using the OptionChainProvider method. That one shows the weeklys - ex. 20220209 contracts. But that runs into a different issue. When I place an order, I get the error message “SPY XVVXI02W73VQ|SPY R735QTJ8XC9X) was not found in your security list”. When I inspect the data, it shows the correct contract (ex. SPY 220209C00446000)

My code for #1 is below. I've attached the Project and Backtest for #2

Hope someone can point me out if I'm missing something.

Thanks

#########################

##1. AddOption code

from AlgorithmImports import *

from datetime import timedelta

class BullCallSpreadAlgorithm(QCAlgorithm):
def Initialize(self):

self.SetStartDate(2022, 2, 7)

self.SetEndDate(2022, 2, 8)

self.SetCash(500000)

ticker = 'SPY'

equity = self.AddEquity(ticker, Resolution.Daily)

option = self.AddOption(ticker, Resolution.Daily)

self.symbol = option.Symbol

# set our strike/expiry filter for this option chain

# option.SetFilter(-7, 7, timedelta(30), timedelta(60))

 

def OnData(self,slice):

try:

optionchain = slice.OptionChains

expiry_dates = []

for i in slice.OptionChains:

if i.Key != self.symbol: continue

chains = i.Value

contract_list = [x for x in chains]

# if there is no contracts in this optionchain, pass the instance

if (slice.OptionChains.Count == 0) or (len(contract_list) == 0):

return

# if there is no securities in portfolio, trade the options

if not self.Portfolio.Invested:

self.TradeOptions(optionchain)

except Exception as e:

self.Log (e.message)

def TradeOptions(self,optionchain):

try:

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=False)[0].Expiry

# filter the call options from the contracts expires on that date

call = [i for i in chain if i.Expiry == expiry and i.Right == 0]

# sorted the contracts according to their strike prices

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]

underlying_price = chain.Underlying.Price

self.Log ('underlying_price = ' + str (underlying_price))

self.Log(self.call_low)

self.Log(self.call_high)

self.Buy(self.call_low.Symbol, 1)

self.Sell(self.call_high.Symbol ,1)

except Exception as e:

self.Log (e.message)

 

def OnOrderEvent(self, orderEvent):

self.Log(str(orderEvent))