Overall Statistics
from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Common")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Algorithm.Framework")

from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Algorithm.Framework import *
from QuantConnect.Algorithm.Framework.Portfolio import PortfolioTarget
from QuantConnect.Algorithm.Framework.Risk import RiskManagementModel

class TrailingStopRiskManagementModel(RiskManagementModel):
    '''Provides an implementation of IRiskManagementModel that limits the maximum possible loss
    measured from the highest unrealized profit'''
    def __init__(self, maximumDrawdownPercent = 0.08):
        '''Initializes a new instance of the TrailingStopRiskManagementModel class
        Args:
            maximumDrawdownPercent: The maximum percentage drawdown allowed for algorithm portfolio compared with the highest unrealized profit, defaults to 5% drawdown'''
        self.maximumDrawdownPercent = -abs(maximumDrawdownPercent)
        self.trailingHighs = dict()
        self.lastDay = -1
        
        self.percentGain = 0.01

    def ManageRisk(self, algorithm, targets):
        '''Manages the algorithm's risk at each time step
        Args:
            algorithm: The algorithm instance
            targets: The current portfolio targets to be assessed for risk'''
            
        if algorithm.Time.day == self.lastDay:
            return []
        self.lastDay = algorithm.Time.day
        
        riskAdjustedTargets = list()

        for kvp in algorithm.Securities:
            symbol = kvp.Key
            security = kvp.Value
            percentChange = algorithm.Securities[symbol].Holdings.UnrealizedProfitPercent / 0.01

            # Add newly invested securities
            if symbol not in self.trailingHighs:
                self.trailingHighs[symbol] = security.Close    # Set to average holding cost
                continue
            
            # Remove if not invested
            if not security.Invested and symbol in self.trailingHighs:
                try:
                    self.trailingHighs.pop(symbol, None)
                except:
                    continue
                continue
            
            if percentChange.is_integer() and percentChange > 0:
                self.trailingHighs[symbol] = security.Close
            

            # Check for new highs and update - set to tradebar high
            # if self.trailingHighs[symbol] < security.High:
            #     self.trailingHighs[symbol] = security.High
            #     continue

            # Check for securities past the drawdown limit
            securityHigh = self.trailingHighs[symbol]
            if securityHigh == 0:
                riskAdjustedTargets.append(PortfolioTarget(symbol, 0))
                continue
            
            drawdown = (security.Low / securityHigh) - 1

            if drawdown < self.maximumDrawdownPercent:
                # liquidate
                riskAdjustedTargets.append(PortfolioTarget(symbol, 0))

        return riskAdjustedTargets
## SIMON LesFlex June 2021 ##
## Modified by Vladimir

from QuantConnect.Python import PythonQuandl

### Simon LesFlex June 2021 ###
### Key Short—Term Economic Indicators. The Key Economic Indicators (KEI) database contains monthly and quarterly statistics 
### (and associated statistical methodological information) for the 33 OECD member and for a selection of non—member countries 
### on a wide variety of economic indicators, namely: quarterly national accounts, industrial production, composite leading indicators, 
### business tendency and consumer opinion surveys, retail trade, consumer and producer prices, hourly earnings, employment/unemployment,
### interest rates, monetary aggregates, exchange rates, international trade and balance of payments. Indicators have been prepared by national statistical 
### agencies primarily to meet the requirements of users within their own country. In most instances, the indicators are compiled in accordance with 
### international statistical guidelines and recommendations. However, national practices may depart from these guidelines, and these departures may 
### impact on comparability between countries. There is an on—going process of review and revision of the contents of the database in order to maximise 
### the relevance of the database for short—term economic analysis.
### For more information see: http://stats.oecd.org/OECDStat_Metadata/ShowMetadata.ashx?Dataset=KEI&Lang=en
### Reference Data Set: https://www.quandl.com/data/OECD/KEI_LOLITOAA_OECDE_ST_M-Leading-indicator-amplitude-adjusted-OECD-Europe-Level-ratio-or-index-Monthly
## keihist = 1400

import numpy as np
from itertools import groupby

class QuandlImporterAlgorithm(QCAlgorithm):

    def Initialize(self):
        self.quandlCode = "OECD/KEI_LOLITOAA_OECDE_ST_M"
        ## Optional argument - personal token necessary for restricted dataset
        #Quandl.SetAuthCode("PrzwuZR28Wqegvv1sdJ7")
        self.SetBrokerageModel(BrokerageName.AlphaStreams)
        
        self.SetStartDate(2015,1,1)                                 #Set Start Date
        self.SetEndDate(2015,6,1)            #Set End Date
        self.SetCash(25000)                                         #Set Strategy Cash
        self.SetWarmup(100)
        self.SetBenchmark("SPY")
        self.init = True
        self.kei = self.AddData(QuandlCustomColumns, self.quandlCode, Resolution.Daily, TimeZones.NewYork).Symbol
        self.sma = self.SMA(self.kei, 1)
        self.mom = self.MOMP(self.kei, 2)
        self.XLFsector_symbolDataBySymbol = {}
        self.XLEsector_symbolDataBySymbol = {}
        self.XLBsector_symbolDataBySymbol = {}
        self.XLIsector_symbolDataBySymbol = {}
        self.XLYsector_symbolDataBySymbol = {}
        self.XLPsector_symbolDataBySymbol = {}
        self.XLUsector_symbolDataBySymbol = {}
        self.XLKsector_symbolDataBySymbol = {}
        self.XLVsector_symbolDataBySymbol = {}
        self.XLCsector_symbolDataBySymbol = {}
        
        self.AddRiskManagement(TrailingStopRiskManagementModel(0.06))
        
        #self.SPY = self.AddEquity('SPY', Resolution.Daily).Symbol
        self.stock = self.AddEquity('QQQ', Resolution.Hour).Symbol
        self.bond = self.AddEquity('TLT', Resolution.Hour).Symbol
        self.vix = self.AddEquity('VIX', Resolution.Minute).Symbol
        
        self.XLF = self.AddEquity('XLF', Resolution.Hour).Symbol
        self.XLE = self.AddEquity('XLE', Resolution.Hour).Symbol
        self.XLB = self.AddEquity('XLB', Resolution.Hour).Symbol
        self.XLI = self.AddEquity('XLI', Resolution.Hour).Symbol
        self.XLY = self.AddEquity('XLY', Resolution.Hour).Symbol
        self.XLP = self.AddEquity('XLP', Resolution.Hour).Symbol
        self.XLU = self.AddEquity('XLU', Resolution.Hour).Symbol
        self.XLK = self.AddEquity('XLK', Resolution.Hour).Symbol
        self.XLV = self.AddEquity('XLV', Resolution.Hour).Symbol
        self.XLC = self.AddEquity('XLC', Resolution.Hour).Symbol
        
        #Stocks in Sectors
        #self.XLFsector = ["JPM","BAC","BRK.B"]
        self.XLFsector = []
        #self.XLEsector = ["XOM","CVX"]
        self.XLEsector = []
        self.XLBsector = ["LIN","SHW","APD"]
        self.XLIsector = ["HON","UNP","UPS"]
        self.XLYsector = ["AMZN","TSLA","HD"]
        self.XLPsector = ["PG","KO","PEP","WMT"]
        self.XLUsector = ["NEE","DUK","SO"]
        self.XLKsector = ["APPL","MSFT","NVDA"]
        self.XLVsector = ["JNJ","PFE","UNH"]
        self.XLCsector = ["FB", "GOOG", "DIS"]
        
        #Strategy
        strat = "self.Securities[symbol].Close < symbolData.high.Current.Value"
            
        self.UniverseSettings.Resolution = Resolution.Daily
        self.AddUniverse(self.XLFcoarse, self.XLFfine)
        #self.AddUniverse(self.XLEcoarse, self.XLEfine)
        self.numberOfSymbolsCoarse = 500
        self.lastMonth = 0
        self.weight = 0
        self.activelyTrading = []
                
       # symbol_list = ['XLC', 'XLE', 'XLU', 'XLI', 'XLB', 'XLK', 'XLP', 'XLY', 'XLF', 'XLV']
        #self.symbols = [self.AddEquity(symbol, Resolution.Minute).Symbol for symbol in symbol_list]
        
        for symbol in self.XLFsector:
            self.AddEquity(symbol, Resolution.Hour)
            
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLFsector_symbolDataBySymbol[symbol] = symbolData
        
        for symbol in self.XLEsector:

            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLEsector_symbolDataBySymbol[symbol] = symbolData
            
        for symbol in self.XLBsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLBsector_symbolDataBySymbol[symbol] = symbolData
        
        for symbol in self.XLIsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLIsector_symbolDataBySymbol[symbol] = symbolData
            
        for symbol in self.XLYsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLYsector_symbolDataBySymbol[symbol] = symbolData
            
        for symbol in self.XLPsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLPsector_symbolDataBySymbol[symbol] = symbolData
        
        for symbol in self.XLUsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLUsector_symbolDataBySymbol[symbol] = symbolData
            
        for symbol in self.XLKsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLKsector_symbolDataBySymbol[symbol] = symbolData
        
        
        
        self.Schedule.On(self.DateRules.EveryDay(self.stock), self.TimeRules.AfterMarketOpen(self.stock, 1), 
            self.Rebalance)
            
        #self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.Every(30), self.EveryDayAfterMarketOpen)
    
    
            
    
    def XLFcoarse(self, coarse):
        if self.Time.day == self.lastMonth:
            return Universe.Unchanged
        self.lastMonth = self.Time.day
        
        allCoarse = [x for x in coarse if x.HasFundamentalData and x.Price > 50 and x.Volume > 200000]
        finalCoarse = sorted(allCoarse, key = lambda x: x.DollarVolume, reverse = True)
        
        return [x.Symbol for x in finalCoarse][:self.numberOfSymbolsCoarse]
        #return self.tickers
    
    def XLFfine(self, fine):
        filteredSymbols = []
        sortedBySector = [x for x in fine]
        for code, g in groupby(sortedBySector, lambda x: x.AssetClassification.MorningstarSectorCode):
            for x in sorted(g, key = lambda x: x.ValuationRatios.PERatio, reverse = False)[:2]:
                filteredSymbols.append(x.Symbol)
            self.XLFsector = filteredSymbols
        return filteredSymbols[:3]

        
    def XLEcoarse(self, coarse):
        if self.Time.day == self.lastMonth:
            return Universe.Unchanged
        self.lastMonth = self.Time.day
        
        allCoarse = [x for x in coarse if x.HasFundamentalData and x.Price > 50 and x.Volume > 200000]
        finalCoarse = sorted(allCoarse, key = lambda x: x.DollarVolume, reverse = True)
        
        return [x.Symbol for x in finalCoarse][:self.numberOfSymbolsCoarse]
        #return self.tickers
    
    def XLEfine(self, fine):
        filteredSymbols = []
        sortedBySector = [x for x in fine]
        for code, g in groupby(sortedBySector, lambda x: x.AssetClassification.MorningstarSectorCode):
            for x in sorted(g, key = lambda x: x.ValuationRatios.PERatio, reverse = False)[:2]:
                filteredSymbols.append(x.Symbol)
        self.XLEsector = filteredSymbols
    
        return filteredSymbols[:3]
    
    def OnSecuritiesChanged(self,changes):
        for x in changes.AddedSecurities:
            if x.Symbol not in self.XLFsector_symbolDataBySymbol:
               self.XLFsector_symbolDataBySymbol = SymbolData(self,x.Symbol)
        for x in changes.RemovedSecurities:
            symbol_data = self.XLFsector_symbolDataBySymbol.pop(x.Symbol, None)
            if symbol_data:
                  symbol_data.dispose()
    
    def Rebalance(self):
        if self.IsWarmingUp or not self.mom.IsReady or not self.sma.IsReady: return
        initial_asset = self.stock if self.mom.Current.Value > 0 else self.bond
        
        if self.init:
            #self.SetHoldings(initial_asset, 1)
            self.init = False
            

        keihist = self.History([self.kei], (int(self.GetParameter("keihist"))))
        #keihist = keihist['Value'].unstack(level=0).dropna()
        keihistlowt = np.nanpercentile(keihist, 15)
        keihistmidt = np.nanpercentile(keihist, 50)
        keihisthight = np.nanpercentile(keihist, 90)
        kei = self.sma.Current.Value
        keimom = self.mom.Current.Value
            
        if (keimom < 0 and kei < keihistmidt and  kei > keihistlowt) and not (self.Securities[self.bond].Invested):
            # DECLINE
            self.Liquidate()
            self.SetHoldings(self.XLP, .01)
            
            for symbol, symbolData in self.XLPsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            self.SetHoldings(self.bond, .5)
            self.Debug("STAPLES {0} >> {1}".format(self.XLP, self.Time))
        
        elif (keimom > 0 and kei < keihistlowt) and not (self.Securities[self.XLB].Invested):
            # RECOVERY
            self.Liquidate()
            self.SetHoldings(self.XLB, .01)
            
            for symbol, symbolData in self.XLEsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            #XLB
            for symbol, symbolData in self.XLBsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            #XLY
            for symbol, symbolData in self.XLYsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
           
            self.Debug("MATERIALS {0} >> {1}".format(self.XLB, self.Time))
            
            
        elif (keimom > 0 and kei > keihistlowt and kei < keihistmidt) and not (self.Securities[self.XLE].Invested):
            # EARLY
            self.Liquidate()
            self.SetHoldings(self.XLE, .01)

            #XLF
            for symbol, symbolData in self.XLFsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            #XLI
            for symbol, symbolData in self.XLIsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            #XLE 
            for symbol, symbolData in self.XLEsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
           
            
            self.Debug("ENERGY {0} >> {1}".format(self.XLE, self.Time))
            
        elif (keimom > 0 and kei > keihistmidt and kei < keihisthight) and not (self.Securities[self.XLU].Invested):
            # REBOUND
            self.Liquidate()
            #self.SetHoldings(self.XLK, .5)
            self.SetHoldings(self.XLU, .01)
            
            #XLU
            for symbol, symbolData in self.XLEsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            
            
            
            self.Debug("UTILITIES {0} >> {1}".format(self.XLU, self.Time))
        
        elif (keimom < 0 and kei < keihisthight and kei > keihistmidt) and not (self.Securities[self.XLK].Invested):
            # LATE
            self.Liquidate()
            self.SetHoldings(self.XLK, .01)
            
            for symbol, symbolData in self.XLKsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value) :
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            #self.SetHoldings(self.XLV, .5)
            
            for symbol, symbolData in self.XLVsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value) :
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
           
            self.Debug("INFO TECH {0} >> {1}".format(self.XLK, self.Time))
        
        elif (keimom < 0 and kei < 100 and not self.Securities[self.bond].Invested):
            self.Liquidate()
            self.SetHoldings(self.bond, 1)
        

        self.Plot("LeadInd", "SMA(LeadInd)", self.sma.Current.Value)
        self.Plot("LeadInd", "THRESHOLD", 100)
        self.Plot("MOMP", "MOMP(LeadInd)", self.mom.Current.Value)
        self.Plot("MOMP", "THRESHOLD", 0)

        
# Quandl often doesn't use close columns so need to tell LEAN which is the "value" column.
class QuandlCustomColumns(PythonQuandl):
    def __init__(self):
        # Define ValueColumnName: cannot be None, Empty or non-existant column name
        self.ValueColumnName = "Value"
        
class SymbolData:
    def __init__(self, symbol, sma7, ema10, sma20, sma50, sma200,  ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow):
        self.Symbol = symbol
        self.sma7 = sma7
        self.ema10 = ema10
        self.sma20 = sma20
        self.sma50 = sma50
        self.sma200 = sma200
        self.ema20 = ema20
        self.rsi = rsi
        self.wilr = wilr
        self.wilr_fast = wilr_fast
        self.high = high
        self.midhigh = midhigh
        self.low = low
        self.stoplow = stoplow
## SIMON LesFlex June 2021 ##
## Modified by Vladimir

from QuantConnect.Python import PythonQuandl

### Simon LesFlex June 2021 ###
### Key Short—Term Economic Indicators. The Key Economic Indicators (KEI) database contains monthly and quarterly statistics 
### (and associated statistical methodological information) for the 33 OECD member and for a selection of non—member countries 
### on a wide variety of economic indicators, namely: quarterly national accounts, industrial production, composite leading indicators, 
### business tendency and consumer opinion surveys, retail trade, consumer and producer prices, hourly earnings, employment/unemployment,
### interest rates, monetary aggregates, exchange rates, international trade and balance of payments. Indicators have been prepared by national statistical 
### agencies primarily to meet the requirements of users within their own country. In most instances, the indicators are compiled in accordance with 
### international statistical guidelines and recommendations. However, national practices may depart from these guidelines, and these departures may 
### impact on comparability between countries. There is an on—going process of review and revision of the contents of the database in order to maximise 
### the relevance of the database for short—term economic analysis.
### For more information see: http://stats.oecd.org/OECDStat_Metadata/ShowMetadata.ashx?Dataset=KEI&Lang=en
### Reference Data Set: https://www.quandl.com/data/OECD/KEI_LOLITOAA_OECDE_ST_M-Leading-indicator-amplitude-adjusted-OECD-Europe-Level-ratio-or-index-Monthly
## keihist = 1400

import numpy as np

class QuandlImporterAlgorithm(QCAlgorithm):

    def Initialize(self):
        self.quandlCode = "OECD/KEI_LOLITOAA_OECDE_ST_M"
        ## Optional argument - personal token necessary for restricted dataset
        #Quandl.SetAuthCode("PrzwuZR28Wqegvv1sdJ7")
        self.SetBrokerageModel(BrokerageName.AlphaStreams)
        
        self.SetStartDate(2015,1,1)                                 #Set Start Date
        #self.SetEndDate(2021,1,1)            #Set End Date
        self.SetCash(25000)                                         #Set Strategy Cash
        self.SetWarmup(100)
        self.SetBenchmark("SPY")
        self.init = True
        self.kei = self.AddData(QuandlCustomColumns, self.quandlCode, Resolution.Daily, TimeZones.NewYork).Symbol
        self.sma = self.SMA(self.kei, 1)
        self.mom = self.MOMP(self.kei, 2)
        self.XLFsector_symbolDataBySymbol = {}
        self.XLEsector_symbolDataBySymbol = {}
        self.XLBsector_symbolDataBySymbol = {}
        self.XLIsector_symbolDataBySymbol = {}
        self.XLYsector_symbolDataBySymbol = {}
        self.XLPsector_symbolDataBySymbol = {}
        self.XLUsector_symbolDataBySymbol = {}
        self.XLKsector_symbolDataBySymbol = {}
        self.XLVsector_symbolDataBySymbol = {}
        self.XLCsector_symbolDataBySymbol = {}
        
        self.AddRiskManagement(TrailingStopRiskManagementModel(0.06))
        
        #self.SPY = self.AddEquity('SPY', Resolution.Daily).Symbol
        self.stock = self.AddEquity('QQQ', Resolution.Hour).Symbol
        self.bond = self.AddEquity('TLT', Resolution.Hour).Symbol
        self.vix = self.AddEquity('VIX', Resolution.Minute).Symbol
        
        self.XLF = self.AddEquity('XLF', Resolution.Hour).Symbol
        self.XLE = self.AddEquity('XLE', Resolution.Hour).Symbol
        self.XLB = self.AddEquity('XLB', Resolution.Hour).Symbol
        self.XLI = self.AddEquity('XLI', Resolution.Hour).Symbol
        self.XLY = self.AddEquity('XLY', Resolution.Hour).Symbol
        self.XLP = self.AddEquity('XLP', Resolution.Hour).Symbol
        self.XLU = self.AddEquity('XLU', Resolution.Hour).Symbol
        self.XLK = self.AddEquity('XLK', Resolution.Hour).Symbol
        self.XLV = self.AddEquity('XLV', Resolution.Hour).Symbol
        self.XLC = self.AddEquity('XLC', Resolution.Hour).Symbol
        
        #Stocks in Sectors
        self.XLFsector = ["JPM","BAC","BRK.B"]
        self.XLEsector = ["XOM","CVX"]
        self.XLBsector = ["LIN","SHW","APD"]
        self.XLIsector = ["HON","UNP","UPS"]
        self.XLYsector = ["AMZN","TSLA","HD"]
        self.XLPsector = ["PG","KO","PEP","WMT"]
        self.XLUsector = ["NEE","DUK","SO"]
        self.XLKsector = ["APPL","MSFT","NVDA"]
        self.XLVsector = ["JNJ","PFE","UNH"]
        self.XLCsector = ["FB", "GOOG", "DIS"]
        
        #Strategy
        strat = "self.Securities[symbol].Close < symbolData.high.Current.Value"
                
       # symbol_list = ['XLC', 'XLE', 'XLU', 'XLI', 'XLB', 'XLK', 'XLP', 'XLY', 'XLF', 'XLV']
        #self.symbols = [self.AddEquity(symbol, Resolution.Minute).Symbol for symbol in symbol_list]
        
        for symbol in self.XLFsector:
            self.AddEquity(symbol, Resolution.Hour)
            
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLFsector_symbolDataBySymbol[symbol] = symbolData
        
        for symbol in self.XLEsector:

            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLEsector_symbolDataBySymbol[symbol] = symbolData
            
        for symbol in self.XLBsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLBsector_symbolDataBySymbol[symbol] = symbolData
        
        for symbol in self.XLIsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLIsector_symbolDataBySymbol[symbol] = symbolData
            
        for symbol in self.XLYsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLYsector_symbolDataBySymbol[symbol] = symbolData
            
        for symbol in self.XLPsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLPsector_symbolDataBySymbol[symbol] = symbolData
        
        for symbol in self.XLUsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLUsector_symbolDataBySymbol[symbol] = symbolData
            
        for symbol in self.XLKsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLKsector_symbolDataBySymbol[symbol] = symbolData
        
        
        
        self.Schedule.On(self.DateRules.EveryDay(self.stock), self.TimeRules.AfterMarketOpen(self.stock, 1), 
            self.Rebalance)
            
        #self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.Every(30), self.EveryDayAfterMarketOpen)
        

    def Rebalance(self):
        if self.IsWarmingUp or not self.mom.IsReady or not self.sma.IsReady: return
        initial_asset = self.stock if self.mom.Current.Value > 0 else self.bond
        
        if self.init:
            #self.SetHoldings(initial_asset, 1)
            self.init = False
            

        keihist = self.History([self.kei], (int(self.GetParameter("keihist"))))
        #keihist = keihist['Value'].unstack(level=0).dropna()
        keihistlowt = np.nanpercentile(keihist, 15)
        keihistmidt = np.nanpercentile(keihist, 50)
        keihisthight = np.nanpercentile(keihist, 90)
        kei = self.sma.Current.Value
        keimom = self.mom.Current.Value
            
        if (keimom < 0 and kei < keihistmidt and  kei > keihistlowt) and not (self.Securities[self.bond].Invested):
            # DECLINE
            self.Liquidate()
            self.SetHoldings(self.XLP, .01)
            
            for symbol, symbolData in self.XLPsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            self.SetHoldings(self.bond, .5)
            self.Debug("STAPLES {0} >> {1}".format(self.XLP, self.Time))
        
        elif (keimom > 0 and kei < keihistlowt) and not (self.Securities[self.XLB].Invested):
            # RECOVERY
            self.Liquidate()
            self.SetHoldings(self.XLB, .01)
            
            for symbol, symbolData in self.XLEsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            #XLB
            for symbol, symbolData in self.XLBsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            #XLY
            for symbol, symbolData in self.XLYsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
           
            self.Debug("MATERIALS {0} >> {1}".format(self.XLB, self.Time))
            
            
        elif (keimom > 0 and kei > keihistlowt and kei < keihistmidt) and not (self.Securities[self.XLE].Invested):
            # EARLY
            self.Liquidate()
            self.SetHoldings(self.XLE, .01)

            #XLF
            for symbol, symbolData in self.XLFsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            #XLI
            for symbol, symbolData in self.XLIsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            #XLE 
            for symbol, symbolData in self.XLEsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
           
            
            self.Debug("ENERGY {0} >> {1}".format(self.XLE, self.Time))
            
        elif (keimom > 0 and kei > keihistmidt and kei < keihisthight) and not (self.Securities[self.XLU].Invested):
            # REBOUND
            self.Liquidate()
            #self.SetHoldings(self.XLK, .5)
            self.SetHoldings(self.XLU, .01)
            
            #XLU
            for symbol, symbolData in self.XLEsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            
            
            
            self.Debug("UTILITIES {0} >> {1}".format(self.XLU, self.Time))
        
        elif (keimom < 0 and kei < keihisthight and kei > keihistmidt) and not (self.Securities[self.XLK].Invested):
            # LATE
            self.Liquidate()
            self.SetHoldings(self.XLK, .01)
            
            for symbol, symbolData in self.XLKsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value) :
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            #self.SetHoldings(self.XLV, .5)
            
            for symbol, symbolData in self.XLVsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value) :
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
           
            self.Debug("INFO TECH {0} >> {1}".format(self.XLK, self.Time))
        
        elif (keimom < 0 and kei < 100 and not self.Securities[self.bond].Invested):
            self.Liquidate()
            self.SetHoldings(self.bond, 1)
        

        self.Plot("LeadInd", "SMA(LeadInd)", self.sma.Current.Value)
        self.Plot("LeadInd", "THRESHOLD", 100)
        self.Plot("MOMP", "MOMP(LeadInd)", self.mom.Current.Value)
        self.Plot("MOMP", "THRESHOLD", 0)

        
# Quandl often doesn't use close columns so need to tell LEAN which is the "value" column.
class QuandlCustomColumns(PythonQuandl):
    def __init__(self):
        # Define ValueColumnName: cannot be None, Empty or non-existant column name
        self.ValueColumnName = "Value"
        
class SymbolData:
    def __init__(self, symbol, sma7, ema10, sma20, sma50, sma200,  ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow):
        self.Symbol = symbol
        self.sma7 = sma7
        self.ema10 = ema10
        self.sma20 = sma20
        self.sma50 = sma50
        self.sma200 = sma200
        self.ema20 = ema20
        self.rsi = rsi
        self.wilr = wilr
        self.wilr_fast = wilr_fast
        self.high = high
        self.midhigh = midhigh
        self.low = low
        self.stoplow = stoplow
## SIMON LesFlex June 2021 ##
## Modified by Vladimir

from QuantConnect.Python import PythonQuandl
import numpy as np
import pandas as pd
import scipy as sc

from datetime import timedelta
from QuantConnect.Data.UniverseSelection import * 
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel
### Simon LesFlex June 2021 ###
### Key Short—Term Economic Indicators. The Key Economic Indicators (KEI) database contains monthly and quarterly statistics 
### (and associated statistical methodological information) for the 33 OECD member and for a selection of non—member countries 
### on a wide variety of economic indicators, namely: quarterly national accounts, industrial production, composite leading indicators, 
### business tendency and consumer opinion surveys, retail trade, consumer and producer prices, hourly earnings, employment/unemployment,
### interest rates, monetary aggregates, exchange rates, international trade and balance of payments. Indicators have been prepared by national statistical 
### agencies primarily to meet the requirements of users within their own country. In most instances, the indicators are compiled in accordance with 
### international statistical guidelines and recommendations. However, national practices may depart from these guidelines, and these departures may 
### impact on comparability between countries. There is an on—going process of review and revision of the contents of the database in order to maximise 
### the relevance of the database for short—term economic analysis.
### For more information see: http://stats.oecd.org/OECDStat_Metadata/ShowMetadata.ashx?Dataset=KEI&Lang=en
### Reference Data Set: https://www.quandl.com/data/OECD/KEI_LOLITOAA_OECDE_ST_M-Leading-indicator-amplitude-adjusted-OECD-Europe-Level-ratio-or-index-Monthly
## keihist = 1400



class SectorBalancedPortfolioConstruction(QCAlgorithm):

    def Initialize(self):
        self.quandlCode = "OECD/KEI_LOLITOAA_OECDE_ST_M"
        ## Optional argument - personal token necessary for restricted dataset
        #Quandl.SetAuthCode("PrzwuZR28Wqegvv1sdJ7")
        self.SetBrokerageModel(BrokerageName.AlphaStreams)
        
        self.SetStartDate(2016,8,10)                                 #Set Start Date
        #self.SetEndDate(2021,1,1)            #Set End Date
        self.SetCash(25000)                                         #Set Strategy Cash
        
        res = Resolution.Hour

        self.SetWarmup(100)
        self.SetBenchmark("SPY")
        self.init = True
        self.kei = self.AddData(QuandlCustomColumns, self.quandlCode, Resolution.Daily, TimeZones.NewYork).Symbol
        self.sma = self.SMA(self.kei, 1)
        self.mom = self.MOMP(self.kei, 2)
        self.XLFsector_symbolDataBySymbol = {}
        self.XLEsector_symbolDataBySymbol = {}
        self.XLBsector_symbolDataBySymbol = {}
        self.XLIsector_symbolDataBySymbol = {}
        self.XLYsector_symbolDataBySymbol = {}
        self.XLPsector_symbolDataBySymbol = {}
        self.XLUsector_symbolDataBySymbol = {}
        self.XLKsector_symbolDataBySymbol = {}
        self.XLVsector_symbolDataBySymbol = {}
        self.XLCsector_symbolDataBySymbol = {}
        
        self.AddRiskManagement(TrailingStopRiskManagementModel(0.06))
        
        self.SPY = self.AddEquity('SPY', Resolution.Daily).Symbol
        self.stock = self.AddEquity('QQQ', Resolution.Hour).Symbol
        self.bond = self.AddEquity('TMF', Resolution.Hour).Symbol
        self.vix = self.AddEquity('VIX', Resolution.Minute).Symbol
        
        self.XLF = self.AddEquity('XLF', Resolution.Hour).Symbol
        self.XLE = self.AddEquity('XLE', Resolution.Hour).Symbol
        self.XLB = self.AddEquity('XLB', Resolution.Hour).Symbol
        self.XLI = self.AddEquity('XLI', Resolution.Hour).Symbol
        self.XLY = self.AddEquity('XLY', Resolution.Hour).Symbol
        self.XLP = self.AddEquity('XLP', Resolution.Hour).Symbol
        self.XLU = self.AddEquity('XLU', Resolution.Hour).Symbol
        self.XLK = self.AddEquity('XLK', Resolution.Hour).Symbol
        self.XLV = self.AddEquity('XLV', Resolution.Hour).Symbol
        self.XLC = self.AddEquity('XLC', Resolution.Hour).Symbol
        
        self.XLFsector = []
        #self.XLFsector = []
        self.XLEsector = []
        self.XLBsector = []
        self.XLIsector = []
        self.XLYsector = []
        self.XLPsector = []
        self.XLUsector = []
        self.XLKsector = []
        self.XLVsector = []
        self.XLCsector = []
       
                # Stock Selector
                
        self.UniverseSettings.Resolution = Resolution.Daily
        #1. Set an instance of MyUniverseSelectionModel using self.SetUniverseSelection
        self.SetUniverseSelection(MyUniverseSelectionModel())
        #self.AddUniverse(self.SelectCoarse,self.SelectFine)
        
        
        self.activelyTrading = []
        self.weight = 0
        self.numberOfSymbolsCoarse = 3
        self.exposureToSector = 3
        self.lastMonth = -1
        
        
        
        
    
       


        
        ## Sectors data
        
        for symbol in self.XLFsector:
            self.AddEquity(symbol, Resolution.Hour)
            
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, int(self.GetParameter("highHist")), Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 10, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLFsector_symbolDataBySymbol[symbol] = symbolData
        
        for symbol in self.XLEsector:

            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, int(self.GetParameter("highHist")), Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 10, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLEsector_symbolDataBySymbol[symbol] = symbolData
            
        for symbol in self.XLBsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, int(self.GetParameter("highHist")), Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 10, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLBsector_symbolDataBySymbol[symbol] = symbolData
        
        for symbol in self.XLIsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, int(self.GetParameter("highHist")), Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 10, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLIsector_symbolDataBySymbol[symbol] = symbolData
            
        for symbol in self.XLYsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, int(self.GetParameter("highHist")), Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 10, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLYsector_symbolDataBySymbol[symbol] = symbolData
            
        for symbol in self.XLPsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, int(self.GetParameter("highHist")), Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 10, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLPsector_symbolDataBySymbol[symbol] = symbolData
        
        for symbol in self.XLUsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, int(self.GetParameter("highHist")), Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 10, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLUsector_symbolDataBySymbol[symbol] = symbolData
            
        for symbol in self.XLKsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, int(self.GetParameter("highHist")), Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 10, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLKsector_symbolDataBySymbol[symbol] = symbolData
        
        
        ## Sector Scheduler
        self.Schedule.On(self.DateRules.EveryDay(self.stock), self.TimeRules.AfterMarketOpen(self.stock, 1), 
            self.Rebalance)
            
        
    def SelectCoarse(self, algorithm, coarse):
        filtered = [x for x in coarse if x.HasFundamentalData > 0 and x.Price > 0]
        sortedByDollarVolume = sorted(filtered, key=lambda x: x.DollarVolume, reverse=True)
        return [x.Symbol for x in sortedByDollarVolume][:100]

    def SelectFine(self, algorithm, fine):
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Technology]
        self.XLKsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:3]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.FinancialServices]
        self.XLFsector  = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:2]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Utilities]
        self.XLUsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.ConsumerDefensive]
        self.XLPsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.ConsumerCyclical]
        self.XLYsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.RealEstate]
        self.XLREsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.BasicMaterials]
        self.XLBsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.CommunicationServices]
        self.XLCsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Energy]
        self.XLEsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Industrials]
        self.XLIsector  = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Healthcare]
        self.XLVsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        
        
        return [x.Symbol for x in self.XLKsector + self.XLFsector + self.XLUsector + self.XLPsector + self.XLYsector + self.XLREsector + self.XLBsector + self.XLCsector + self.XLEsector + self.XLIsector + self.XLVsector]


            
        #self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.Every(30), self.EveryDayAfterMarketOpen)
    
    
                


    def Rebalance(self):
        if self.IsWarmingUp or not self.mom.IsReady or not self.sma.IsReady: return
        initial_asset = self.stock if self.mom.Current.Value > 0 else self.bond
        
        if self.init:
            #self.SetHoldings(initial_asset, 1)
            self.init = False
            

        keihist = self.History([self.kei], (int(self.GetParameter("keihist"))))
        #keihist = keihist['Value'].unstack(level=0).dropna()
        keihistlowt = np.nanpercentile(keihist, 15)
        keihistmidt = np.nanpercentile(keihist, 50)
        keihisthight = np.nanpercentile(keihist, 90)
        kei = self.sma.Current.Value
        keimom = self.mom.Current.Value
            
        if (keimom < 0 and kei < keihistmidt and  kei > keihistlowt) and not (self.Securities[self.bond].Invested) and self.Portfolio["QQQ"].Invested:
            # DECLINE
            self.Liquidate()
            self.SetHoldings(self.XLP, .01)
            
            for symbol, symbolData in self.XLPsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
                    
           #Stop Loss
#            for symbol, symbolData in self.XLPsector_symbolDataBySymbol.items():
#                if not (self.Securities[symbol].Close < symbolData.low.Current.Value) and (self.Securities[self.XLB].Invested):
#                    self.Liquidate()
#                    self.SetHoldings(self.XLP, .01)
            
            self.SetHoldings(self.bond, .4)
            self.Debug("STAPLES {0} >> {1}".format(self.XLP, self.Time))
        
        elif (keimom > 0 and kei < keihistlowt) and not (self.Securities[self.XLB].Invested) and self.Portfolio["QQQ"].Invested:
            # RECOVERY
            self.Liquidate()
            self.SetHoldings(self.XLB, .01)
            
            for symbol, symbolData in self.XLEsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            #XLB
            for symbol, symbolData in self.XLBsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            #XLY
            for symbol, symbolData in self.XLYsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
           
            #Stop Loss
#            for symbol, symbolData in self.XLBsector_symbolDataBySymbol.items():
#                if not (self.Securities[symbol].Close < symbolData.low.Current.Value) and (self.Securities[self.XLB].Invested):
#                    self.Liquidate()
#                    self.SetHoldings(self.XLB, .01)
           
           
            self.Debug("MATERIALS {0} >> {1}".format(self.XLB, self.Time))
            
            
        elif (keimom > 0 and kei > keihistlowt and kei < keihistmidt) and not (self.Securities[self.XLE].Invested) and self.Portfolio["QQQ"].Invested:
            # EARLY
            self.Liquidate()
            self.SetHoldings(self.XLE, .01)

            #XLF
            for symbol, symbolData in self.XLFsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            #XLI
            for symbol, symbolData in self.XLIsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            #XLE 
            for symbol, symbolData in self.XLEsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
                    
            #Stop Loss
#            for symbol, symbolData in self.XLEsector_symbolDataBySymbol.items():
#                if not (self.Securities[symbol].Close < symbolData.low.Current.Value) and (self.Securities[self.XLE].Invested):
#                    self.Liquidate()
#                    self.SetHoldings(self.XLE, .01)
           
            
            self.Debug("ENERGY {0} >> {1}".format(self.XLE, self.Time))
            
        elif (keimom > 0 and kei > keihistmidt and kei < keihisthight) and not (self.Securities[self.XLU].Invested) and self.Portfolio["QQQ"].Invested:
            # REBOUND
            self.Liquidate()
            #self.SetHoldings(self.XLK, .5)
            self.SetHoldings(self.XLU, .01)
            
            #XLU
            for symbol, symbolData in self.XLUsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            #Stop Loss
 #           for symbol, symbolData in self.XLUsector_symbolDataBySymbol.items():
 #               if not (self.Securities[symbol].Close < symbolData.low.Current.Value) and (self.Securities[self.XLU].Invested):
 #                   self.Liquidate()
 #                   self.SetHoldings(self.XLU, .01)
            
            
            
            self.Debug("UTILITIES {0} >> {1}".format(self.XLU, self.Time))
        
        elif (keimom < 0 and kei < keihisthight and kei > keihistmidt) and not (self.Securities[self.XLK].Invested) and self.Portfolio["QQQ"].Invested:
            # LATE
            self.Liquidate()
            self.SetHoldings(self.XLK, .01)
            
            for symbol, symbolData in self.XLKsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value) :
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            #self.SetHoldings(self.XLV, .5)
            
            for symbol, symbolData in self.XLVsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value) :
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
           
            self.Debug("INFO TECH {0} >> {1}".format(self.XLK, self.Time))
            
            #Stop Loss
  #          for symbol, symbolData in self.XLKsector_symbolDataBySymbol.items():
 #               if not (self.Securities[symbol].Close < symbolData.low.Current.Value) and (self.Securities[self.XLK].Invested):
 #                   self.Liquidate()
 #                   self.SetHoldings(self.XLK, .01)
        
        elif (keimom < 0 and kei < 100 and not self.Securities[self.bond].Invested):
            self.Liquidate()
            self.SetHoldings(self.bond, .5)
        

        self.Plot("LeadInd", "SMA(LeadInd)", self.sma.Current.Value)
        self.Plot("LeadInd", "THRESHOLD", 100)
        self.Plot("MOMP", "MOMP(LeadInd)", self.mom.Current.Value)
        self.Plot("MOMP", "THRESHOLD", 0)

    


        
# Quandl often doesn't use close columns so need to tell LEAN which is the "value" column.
class QuandlCustomColumns(PythonQuandl):
    def __init__(self):
        # Define ValueColumnName: cannot be None, Empty or non-existant column name
        self.ValueColumnName = "Value"
        
class SymbolData:
    def __init__(self, symbol, sma7, ema10, sma20, sma50, sma200,  ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow):
        self.Symbol = symbol
        self.sma7 = sma7
        self.ema10 = ema10
        self.sma20 = sma20
        self.sma50 = sma50
        self.sma200 = sma200
        self.ema20 = ema20
        self.rsi = rsi
        self.wilr = wilr
        self.wilr_fast = wilr_fast
        self.high = high
        self.midhigh = midhigh
        self.low = low
        self.stoplow = stoplow
        
#class MyUniverseSelectionModel(FundamentalUniverseSelectionModel):

    def __init__(self):
        super().__init__(True, None)

    def SelectCoarse(self, algorithm, coarse):
        filtered = [x for x in coarse if x.HasFundamentalData > 0 and x.Price > 0]
        sortedByDollarVolume = sorted(filtered, key=lambda x: x.DollarVolume, reverse=True)
        return [x.Symbol for x in sortedByDollarVolume][:100]

    def SelectFine(self, algorithm, fine):
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Technology]
        self.XLKsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:3]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.FinancialServices]
        self.XLFsector  = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:2]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Utilities]
        self.XLUsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.ConsumerDefensive]
        self.XLPsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.ConsumerCyclical]
        self.XLYsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.RealEstate]
        self.XLREsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.BasicMaterials]
        self.XLBsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.CommunicationServices]
        self.XLCsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Energy]
        self.XLEsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Industrials]
        self.XLIsector  = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Healthcare]
        self.XLVsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        
        
        return [x.Symbol for x in self.XLKsector + self.XLFsector + self.XLUsector + self.XLPsector + self.XLYsector + self.XLREsector + self.XLBsector + self.XLCsector + self.XLEsector + self.XLIsector + self.XLVsector]
## SIMON LesFlex June 2021 ##
## Modified by Vladimir

from QuantConnect.Python import PythonQuandl
import numpy as np
import pandas as pd
import scipy as sc

from datetime import timedelta
from QuantConnect.Data.UniverseSelection import * 
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel
### Simon LesFlex June 2021 ###
### Key Short—Term Economic Indicators. The Key Economic Indicators (KEI) database contains monthly and quarterly statistics 
### (and associated statistical methodological information) for the 33 OECD member and for a selection of non—member countries 
### on a wide variety of economic indicators, namely: quarterly national accounts, industrial production, composite leading indicators, 
### business tendency and consumer opinion surveys, retail trade, consumer and producer prices, hourly earnings, employment/unemployment,
### interest rates, monetary aggregates, exchange rates, international trade and balance of payments. Indicators have been prepared by national statistical 
### agencies primarily to meet the requirements of users within their own country. In most instances, the indicators are compiled in accordance with 
### international statistical guidelines and recommendations. However, national practices may depart from these guidelines, and these departures may 
### impact on comparability between countries. There is an on—going process of review and revision of the contents of the database in order to maximise 
### the relevance of the database for short—term economic analysis.
### For more information see: http://stats.oecd.org/OECDStat_Metadata/ShowMetadata.ashx?Dataset=KEI&Lang=en
### Reference Data Set: https://www.quandl.com/data/OECD/KEI_LOLITOAA_OECDE_ST_M-Leading-indicator-amplitude-adjusted-OECD-Europe-Level-ratio-or-index-Monthly
## keihist = 1400



class SectorBalancedPortfolioConstruction(QCAlgorithm):

    def Initialize(self):
        self.quandlCode = "OECD/KEI_LOLITOAA_OECDE_ST_M"
        ## Optional argument - personal token necessary for restricted dataset
        #Quandl.SetAuthCode("PrzwuZR28Wqegvv1sdJ7")
        self.SetBrokerageModel(BrokerageName.AlphaStreams)
        
        self.SetStartDate(2016,8,10)                                 #Set Start Date
        #self.SetEndDate(2021,1,1)            #Set End Date
        self.SetCash(25000)                                         #Set Strategy Cash
        
        res = Resolution.Hour

        self.SetWarmup(100)
        self.SetBenchmark("SPY")
        self.init = True
        self.kei = self.AddData(QuandlCustomColumns, self.quandlCode, Resolution.Daily, TimeZones.NewYork).Symbol
        self.sma = self.SMA(self.kei, 1)
        self.mom = self.MOMP(self.kei, 2)
        self.XLFsector_symbolDataBySymbol = {}
        self.XLEsector_symbolDataBySymbol = {}
        self.XLBsector_symbolDataBySymbol = {}
        self.XLIsector_symbolDataBySymbol = {}
        self.XLYsector_symbolDataBySymbol = {}
        self.XLPsector_symbolDataBySymbol = {}
        self.XLUsector_symbolDataBySymbol = {}
        self.XLKsector_symbolDataBySymbol = {}
        self.XLVsector_symbolDataBySymbol = {}
        self.XLCsector_symbolDataBySymbol = {}
        
        self.AddRiskManagement(TrailingStopRiskManagementModel(0.06))
        
        self.SPY = self.AddEquity('SPY', Resolution.Daily).Symbol
        self.stock = self.AddEquity('QQQ', Resolution.Hour).Symbol
        self.bond = self.AddEquity('TMF', Resolution.Hour).Symbol
        self.vix = self.AddEquity('VIX', Resolution.Minute).Symbol
        
        self.XLF = self.AddEquity('XLF', Resolution.Hour).Symbol
        self.XLE = self.AddEquity('XLE', Resolution.Hour).Symbol
        self.XLB = self.AddEquity('XLB', Resolution.Hour).Symbol
        self.XLI = self.AddEquity('XLI', Resolution.Hour).Symbol
        self.XLY = self.AddEquity('XLY', Resolution.Hour).Symbol
        self.XLP = self.AddEquity('XLP', Resolution.Hour).Symbol
        self.XLU = self.AddEquity('XLU', Resolution.Hour).Symbol
        self.XLK = self.AddEquity('XLK', Resolution.Hour).Symbol
        self.XLV = self.AddEquity('XLV', Resolution.Hour).Symbol
        self.XLC = self.AddEquity('XLC', Resolution.Hour).Symbol
        
        self.XLFsector = []
        #self.XLFsector = []
        self.XLEsector = []
        self.XLBsector = []
        self.XLIsector = []
        self.XLYsector = []
        self.XLPsector = []
        self.XLUsector = []
        self.XLKsector = []
        self.XLVsector = []
        self.XLCsector = []
       
                # Stock Selector
                
        self.UniverseSettings.Resolution = Resolution.Daily
        #1. Set an instance of MyUniverseSelectionModel using self.SetUniverseSelection
        #self.SetUniverseSelection()
        
        self.AddUniverse(self.SelectCoarse, self.SelectFine)
        self.SetWarmup(500)
        self.symbolBySectorCode = dict()
        
        
        self.activelyTrading = []
        self.weight = 0
        self.numberOfSymbolsCoarse = 3
        self.exposureToSector = 3
        self.lastMonth = -1

        
        ## Sectors data
        
        for symbol in self.XLFsector:
            self.AddEquity(symbol, Resolution.Hour)
            
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, int(self.GetParameter("highHist")), Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 10, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLFsector_symbolDataBySymbol[symbol] = symbolData
        
        for symbol in self.XLEsector:

            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, int(self.GetParameter("highHist")), Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 10, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLEsector_symbolDataBySymbol[symbol] = symbolData
            
        for symbol in self.XLBsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, int(self.GetParameter("highHist")), Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 10, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLBsector_symbolDataBySymbol[symbol] = symbolData
        
        for symbol in self.XLIsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, int(self.GetParameter("highHist")), Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 10, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLIsector_symbolDataBySymbol[symbol] = symbolData
            
        for symbol in self.XLYsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, int(self.GetParameter("highHist")), Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 10, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLYsector_symbolDataBySymbol[symbol] = symbolData
            
        for symbol in self.XLPsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, int(self.GetParameter("highHist")), Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 10, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLPsector_symbolDataBySymbol[symbol] = symbolData
        
        for symbol in self.XLUsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, int(self.GetParameter("highHist")), Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 10, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLUsector_symbolDataBySymbol[symbol] = symbolData
            
        for symbol in self.XLKsector:
            self.AddEquity(symbol, Resolution.Hour)
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)
            wilr_fast = self.WILR(symbol, 10, Resolution.Daily)
            high = self.MAX(symbol, int(self.GetParameter("highHist")), Resolution.Daily, Field.High)
            midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            low = self.MIN(symbol, 10, Resolution.Daily, Field.Low)
            stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            
            symbolData = SymbolData(symbol, sma7, ema10, sma20, sma200, sma50, ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow)
            self.XLKsector_symbolDataBySymbol[symbol] = symbolData
        
        
        ## Sector Scheduler
        self.Schedule.On(self.DateRules.EveryDay(self.stock), self.TimeRules.AfterMarketOpen(self.stock, 1), 
            self.Rebalance)
            
        
    def SelectCoarse(self, coarse):
        filtered = [x for x in coarse if x.HasFundamentalData and x.Price > 0]
        sortedByDollarVolume = sorted(filtered, key=lambda x: x.DollarVolume, reverse=True)
        return [x.Symbol for x in sortedByDollarVolume][:100]

    def SelectFine(self, fine):
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Technology]
        self.XLKsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:3]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.FinancialServices]
        self.XLFsector  = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:2]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Utilities]
        self.XLUsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.ConsumerDefensive]
        self.XLPsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.ConsumerCyclical]
        self.XLYsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.RealEstate]
        self.XLREsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.BasicMaterials]
        self.XLBsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.CommunicationServices]
        self.XLCsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Energy]
        self.XLEsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Industrials]
        self.XLIsector  = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Healthcare]
        self.XLVsector = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1]
        
        
        return [x.Symbol for x in self.XLKsector + self.XLFsector + self.XLUsector + self.XLPsector + self.XLYsector + self.XLREsector + self.XLBsector + self.XLCsector + self.XLEsector + self.XLIsector + self.XLVsector]


            
        #self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.Every(30), self.EveryDayAfterMarketOpen)
    
    def OnSecuritiesChanged(self, changes):
        for security in changes.AddedSecurities:
            sectorCode = security.Fundamentals.AssetClassification.MorningstarSectorCode
            if sectorCode not in self.symbolBySectorCode:
                self.symbolBySectorCode[sectorCode] = list()
            self.symbolBySectorCode[sectorCode].append(security.Symbol) 

        for security in changes.RemovedSecurities:
            sectorCode = security.Fundamentals.AssetClassification.MorningstarSectorCode
            if sectorCode in self.symbolBySectorCode:
                symbol = security.Symbol
                if symbol in self.symbolBySectorCode[sectorCode]:
                    self.symbolBySectorCode[sectorCode].remove(symbol)

        self.OnSecuritiesChanged(changes)
      


    def Rebalance(self):
        if self.IsWarmingUp or not self.mom.IsReady or not self.sma.IsReady: return
        initial_asset = self.stock if self.mom.Current.Value > 0 else self.bond
        
        if self.init:
            #self.SetHoldings(initial_asset, 1)
            self.init = False
            

        keihist = self.History([self.kei], (int(self.GetParameter("keihist"))))
        #keihist = keihist['Value'].unstack(level=0).dropna()
        keihistlowt = np.nanpercentile(keihist, 15)
        keihistmidt = np.nanpercentile(keihist, 50)
        keihisthight = np.nanpercentile(keihist, 90)
        kei = self.sma.Current.Value
        keimom = self.mom.Current.Value
            
        if (keimom < 0 and kei < keihistmidt and  kei > keihistlowt) and not (self.Securities[self.bond].Invested) and self.Portfolio["QQQ"].Invested:
            # DECLINE
            self.Liquidate()
            self.SetHoldings(self.XLP, .01)
            
            for symbol, symbolData in self.XLPsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
                    
           #Stop Loss
#            for symbol, symbolData in self.XLPsector_symbolDataBySymbol.items():
#                if not (self.Securities[symbol].Close < symbolData.low.Current.Value) and (self.Securities[self.XLB].Invested):
#                    self.Liquidate()
#                    self.SetHoldings(self.XLP, .01)
            
            self.SetHoldings(self.bond, .4)
            self.Debug("STAPLES {0} >> {1}".format(self.XLP, self.Time))
        
        elif (keimom > 0 and kei < keihistlowt) and not (self.Securities[self.XLB].Invested) and self.Portfolio["QQQ"].Invested:
            # RECOVERY
            self.Liquidate()
            self.SetHoldings(self.XLB, .01)
            
            for symbol, symbolData in self.XLEsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            #XLB
            for symbol, symbolData in self.XLBsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            #XLY
            for symbol, symbolData in self.XLYsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
           
            #Stop Loss
#            for symbol, symbolData in self.XLBsector_symbolDataBySymbol.items():
#                if not (self.Securities[symbol].Close < symbolData.low.Current.Value) and (self.Securities[self.XLB].Invested):
#                    self.Liquidate()
#                    self.SetHoldings(self.XLB, .01)
           
           
            self.Debug("MATERIALS {0} >> {1}".format(self.XLB, self.Time))
            
            
        elif (keimom > 0 and kei > keihistlowt and kei < keihistmidt) and not (self.Securities[self.XLE].Invested) and self.Portfolio["QQQ"].Invested:
            # EARLY
            self.Liquidate()
            self.SetHoldings(self.XLE, .01)

            #XLF
            for symbol, symbolData in self.XLFsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            #XLI
            for symbol, symbolData in self.XLIsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            #XLE 
            for symbol, symbolData in self.XLEsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
                    
            #Stop Loss
#            for symbol, symbolData in self.XLEsector_symbolDataBySymbol.items():
#                if not (self.Securities[symbol].Close < symbolData.low.Current.Value) and (self.Securities[self.XLE].Invested):
#                    self.Liquidate()
#                    self.SetHoldings(self.XLE, .01)
           
            
            self.Debug("ENERGY {0} >> {1}".format(self.XLE, self.Time))
            
        elif (keimom > 0 and kei > keihistmidt and kei < keihisthight) and not (self.Securities[self.XLU].Invested) and self.Portfolio["QQQ"].Invested:
            # REBOUND
            self.Liquidate()
            #self.SetHoldings(self.XLK, .5)
            self.SetHoldings(self.XLU, .01)
            
            #XLU
            for symbol, symbolData in self.XLUsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value):
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            
            #Stop Loss
 #           for symbol, symbolData in self.XLUsector_symbolDataBySymbol.items():
 #               if not (self.Securities[symbol].Close < symbolData.low.Current.Value) and (self.Securities[self.XLU].Invested):
 #                   self.Liquidate()
 #                   self.SetHoldings(self.XLU, .01)
            
            
            
            self.Debug("UTILITIES {0} >> {1}".format(self.XLU, self.Time))
        
        elif (keimom < 0 and kei < keihisthight and kei > keihistmidt) and not (self.Securities[self.XLK].Invested) and self.Portfolio["QQQ"].Invested:
            # LATE
            self.Liquidate()
            self.SetHoldings(self.XLK, .01)
            
            for symbol, symbolData in self.XLKsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value) :
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
            #self.SetHoldings(self.XLV, .5)
            
            for symbol, symbolData in self.XLVsector_symbolDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma50.Current.Value) :
                    self.SetHoldings(symbol, .1, False, "Buy Signal")
           
            self.Debug("INFO TECH {0} >> {1}".format(self.XLK, self.Time))
            
            #Stop Loss
  #          for symbol, symbolData in self.XLKsector_symbolDataBySymbol.items():
 #               if not (self.Securities[symbol].Close < symbolData.low.Current.Value) and (self.Securities[self.XLK].Invested):
 #                   self.Liquidate()
 #                   self.SetHoldings(self.XLK, .01)
        
        elif (keimom < 0 and kei < 100 and not self.Securities[self.bond].Invested):
            self.Liquidate()
            self.SetHoldings(self.bond, .5)
        

        self.Plot("LeadInd", "SMA(LeadInd)", self.sma.Current.Value)
        self.Plot("LeadInd", "THRESHOLD", 100)
        self.Plot("MOMP", "MOMP(LeadInd)", self.mom.Current.Value)
        self.Plot("MOMP", "THRESHOLD", 0)

    


        
# Quandl often doesn't use close columns so need to tell LEAN which is the "value" column.
class QuandlCustomColumns(PythonQuandl):
    def __init__(self):
        # Define ValueColumnName: cannot be None, Empty or non-existant column name
        self.ValueColumnName = "Value"
        
class SymbolData:
    def __init__(self, symbol, sma7, ema10, sma20, sma50, sma200,  ema20, rsi, wilr, wilr_fast, high, midhigh, low, stoplow):
        self.Symbol = symbol
        self.sma7 = sma7
        self.ema10 = ema10
        self.sma20 = sma20
        self.sma50 = sma50
        self.sma200 = sma200
        self.ema20 = ema20
        self.rsi = rsi
        self.wilr = wilr
        self.wilr_fast = wilr_fast
        self.high = high
        self.midhigh = midhigh
        self.low = low
        self.stoplow = stoplow