Overall Statistics
class UncoupledTransdimensionalPrism(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2007, 1, 1)
        self.SetCash(10000)  # Set Strategy Cash
        spy = self.AddEquity("SPY", Resolution.Minute)
        QQQ = self.AddEquity("QQQ", Resolution.Minute)
        WMT = self.AddEquity("QLD", Resolution.Minute)
        spy.SetDataNormalizationMode(DataNormalizationMode.Raw)
        QQQ.SetDataNormalizationMode(DataNormalizationMode.Raw)
        WMT.SetDataNormalizationMode(DataNormalizationMode.Raw)
        self.spy = spy.Symbol
        self.QQQ = QQQ.Symbol
        self.WMT = WMT.Symbol
        self.contract = None
        self.Count = 0
        self.D = self.Time.date()
        self.T = self.Time
        self.priceSPY = 0
        self.priceQQQ = 0
        self.SPYholdings = .60
        self.QQQholdings = .36
        self.WMTholdings = .0
        self.Quarter = self.Time.date().month
        self.SetBenchmark("SPY")
        

    def OnData(self, data): 
        
        #sameday
        
        if self.D == self.Time.date():
            
            #do at start of day
            if self.Count == 0:
                
                if not self.Portfolio[self.spy].Invested:
                    self.SetHoldings(self.spy, self.SPYholdings)
                    
                if not self.Portfolio[self.QQQ].Invested:
                    self.SetHoldings(self.QQQ, self.QQQholdings)
                
                if not self.Portfolio[self.WMT].Invested:
                    self.SetHoldings(self.WMT, self.WMTholdings)
                    
                if data.ContainsKey("SPY"):
                    self.priceSPY = data.Bars["SPY"].High
                    #self.priceQQQ = data.Bars["QQQ"].High
                    
               # self.Debug(self.T)
               # self.Debug(self.priceSPY)
                self.Count = 1
                
            #if not start of day
            else:
                if data.ContainsKey("SPY"):
                    if ( (data.Bars["SPY"].High - self.priceSPY) / self.priceSPY ) < -.08:
                        #self.Debug(self.Time)
                        #self.Debug((data.Bars["SPY"].High - self.priceSPY) / self.priceSPY )
                        self.SetHoldings(self.spy, 0)
                        self.SetHoldings(self.QQQ, 0)
                        self.SetHoldings(self.WMT, 0)
                        return
                    #return
        
        else:
            
            if not self.Quarter ==  self.Time.date().month:
                self.Debug( self.Time.date().month)
                self.Debug( self.Time.date())
                #self.SetHoldings(self.spy, self.SPYholdings)
                #self.SetHoldings(self.QQQ, self.QQQholdings)
                #self.SetHoldings(self.WMT, self.WMTholdings)
                
                self.Debug (self.Portfolio[self.spy].Price * self.Portfolio[self.spy].Quantity)
                self.Debug (self.Portfolio[self.QQQ].Price * self.Portfolio[self.QQQ].Quantity)
                
                
                self.SetHoldings(self.spy, self.SPYholdings)
                    
                
                self.SetHoldings(self.QQQ, self.QQQholdings)
                
                   
                self.SetHoldings(self.WMT, self.WMTholdings)
                
                self.Quarter =  self.Time.date().month
            
            
            else:
                if not self.Portfolio[self.spy].Invested:
                    self.SetHoldings(self.spy, self.SPYholdings)
                    
                if not self.Portfolio[self.QQQ].Invested:
                    self.SetHoldings(self.QQQ, self.QQQholdings)
                
                if not self.Portfolio[self.WMT].Invested:    
                    self.SetHoldings(self.WMT, self.WMTholdings)
            
            self.Count = 0
            self.D = self.Time.date()
            self.T = self.Time
            
            
            
        
       # if not self.Portfolio[self.spy].Invested:
           # self.SetHoldings(self.spy, .60)

        
       # if not self.Portfolio[self.QQQ].Invested:
          #  self.SetHoldings(self.QQQ, .36)
        
        # self.Debug(self.Time)
        # self.Debug(data.Bars["SPY"])
            
        # DO HEDGE
        if self.contract is None:
            self.contract = self.GetContract()
            return
        
        if (self.contract.ID.Date - self.Time).days < 180:
            self.Liquidate(self.contract)
            self.RemoveSecurity(self.contract)
            self.contract = None
            return
        
        if not self.Portfolio[self.contract].Invested:
            self.SetHoldings(self.contract, 0.04)
        
        #Exercixe our option when they increase in value to 20% OTM
        if  self.Securities[self.spy].Price < self.contract.ID.StrikePrice * 1.20:
            self.Liquidate(self.contract)
            self.RemoveSecurity(self.contract)
            
    
    def GetContract(self):
        # Set our target strike as 40% OTM long put 
        targetStrike = (self.Securities[self.spy].Price * 0.60) - (self.Securities[self.spy].Price * 0.60)%5
        contracts = self.OptionChainProvider.GetOptionContractList(self.spy, self.Time)
        puts = [x for x in contracts if x.ID.OptionRight == OptionRight.Put]
        puts = sorted( sorted(puts, key = lambda x: x.ID.Date, reverse = True),
                       key = lambda x: x.ID.StrikePrice)
        puts = [x for x in puts if x.ID.StrikePrice == targetStrike]
        puts = [x for x in puts if 270 < (x.ID.Date - self.Time).days <= 420]
        if len(puts) == 0:
            self.Log("No Puts")
            return None
        self.AddOptionContract(puts[0], Resolution.Minute)
        return puts[0]