Overall Statistics
class NadionTachyonProcessor(QCAlgorithm):
    openingBar = None
    secondaryBar = None
    
    def Initialize(self):
        self.SetStartDate(2017, 2, 1)
        self.SetEndDate(2017, 3, 1)
        self.SetCash(500000)
        self.AddEquity("GOOG", Resolution.Minute)
        option = self.AddOption("GOOG", Resolution.Minute)
        self.symbol = option.Symbol
        self.SetBenchmark("GOOG")
        option.SetFilter(-11,11, timedelta(0), timedelta(40))
        self.Consolidate("GOOG", timedelta(minutes=30), self.OnDataConsolidated)
      

        self.Schedule.On(self.DateRules.EveryDay("GOOG"), self.TimeRules.BeforeMarketClose("GOOG", 10), self.ClosePositions)


    def OnData(self, slice):
        '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
            Arguments:
                data: Slice object keyed by symbol containing the stock data
        '''
        if self.Portfolio["GOOG"].Quantity != 0:
            self.Liquidate()
        
        if self.Portfolio.Invested or self.openingBar is None or self.secondaryBar is None:
            return

        
        
        if (self.secondaryBar.Close > self.openingBar.High) and (self.openingBar.High>self.secondaryBar.Low>self.openingBar.High):
            #call at price self.openingBar.Low
            
            for i in slice.OptionChains:
                chain = i.Value
                contract_list = [x for x in chain]
                
                # if there is no optionchain or no contracts in this optionchain, pass the instance
                if (slice.OptionChains.Count == 0) or (len(contract_list) == 0): 
                    return   
                expiry = sorted(chain,key = lambda x: x.Expiry)[0].Expiry
                # filter the call and put options from the contracts
                call = [i for i in chain if i.Expiry == expiry and i.Right == 0]
                put = [i for i in chain if i.Expiry == expiry and i.Right == 1]
                
                call_contracts = sorted(call,key = lambda x: x.Strike)    
                put_contracts = sorted(put,key = lambda x: x.Strike)    
                if len(call_contracts) == 0 or len(put_contracts) == 0 : continue
    
                otm_put = put_contracts[10]
                self.trade_contracts = [otm_put.Symbol]
                self.Sell(otm_put.Symbol ,1)
                
        if (self.secondaryBar.Close < self.openingBar.Low) and (self.openingBar.High>self.secondaryBar.High>self.openingBar.High):
            #call at price self.openingBar.High
            for i in slice.OptionChains:
                chain = i.Value
                contract_list = [x for x in chain]
                # if there is no optionchain or no contracts in this optionchain, pass the instance
                if (slice.OptionChains.Count == 0) or (len(contract_list) == 0): 
                    return   
                expiry = sorted(chain,key = lambda x: x.Expiry)[0].Expiry
                # filter the call and put options from the contracts
                call = [i for i in chain if i.Expiry == expiry and i.Right == 0]
                put = [i for i in chain if i.Expiry == expiry and i.Right == 1]
                
                call_contracts = sorted(call,key = lambda x: x.Strike)    
                put_contracts = sorted(put,key = lambda x: x.Strike)    
                if len(call_contracts) == 0 or len(put_contracts) == 0 : continue
    
                otm_call= call_contracts[-10]
                self.trade_contracts = [otm_call.Symbol]
                self.Sell(otm_put.Symbol ,1)
            
    def OnOrderEvent(self, orderEvent):
        self.Log(str(orderEvent))

    def OnDataConsolidated(self, bar):
        if bar.Time.hour == 9 and bar.Time.minute == 30:
            self.openingBar = bar
        if bar.Time.hour == 10 and bar.Time.minute == 0:
            self.secondaryBar = bar
    
    def ClosePositions(self):
        self.secondaryBar = None
        self.openingBar = None
#        self.Liquidate("SPY")