Hello, greatly appreciate help getting a program to work as intended. In the first options tutorial “ data.OptionChains” data was used to get the option chains however that is not applicable to this code.
The program scans the top 500 dollar volume stocks for premarket gaps & buy options contracts when found however the tutorial does not explain how accomplish that to my knowledge.
Knew to coding, probably missed the solution to this program somewhere in the tutorials however I'm stumped right now.
from AlgorithmImports import *
class Breakout(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2022, 7, 2)
self.SetEndDate(2022, 8, 2)
self.SetCash(1000000)
self.DTE = 25
# target percentage options are out of the money .01 == 1%
self.OTM = .01
self.contract = str()
self.securities = str()
# add SPY so that we can use it in the schedule rule below
self.SPY = self.AddEquity('SPY', Resolution.Minute).Symbol
# build a universe using the CoarseFilter and FineFilter functions defined below
self.AddUniverse(self.CoarseFilter)
self.SPY = self.AddEquity("SPY").Symbol
self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 1), self.AfterMarketOpen)
def CoarseFilter(self, universe):
# filter universe, ensure DollarVolume is above a certain threshold
# also filter by assets that have fundamental data
universe = [asset for asset in universe if asset.DollarVolume > 1000000 and asset.Price > 10 and asset.HasFundamentalData]
# sort universe by highest dollar volume
sortedByDollarVolume = sorted(universe, key=lambda asset: asset.DollarVolume, reverse=True)
# only select the first 500
topSortedByDollarVolume = sortedByDollarVolume[:500]
# we must return a list of the symbol objects only
symbolObjects = [asset.Symbol for asset in topSortedByDollarVolume]
# this line is not necessary, but we will use it for debugging to see a list of ticker symbols
tickerSymbolValuesOnly = [symbol.Value for symbol in symbolObjects]
return symbolObjects
def AfterMarketOpen(self):
for security in self.ActiveSecurities.Values:
symbol = security.Symbol
historyData = self.History(symbol, 2, Resolution.Daily)
try:
openDayAfterEarnings = historyData['open'][-1]
closeDayAfterEarnings = historyData['close'][-1]
highDayAfterEarnings = historyData['high'][-1]
closeDayBeforeEarnings = historyData['close'][-2]
except:
self.Debug(f"History data unavailable for {symbol.Value}")
continue
priceGap = openDayAfterEarnings - closeDayBeforeEarnings
percentGap = priceGap / closeDayBeforeEarnings
closeStrength = (closeDayAfterEarnings - openDayAfterEarnings) / (highDayAfterEarnings - openDayAfterEarnings)
if percentGap > 0.05:
# if closeDayAfterEarnings > closeDayBeforeEarnings and closeStrength > 0.5:
#self.Securities = symbol
#self.Debug(self.securities)
Option = self.AddOption(symbol, Resolution.Minute)
Option.SetFilter(-1, 1, timedelta(20), timedelta(40))
for i in OptionChains:
chains = i.Value
self.BuyCall(chains)
def BuyCall(self,chains):
expiry = sorted(chains,key = lambda x: x.Expiry, reverse=True)[0].Expiry
calls = [i for i in chains if i.Expiry == expiry and i.Right == OptionRight.Call]
call_contracts = sorted(calls,key = lambda x: abs(x.Strike - x.UnderlyingLastPrice))
if len(call_contracts) == 0:
return
self.call = call_contracts[0]
quantity = self.Portfolio.TotalPortfolioValue / self.call.AskPrice
quantity = int( 0.05 * quantity / 100 )
self.Buy(self.call.symbol, 1)
Mia Alissi
From the provided code, it seems like you are trying to add options for the top 500 dollar volume stocks and then buy options contracts when certain conditions are met. However, there seems to be a misunderstanding in how to handle options data in QuantConnect.
In your
AfterMarketOpen
function, you are trying to loop overOptionChains
which is not defined. Instead, you should be using theSlice
object that is passed to theOnData
function to access the option chain data. TheSlice
object contains all the data at each time step, including the option chain data.Here is an example of how you can access the option chain data:
In the loop,
chain
is anOptionChain
object that contains the option contracts data. You can then filter and sort the contracts based on your criteria.Also, in your
BuyCall
function, you are trying to buy the option contract usingself.Buy(self.call.symbol, 1)
. However,self.call.symbol
is not a valid symbol object. You should be usingself.call.Symbol
instead.Here is the corrected line:
Please note that handling options data can be complex due to the large number of contracts and the need to filter and sort them based on various criteria. I would recommend going through the options tutorial on QuantConnect to get a better understanding of how to work with options data.
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Benrashi Jacobson
Hello, implemented those changes however getting an error during the option contract addition process “self.AddOptionsContract()” regarding the symbol not being valid. Tried multiple methods all failed, in the error shown during the last attempt the symbol input was accurate appreciate help resolving this issue.
Benrashi Jacobson
New code
Mia Alissi
Your updated code seems to be on the right track. You are now correctly using the
OnData
function to access the option chain data. However, there are still a few issues that need to be addressed.In your
BuyCall
function, you are calculating the quantity based on theAskPrice
of the option contract. However, theAskPrice
might be zero if there is no ask price available, which will cause a division by zero error. You should add a check to ensure that theAskPrice
is not zero before calculating the quantity.You are trying to buy the option contract using
self.Buy(self.call.Symbol, 1)
. However, this will only buy one contract regardless of the calculated quantity. You should be using the calculated quantity instead.Here is the corrected
BuyCall
function:AfterMarketOpen
function, you are adding options for each security inself.ActiveSecurities.Values
. However, you are not removing these options later. This can lead to a large number of options being added and can slow down your algorithm. You should remove the options once you are done with them using theRemoveSecurity
function.Here is an example of how you can remove an option:
Please note that handling options data can be complex due to the large number of contracts and the need to filter and sort them based on various criteria. I would recommend going through the options tutorial on QuantConnect to get a better understanding of how to work with options data.
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Benrashi Jacobson
Current code
Mia Alissi
Your updated code seems to be on the right track. You are now correctly using the
OnData
function to access the option chain data. However, there are still a few issues that need to be addressed.In your
BuyCall
function, you are calculating the quantity based on theAskPrice
of the option contract. However, theAskPrice
might be zero if there is no ask price available, which will cause a division by zero error. You should add a check to ensure that theAskPrice
is not zero before calculating the quantity.You are trying to buy the option contract using
self.Buy(self.call.Symbol, 1)
. However, this will only buy one contract regardless of the calculated quantity. You should be using the calculated quantity instead.Here is the corrected
BuyCall
function:AfterMarketOpen
function, you are adding options for each security inself.ActiveSecurities.Values
. However, you are not removing these options later. This can lead to a large number of options being added and can slow down your algorithm. You should remove the options once you are done with them using theRemoveSecurity
function.Here is an example of how you can remove an option:
Please note that handling options data can be complex due to the large number of contracts and the need to filter and sort them based on various criteria. I would recommend going through the options tutorial on QuantConnect to get a better understanding of how to work with options data.
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Benrashi Jacobson
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!