Hi All, 

I have been working on a modified wheel options strategy here where I will be selling puts for premium and am looking to have the system self optimize the best put to buy by using the sorting function to take the bid price and divide it by the number of days left before expiry of the option, in order to find the most premium per day option in the chain. however when i backtest it it comes up with an error that i cant seem to fix with:

 Runtime Error: Trying to perform a summation, subtraction, multiplication or division between 'float' and '0, Culture=neutral, PublicKeyToken=null]]' objects throws a TypeError exception. To prevent the exception, ensure that both values share the same type. at OnData in main.py:line 96 :: self.TradePutOption(slice) at TradePutOption in main.py:line 108 at <lambda> in main.py:line 108 TypeError : unsupported operand type(s) for /: 'float' and '0, Culture=neutral, PublicKeyToken=null]]'

now i dont know why this has occured beacause the options chain has been filtered for strikes between 30 and 45 days to there is no way a 0 should be possible in terms of the getbusinessdays function. can someone take a look and help me fix this?

Code below: sorry the backtest cant be found

from QuantConnect.Securities.Option import OptionPriceModels
from datetime import timedelta
import decimal as d

class CoveredCallAlgorithm(QCAlgorithm):

    def Initialize(self):
        self._no_K = 20       # no of strikes around ATM => for uni selection
        self.MIN_EXPIRY = 30 # min num of days to expiration => for uni selection
        self.MAX_EXPIRY = 60 # max num of days to expiration => for uni selection
        self.MAX_DELTA = d.Decimal(0.3)
        self.MIN_PREMIUM = d.Decimal(0.3)
        self.ticker = "AMD"
        self.benchmarkTicker = "SPX"
        self.SetStartDate(2017, 1, 1)
        self.SetEndDate(2018, 12, 1)
        self.SetCash(5000)
        
        self.resolution = Resolution.Minute
        self.call, self.put, self.takeProfitTicket = None, None, None
        
        equity = self.AddEquity(self.ticker, self.resolution)
        option = self.AddOption(self.ticker, self.resolution)
        self.symbol = option.Symbol

        # set strike/expiry filter for this option chain
        option.SetFilter(timedelta(30), timedelta(45))
        
        # set our strike/expiry filter for this option chain
        option.SetFilter(self.UniverseFunc)

        # for greeks and pricer (needs some warmup) - https://github.com/QuantConnect/Lean/blob/21cd972e99f70f007ce689bdaeeafe3cb4ea9c77/Common/Securities/Option/OptionPriceModels.cs#L81
        option.PriceModel = OptionPriceModels.CrankNicolsonFD()  # both European & American, automatically
        
        # this is needed for Greeks calcs
        self.SetWarmUp(TimeSpan.FromDays(60))    # timedelta(7)

        # use the underlying equity as the benchmark
        # self.SetBenchmark(self.benchmarkTicker)
        self.SetBenchmark(self.benchmarkTicker)
        
    def OnData(self,slice):
        if (self.IsWarmingUp): return

        option_invested = [x.Key for x in self.Portfolio if x.Value.Invested and x.Value.Type==SecurityType.Option]
        
        if len(option_invested) == 1: return
            
        # If we already have underlying - check if we need to sell covered call
        if self.Portfolio[self.ticker].Invested:
            self.TradeCallOption(slice) 
        else:
            self.TradePutOption(slice)
 
    def TradePutOption(self,slice):
        for i in slice.OptionChains:
            if i.Key != self.symbol: continue
        
            chain = i.Value
            
            # filter the put options contracts
            puts = [x for x in chain if x.Right == OptionRight.Put and abs(x.Greeks.Delta) > 0 and abs(x.Greeks.Delta) < self.MAX_DELTA and x.BidPrice > self.MIN_PREMIUM] 
            
            # sorted the contracts according to their bid price divided by the number of days left in the contract to find premium per day
            contracts = sorted(puts, key = lambda x: x.BidPrice / self.TradingCalendar.GetDaysByType(TradingDayType.BusinessDay, self.Time, x.Expiry))
                                            
            if len(contracts) == 0: continue  
        
            self.put = contracts[0].Symbol
            
            # Sell Put
            ticket = self.MarketOrder(self.put, -1, asynchronous = False)     
            
            # set Take Profit order
            self.takeProfitTicket = self.LimitOrder(self.put, 1, round(ticket.AverageFillPrice * d.Decimal(0.1), 2))
    
    def TradeCallOption(self,slice):
        for i in slice.OptionChains:
            if i.Key != self.symbol: continue
        
            chain = i.Value
            
            # filter the put options contracts
            calls = [x for x in chain if x.Right == OptionRight.Call and abs(x.Greeks.Delta) > 0 and abs(x.Greeks.Delta) < self.MAX_DELTA and x.BidPrice > self.MIN_PREMIUM] 
            
            # sorted the contracts according to their expiration dates and choose the ATM options
            contracts = sorted(sorted(calls, key = lambda x: x.BidPrice, reverse=True), 
                                             key = lambda x: x.Expiry)

            if len(contracts) == 0: continue  
        
            self.call = contracts[0].Symbol
            
            # short the call options
            ticket = self.MarketOrder(self.call, -1, asynchronous = False)     
            
            # set Take Profit order
            self.takeProfitTicket = self.LimitOrder(self.call, 1, round(ticket.AverageFillPrice * d.Decimal(0.1), 2))
    
 
    def OnOrderEvent(self, orderEvent):
        self.Log(str(orderEvent))
        
    def OnAssignmentOrderEvent(self, assignmentEvent):
        if self.takeProfitTicket != None:
            self.takeProfitTicket.cancel();
            self.takeProfitTicket = None

    def UniverseFunc(self, universe):
        return universe.IncludeWeeklys()\
                        .Strikes(-self._no_K, self._no_K)\
                        .Expiration(timedelta(self.MIN_EXPIRY), timedelta(self.MAX_EXPIRY))
                        
    def OnFrameworkData(self):
        return