I am using the Universe selection and CoarseFilterFunction to select a basket of stocks.  I then use the OnSecuritiesChanged to call an OptionFilter function which find an ATM call and put option that is closest to 30 DTE and subscribes to the contract data.  Then in OnData I'm parsing through all the ActiveSecurities and calling the OptionFilter again to get the 2 contracts I want (1 ATM call and 1 ATM put) and then I store the bid and ask price.  The issue I'm having is that very often the bid and ask price is 0.0.  Then on the next iteration of the OnData function there will be prices, and then again there may not be.  I'm not sure what I'm doing wrong. I was pulling about 2000 stocks from the coarse filter function, but for testing I am now just pulling 5.  

Here is the code I'm using for the OnData

def OnData(self, data):
 
        for security in self.ActiveSecurities.Values:
            
            if security.Symbol.SecurityType == SecurityType.Equity:
                contracts = self.OptionsFilter(security.Symbol)
                
                if contracts == str(): continue
            
                for contract in contracts:
                    if contract.ID.OptionRight == OptionRight.Put:
                        bid = self.Securities[contract].BidPrice
                    else:
                        ask = self.Securities[contract].AskPrice
                
                if bid > 0 and ask > 0:
                    self.contractsWithPrices += 1
                else:
                    self.contractsWithoutPrices += 1
                    
        self.Debug("Number of Contracts with Prices: " + str(self.contractsWithPrices))
        self.Debug("Number of Contracts without Prices: " + str(self.contractsWithoutPrices))
        self.contractsWithPrices = 0
        self.contractsWithoutPrices = 0

The results of this are as follows.  You can see that of the 5 stocks none of them initially got a bid or ask, then on the next iteration of OnData 4/5 got prices, then all 5, then only 4 again.  I am limiting to 5 stocks for testing, but when I don't limit it's even more erratic with only about 30 or so out of 1700 getting prices.

Number of Contracts with Prices: 0 
Number of Contracts without Prices: 5
Number of Contracts with Prices: 4 
Number of Contracts without Prices: 1
Number of Contracts with Prices: 5 
Number of Contracts without Prices: 0
Number of Contracts with Prices: 4 
Number of Contracts without Prices: 1
Number of Contracts with Prices: 5 
Number of Contracts without Prices: 0
Number of Contracts with Prices: 4 
Number of Contracts without Prices: 1
….

Here is my OnSecuritiesChanged function

def OnSecuritiesChanged(self, changes):
        
        for security in changes.AddedSecurities:
            if security.Symbol.SecurityType == SecurityType.Equity:
                self.OptionsFilter(security.Symbol)

The Options filter method uses this to subscribe to the contracts that I select

def OptionsFilter(self, symbol):

        """Stuff above here to select contracts omitted for brevity"""
            for contract in atmContracts:
                if contract not in self.contractsAdded:
                    self.contractsAdded.add(contract)
                    self.AddOptionContract(contract, Resolution.Minute)
            return atmContracts
        else:
            return str()