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)