Overall Statistics
Total Trades
70
Average Win
1.05%
Average Loss
-0.08%
Compounding Annual Return
53.617%
Drawdown
12.200%
Expectancy
9.215
Net Profit
53.617%
Sharpe Ratio
1.819
Probabilistic Sharpe Ratio
73.909%
Loss Rate
29%
Win Rate
71%
Profit-Loss Ratio
13.30
Alpha
0.017
Beta
1.808
Annual Standard Deviation
0.206
Annual Variance
0.042
Information Ratio
1.628
Tracking Error
0.109
Treynor Ratio
0.207
Total Fees
$70.00
Estimated Strategy Capacity
$430000.00
Lowest Capacity Asset
PWJ T6NYNHTZ5RAD
from System import *
from QuantConnect import *
import numpy as np
import datetime as dt
from datetime import timedelta, datetime
from AlgorithmImports import *
from itertools import groupby
from sklearn.ensemble import GradientBoostingRegressor
from risk import BracketRiskModel
from QuantConnect.Python import PythonQuandl
from trades import *
from trend import *

class NadionResistanceShield(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(int(self.GetParameter("YearStart")),1,1)  # Set Start Date
        self.SetEndDate(int(self.GetParameter("YearEnd")), 1, 1)
        self.SetCash(10000)  # Set Strategy Cash
        #self.tickers = self.ActiveSecurities.Keys

        #self.manually_selected = [self.AddEquity(symbol).Symbol for symbol in self.tickers]
        self.tickers = ["SPY", "BAC"]#,"AIG","BEF","BJH","DBV","DDN","DGP","DZR","FAY","EWM","GDVD","LJJ","LZP","MPD","OCA","PGY","QHG","QOC","ROK","ROL"]#["aapl","AB","AFG","AMP","CNS","FIX","GAL""DHI","SAFM","AMAT","AYI"]
  
        self.quandlCode = "OECD/KEI_LOLITOAA_OECD_ST_M"
        #Quandl.SetAuthCode("MLNarxdsMU92vk-ZJDvg")
        Quandl.SetAuthCode("RXk7Mxue6oH1TM-U8b7c")
        self.SetBenchmark("SPY")
        self.init = True
        self.stage = 0
        self.MarketTrend = 1
        self.MarketDir = 1
        #1 Up, 0 Down
        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.MKT = self.AddEquity('SPY', Resolution.Minute).Symbol
        self.bond = self.AddEquity('TLT', Resolution.Minute).Symbol
        self.previous_SPY = 0

        
        self.symbolDataBySymbol = {}
        self.MarketCaps = ["XLF","XLE","XLB","XLY","XLI","XLP","XLU","XLK","XLV","XLC","VCR","VFH","VGT","VOX","VDC","VDE","VAW"]# "QQQ"]#,"MDY","IWM"]
        self.MarketCapsDataBySymbol = {}
        self.Market = ['SPY']
        self.symbolMarketDataBySymbol = {}
        self.QQQ = ["TQQQ"]
        self.volatilityDataBySymbol = {}


        #Bull Market
        self.RecoveryStocks = ["XLB","XLY"]
        self.EarlyStocks = ["XLE","XLF","XLI"]
        self.ReboundStocks = ["XLK","XLU"]
        self.LateStocks = ["XLK","XLV"]
        self.DeclineStocks = ["XLP"]

        self.RecoveryStocksDataBySymbol = {}
        self.EarlyStocksDataBySymbol = {}
        self.ReboundStocksDataBySymbol = {}
        self.LateStocksDataBySymbol = {}
        self.DeclineStocksDataBySymbol = {}

        #Bear Market
        #self.BearRecoveryStocks = ["XLY"]
        #self.BearEarlyStocks = ["XLF"]
        #self.BearReboundStocks = ["XLK","XLC"]
        #self.BearLateStocks = ["XLP","XLE"]
        #self.BearDeclineStocks = ["XLE","XLB"]
        
        self.BearRecoveryStocks = ["VCR"]
        self.BearEarlyStocks = ["VFH"]
        self.BearReboundStocks = ["VGT","VOX"]
        self.BearLateStocks = ["VDE"]
        self.BearDeclineStocks = ["VDE","VAW"]


        self.BearRecoveryStocksDataBySymbol = {}
        self.BearEarlyStocksDataBySymbol = {}
        self.BearReboundStocksDataBySymbol = {}
        self.BearLateStocksDataBySymbol = {}
        self.BearDeclineStocksDataBySymbol = {}


        self.vix = ["VIX"]
        self.volatilityDataBySymbol = {}
        
        
        #InOut
        self.Trade = True
        #main switch
        self.trade = True
        self.atr=[]
        
        
        self.uvxy = "UVXY"
        self.spxl = "SPXL" 
        self.iwm = "IWM"
        self.mdy = "MDY"
        
        #self.offensive
        
        self.spyg = self.AddEquity("SPYG", Resolution.Hour).Symbol
        self.eem = self.AddEquity("EEM", Resolution.Hour).Symbol
        self.efa = self.AddEquity("EFA", Resolution.Hour).Symbol
        self.vug = self.AddEquity("VUG", Resolution.Hour).Symbol
        
        #netural
        self.bnd = self.AddEquity("EFA", Resolution.Hour).Symbol
        
        #self.defensive
        self.ief = self.AddEquity("IEF", Resolution.Hour).Symbol
        self.bil = self.AddEquity("BIL", Resolution.Hour).Symbol
        self.vglt = self.AddEquity("VGLT", Resolution.Hour).Symbol
        self.lqd = self.AddEquity("LQD", Resolution.Hour).Symbol
        self.tip = self.AddEquity("TIP", Resolution.Hour).Symbol
        self.dbc = self.AddEquity("DBC", Resolution.Hour).Symbol

        # Algo Parameters
        self.prds = [1,3,6,12]
        self.prdwts = np.array([12,6,2,1])
        self.LO, self.LD, self.LP, self.B, self.TO, self.TD = [12,12,0,1,1,3]# [12,12,0,1,1,3]6,12,0,1,1,1]
        self.hprd = max(self.prds+[self.LO,self.LD])*21+50
        
        # Assets
        self.canary = ['SPY','EFA','EEM','BND']
        self.offensive = ['SPYG','EFA','EEM','BND']
        self.defensive = ['BIL','BND','DBC','IEF','LQD','TIP','VGLT']
        self.safe = 'BIL'
        # repeat safe asset so it can be selected multiple times
        self.alldefensive = self.defensive + [self.safe] * max(0,self.TD - sum([1*(e==self.safe) for e in self.defensive]))
        self.eqs = list(dict.fromkeys(self.canary+self.offensive+self.alldefensive))
        for eq in self.eqs:
            self.AddEquity(eq,Resolution.Minute)

        self.spy = self.AddEquity("SPY", Resolution.Minute)
        self.spy_sma200 = self.SMA("SPY", 200, Resolution.Daily)
        
        self.symbols_dict = dict([
            ('SPY',['SPY',0]),('XMMO',['XMMO',0]),('MTUM',['MTUM',0]),('FVAL',['FVAL',0]),
            ('DXD',['DXD',0]),('GLD',['GLD',0]),('DIA',['DIA',0]),('TLT',['TLT',0]),('QQQ',['QQQ',0])
            ])

        self.all_symbols = ["XLF","XLE","XLB","XLY","XLI","XLP","XLU","XLK","XLV","XLC",'SPY','EFA','EEM','BND','BIL','BND','DBC','IEF','LQD','TIP','TLT','QQQ','EFA','EEM','BND',"XMMO","MTUM","FVAL","DIA","DXD"]

        #use this dataframe to hold the stats about the stage
        self.columns = ['stage_date', 'stage_num','stage','stage_days','symbol','price']
        self.stage_log_df = pd.DataFrame(columns=self.columns)
        
        for key in self.symbols_dict:
            self.AddEquity(self.symbols_dict[key][0], Resolution.Minute).Symbol

        self.up_value = 0.5 
        self.down_value = 0.5
        self.SetRiskManagement(BracketRiskModel(self.down_value, self.up_value))

        self.model = GradientBoostingRegressor()
        self.lookback = 30
        self.history_range = 200
        self.X = []
        self.y = []
        
          # Stock Selector
        self.AddUniverse(self.Coarse, self.Fine)
        self.activelyTrading = []
        self.weight = 1
        self.numberOfSymbolsCoarse = 5000
        self.exposureToSector = 2
        self.lastMonth = -3

        for symbol in self.Market:
            sma7 = self.SMA(symbol, 7, Resolution.Daily, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            sma100 = self.SMA(symbol, 100, Resolution.Daily, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            DCHindicator = self.DCH(symbol, 10, 10)
            self.DCHindicator = self.DCH(symbol, 20, 20)
            self.Trend0SPY = Trend0('Trend0', period=10, exponent=1.5)
            self.RegisterIndicator(symbol, self.Trend0SPY, Resolution.Hour)

            self.symbolMarketDataBySymbol[symbol] = symbolMarketData(symbol, sma7, sma20, sma50, sma100, sma200, DCHindicator)

        for symbolmark in self.MarketCaps:
            symbol = self.AddEquity(symbolmark, Resolution.Hour).Symbol
            ema7 = self.EMA(symbol, 7, Resolution.Daily, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Daily, Field.Close)
            sma100 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
            macdSlow = self.MACD(symbol, 26, 48, 12, MovingAverageType.Exponential, Resolution.Daily)
            self.high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            self.midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            self.buylow = self.MIN(symbol, 4, Resolution.Daily, Field.Low)
            self.low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            self.stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            self.DCHindicator = self.DCH(symbol, 20, 20)
            self.DCHindicatorShort = self.DCH(symbol, 10,10)
            RSIConsolidate = self.RSI(symbol, 14, MovingAverageType.Wilders)
            # create the 4 hour data consolidator
            dayConsolidator = TradeBarConsolidator(timedelta(days=5))
            self.SubscriptionManager.AddConsolidator(symbol, dayConsolidator)


            self.RegisterIndicator(symbol, RSIConsolidate, dayConsolidator)
            smaConsolidate = ExponentialMovingAverage(200, MovingAverageType.Simple)
            # create the 4 hour data consolidator
            WeekConsolidator = TradeBarConsolidator(timedelta(days=10))
            self.SubscriptionManager.AddConsolidator(symbol, WeekConsolidator)
            # register the 4 hour consolidated bar data to automatically update the indicator
            self.RegisterIndicator(symbol, smaConsolidate, WeekConsolidator)
            
            self.MarketCapsDataBySymbol[symbol] = symbolMarkData(symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, rsi, macd, macdSlow, RSIConsolidate, smaConsolidate)
        
        for symbol in self.RecoveryStocks:
            self.AddEquity(symbol, Resolution.Hour).Symbol
            ema7 = self.EMA(symbol, 7, Resolution.Daily, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Daily, Field.Close)
            sma100 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
            macdSlow = self.MACD(symbol, 26, 48, 12, MovingAverageType.Exponential, Resolution.Daily)
            self.high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            self.midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            self.buylow = self.MIN(symbol, 4, Resolution.Daily, Field.Low)
            self.low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            self.stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            DCHindicator = self.DCH(symbol, 20, 20)
            self.Trend0Recovery = Trend0('Trend0 Recovery', period=10, exponent=1.5)
            self.RegisterIndicator(symbol, self.Trend0Recovery, Resolution.Hour)
            
            RSIConsolidate = self.RSI(symbol, 14, MovingAverageType.Wilders)
            dayConsolidator = TradeBarConsolidator(timedelta(days=5))
            self.SubscriptionManager.AddConsolidator(symbol, dayConsolidator)
            self.RegisterIndicator(symbol, RSIConsolidate, dayConsolidator)
            
            smaConsolidate = ExponentialMovingAverage(200, MovingAverageType.Simple)
            WeekConsolidator = TradeBarConsolidator(timedelta(days=10))
            self.SubscriptionManager.AddConsolidator(symbol, WeekConsolidator)
            self.RegisterIndicator(symbol, smaConsolidate, WeekConsolidator)
            
            symbolData = SymbolData(symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, rsi, macd, macdSlow, DCHindicator, RSIConsolidate, smaConsolidate)
            self.RecoveryStocksDataBySymbol[symbol] = symbolData

        for symbol in self.EarlyStocks:
            self.AddEquity(symbol, Resolution.Hour).Symbol
            ema7 = self.EMA(symbol, 7, Resolution.Daily, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Daily, Field.Close)
            sma100 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
            macdSlow = self.MACD(symbol, 26, 48, 12, MovingAverageType.Exponential, Resolution.Daily)
            self.high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            self.midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            self.buylow = self.MIN(symbol, 4, Resolution.Daily, Field.Low)
            self.low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            self.stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            DCHindicator = self.DCH(symbol, 20, 20)
            self.Trend0Early = Trend0('Trend0 Early', period=10, exponent=1.5)
            self.RegisterIndicator(symbol, self.Trend0Early, Resolution.Hour)

            RSIConsolidate = self.RSI(symbol, 14, MovingAverageType.Wilders)
            dayConsolidator = TradeBarConsolidator(timedelta(days=5))
            self.SubscriptionManager.AddConsolidator(symbol, dayConsolidator)
            self.RegisterIndicator(symbol, RSIConsolidate, dayConsolidator)
            
            smaConsolidate = ExponentialMovingAverage(200, MovingAverageType.Simple)
            WeekConsolidator = TradeBarConsolidator(timedelta(days=10))
            self.SubscriptionManager.AddConsolidator(symbol, WeekConsolidator)
            self.RegisterIndicator(symbol, smaConsolidate, WeekConsolidator)
            
            symbolData = SymbolData(symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, rsi, macd, macdSlow, DCHindicator, RSIConsolidate, smaConsolidate)
            self.EarlyStocksDataBySymbol[symbol] = symbolData

        for symbol in self.ReboundStocks:
            self.AddEquity(symbol, Resolution.Hour).Symbol
            ema7 = self.EMA(symbol, 7, Resolution.Daily, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Daily, Field.Close)
            sma100 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
            macdSlow = self.MACD(symbol, 26, 48, 12, MovingAverageType.Exponential, Resolution.Daily)
            self.high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            self.midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            self.buylow = self.MIN(symbol, 4, Resolution.Daily, Field.Low)
            self.low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            self.stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            DCHindicator = self.DCH(symbol, 20, 20)
            self.Trend0Rebound = Trend0('Trend0 Rebound', period=10, exponent=1.5)
            self.RegisterIndicator(symbol, self.Trend0Rebound, Resolution.Hour)

            RSIConsolidate = self.RSI(symbol, 14, MovingAverageType.Wilders)
            dayConsolidator = TradeBarConsolidator(timedelta(days=5))
            self.SubscriptionManager.AddConsolidator(symbol, dayConsolidator)
            self.RegisterIndicator(symbol, RSIConsolidate, dayConsolidator)
            
            smaConsolidate = ExponentialMovingAverage(200, MovingAverageType.Simple)
            WeekConsolidator = TradeBarConsolidator(timedelta(days=10))
            self.SubscriptionManager.AddConsolidator(symbol, WeekConsolidator)
            self.RegisterIndicator(symbol, smaConsolidate, WeekConsolidator)
            
            symbolData = SymbolData(symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, rsi, macd, macdSlow, DCHindicator, RSIConsolidate, smaConsolidate)
            self.ReboundStocksDataBySymbol[symbol] = symbolData
        
        for symbol in self.LateStocks:
            self.AddEquity(symbol, Resolution.Hour).Symbol
            ema7 = self.EMA(symbol, 7, Resolution.Daily, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Daily, Field.Close)
            sma100 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
            macdSlow = self.MACD(symbol, 26, 48, 12, MovingAverageType.Exponential, Resolution.Daily)
            self.high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            self.midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            self.buylow = self.MIN(symbol, 4, Resolution.Daily, Field.Low)
            self.low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            self.stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            DCHindicator = self.DCH(symbol, 20, 20)
            self.Trend0Late = Trend0('Trend0 Late', period=10, exponent=1.5)
            self.RegisterIndicator(symbol, self.Trend0Late, Resolution.Hour)

            RSIConsolidate = self.RSI(symbol, 14, MovingAverageType.Wilders)
            dayConsolidator = TradeBarConsolidator(timedelta(days=5))
            self.SubscriptionManager.AddConsolidator(symbol, dayConsolidator)
            self.RegisterIndicator(symbol, RSIConsolidate, dayConsolidator)
            
            smaConsolidate = ExponentialMovingAverage(200, MovingAverageType.Simple)
            WeekConsolidator = TradeBarConsolidator(timedelta(days=10))
            self.SubscriptionManager.AddConsolidator(symbol, WeekConsolidator)
            self.RegisterIndicator(symbol, smaConsolidate, WeekConsolidator)
            
            symbolData = SymbolData(symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, rsi, macd, macdSlow, DCHindicator, RSIConsolidate, smaConsolidate)
            self.LateStocksDataBySymbol[symbol] = symbolData

        for symbol in self.DeclineStocks:
            self.AddEquity(symbol, Resolution.Hour).Symbol
            ema7 = self.EMA(symbol, 7, Resolution.Daily, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Daily, Field.Close)
            sma100 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
            macdSlow = self.MACD(symbol, 26, 48, 12, MovingAverageType.Exponential, Resolution.Daily)
            self.high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            self.midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            self.buylow = self.MIN(symbol, 4, Resolution.Daily, Field.Low)
            self.low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            self.stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            DCHindicator = self.DCH(symbol, 20, 20)
            self.Trend0Decline = Trend0('Trend0 Decline', period=10, exponent=1.5)
            self.RegisterIndicator(symbol, self.Trend0Decline, Resolution.Hour)

            RSIConsolidate = self.RSI(symbol, 14, MovingAverageType.Wilders)
            dayConsolidator = TradeBarConsolidator(timedelta(days=5))
            self.SubscriptionManager.AddConsolidator(symbol, dayConsolidator)
            self.RegisterIndicator(symbol, RSIConsolidate, dayConsolidator)
            
            smaConsolidate = ExponentialMovingAverage(200, MovingAverageType.Simple)
            WeekConsolidator = TradeBarConsolidator(timedelta(days=10))
            self.SubscriptionManager.AddConsolidator(symbol, WeekConsolidator)
            self.RegisterIndicator(symbol, smaConsolidate, WeekConsolidator)
            
            symbolData = SymbolData(symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, rsi, macd, macdSlow, DCHindicator, RSIConsolidate, smaConsolidate)
            self.DeclineStocksDataBySymbol[symbol] = symbolData

        for symbol in self.BearLateStocks:
            self.AddEquity(symbol, Resolution.Hour).Symbol
            ema7 = self.EMA(symbol, 7, Resolution.Daily, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Daily, Field.Close)
            sma100 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
            macdSlow = self.MACD(symbol, 26, 48, 12, MovingAverageType.Exponential, Resolution.Daily)
            self.high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            self.midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            self.buylow = self.MIN(symbol, 4, Resolution.Daily, Field.Low)
            self.low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            self.stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            DCHindicator = self.DCH(symbol, 20, 20)
            self.Trend0BearLate = Trend0('Trend0 BearLate', period=10, exponent=1.5)
            self.RegisterIndicator(symbol, self.Trend0BearLate, Resolution.Hour)

            RSIConsolidate = self.RSI(symbol, 14, MovingAverageType.Wilders)
            dayConsolidator = TradeBarConsolidator(timedelta(days=5))
            self.SubscriptionManager.AddConsolidator(symbol, dayConsolidator)
            self.RegisterIndicator(symbol, RSIConsolidate, dayConsolidator)
            
            smaConsolidate = ExponentialMovingAverage(200, MovingAverageType.Simple)
            WeekConsolidator = TradeBarConsolidator(timedelta(days=10))
            self.SubscriptionManager.AddConsolidator(symbol, WeekConsolidator)
            self.RegisterIndicator(symbol, smaConsolidate, WeekConsolidator)
            
            symbolData = SymbolData(symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, rsi, macd, macdSlow, DCHindicator, RSIConsolidate, smaConsolidate)
            self.BearLateStocksDataBySymbol[symbol] = symbolData

        for symbol in self.BearRecoveryStocks:
            self.AddEquity(symbol, Resolution.Hour).Symbol
            ema7 = self.EMA(symbol, 7, Resolution.Daily, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Daily, Field.Close)
            sma100 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
            macdSlow = self.MACD(symbol, 26, 48, 12, MovingAverageType.Exponential, Resolution.Daily)
            self.high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            self.midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            self.buylow = self.MIN(symbol, 4, Resolution.Daily, Field.Low)
            self.low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            self.stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            DCHindicator = self.DCH(symbol, 20, 20)

            RSIConsolidate = self.RSI(symbol, 14, MovingAverageType.Wilders)
            dayConsolidator = TradeBarConsolidator(timedelta(days=5))
            self.SubscriptionManager.AddConsolidator(symbol, dayConsolidator)
            self.RegisterIndicator(symbol, RSIConsolidate, dayConsolidator)
            
            smaConsolidate = ExponentialMovingAverage(200, MovingAverageType.Simple)
            WeekConsolidator = TradeBarConsolidator(timedelta(days=10))
            self.SubscriptionManager.AddConsolidator(symbol, WeekConsolidator)
            self.RegisterIndicator(symbol, smaConsolidate, WeekConsolidator)
            
            symbolData = SymbolData(symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, rsi, macd, macdSlow, DCHindicator, RSIConsolidate, smaConsolidate)
            self.BearRecoveryStocksDataBySymbol[symbol] = symbolData

        for symbol in self.BearEarlyStocks:
            self.AddEquity(symbol, Resolution.Hour).Symbol
            ema7 = self.EMA(symbol, 7, Resolution.Daily, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Daily, Field.Close)
            sma100 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
            macdSlow = self.MACD(symbol, 26, 48, 12, MovingAverageType.Exponential, Resolution.Daily)
            self.high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            self.midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            self.buylow = self.MIN(symbol, 4, Resolution.Daily, Field.Low)
            self.low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            self.stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            DCHindicator = self.DCH(symbol, 20, 20)

            RSIConsolidate = self.RSI(symbol, 14, MovingAverageType.Wilders)
            dayConsolidator = TradeBarConsolidator(timedelta(days=5))
            self.SubscriptionManager.AddConsolidator(symbol, dayConsolidator)
            self.RegisterIndicator(symbol, RSIConsolidate, dayConsolidator)
            
            smaConsolidate = ExponentialMovingAverage(200, MovingAverageType.Simple)
            WeekConsolidator = TradeBarConsolidator(timedelta(days=10))
            self.SubscriptionManager.AddConsolidator(symbol, WeekConsolidator)
            self.RegisterIndicator(symbol, smaConsolidate, WeekConsolidator)
            
            symbolData = SymbolData(symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, rsi, macd, macdSlow, DCHindicator, RSIConsolidate, smaConsolidate)
            self.BearEarlyStocksDataBySymbol[symbol] = symbolData

        for symbol in self.BearReboundStocks:
            self.AddEquity(symbol, Resolution.Hour).Symbol
            ema7 = self.EMA(symbol, 7, Resolution.Daily, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Daily, Field.Close)
            sma100 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
            macdSlow = self.MACD(symbol, 26, 48, 12, MovingAverageType.Exponential, Resolution.Daily)
            self.high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            self.midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            self.buylow = self.MIN(symbol, 4, Resolution.Daily, Field.Low)
            self.low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            self.stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            DCHindicator = self.DCH(symbol, 20, 20)

            RSIConsolidate = self.RSI(symbol, 14, MovingAverageType.Wilders)
            dayConsolidator = TradeBarConsolidator(timedelta(days=5))
            self.SubscriptionManager.AddConsolidator(symbol, dayConsolidator)
            self.RegisterIndicator(symbol, RSIConsolidate, dayConsolidator)
            
            smaConsolidate = ExponentialMovingAverage(200, MovingAverageType.Simple)
            WeekConsolidator = TradeBarConsolidator(timedelta(days=10))
            self.SubscriptionManager.AddConsolidator(symbol, WeekConsolidator)
            self.RegisterIndicator(symbol, smaConsolidate, WeekConsolidator)
            
            symbolData = SymbolData(symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, rsi, macd, macdSlow, DCHindicator, RSIConsolidate, smaConsolidate)
            self.BearReboundStocksDataBySymbol[symbol] = symbolData
         
        for symbol in self.BearDeclineStocks:
            self.AddEquity(symbol, Resolution.Hour).Symbol
            ema7 = self.EMA(symbol, 7, Resolution.Daily, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Daily, Field.Close)
            sma100 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
            macdSlow = self.MACD(symbol, 26, 48, 12, MovingAverageType.Exponential, Resolution.Daily)
            self.high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            self.midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            self.buylow = self.MIN(symbol, 4, Resolution.Daily, Field.Low)
            self.low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            self.stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            DCHindicator = self.DCH(symbol, 20, 20)

            RSIConsolidate = self.RSI(symbol, 14, MovingAverageType.Wilders)
            dayConsolidator = TradeBarConsolidator(timedelta(days=5))
            self.SubscriptionManager.AddConsolidator(symbol, dayConsolidator)
            self.RegisterIndicator(symbol, RSIConsolidate, dayConsolidator)
            
            smaConsolidate = ExponentialMovingAverage(200, MovingAverageType.Simple)
            WeekConsolidator = TradeBarConsolidator(timedelta(days=10))
            self.SubscriptionManager.AddConsolidator(symbol, WeekConsolidator)
            self.RegisterIndicator(symbol, smaConsolidate, WeekConsolidator)
            
            symbolData = SymbolData(symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, rsi, macd, macdSlow, DCHindicator, RSIConsolidate, smaConsolidate)
            self.BearDeclineStocksDataBySymbol[symbol] = symbolData

        for symbol in self.QQQ:
            self.AddEquity(symbol, Resolution.Hour).Symbol
            ema7 = self.EMA(symbol, 7, Resolution.Daily, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Daily, Field.Close)
            sma100 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
            macdSlow = self.MACD(symbol, 26, 48, 12, MovingAverageType.Exponential, Resolution.Daily)
            self.high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            self.midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            self.buylow = self.MIN(symbol, 4, Resolution.Daily, Field.Low)
            self.low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            self.stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            DCHindicator = self.DCH(symbol, 20, 20)

            RSIConsolidate = self.RSI(symbol, 14, MovingAverageType.Wilders)
            dayConsolidator = TradeBarConsolidator(timedelta(days=5))
            self.SubscriptionManager.AddConsolidator(symbol, dayConsolidator)
            self.RegisterIndicator(symbol, RSIConsolidate, dayConsolidator)
            
            smaConsolidate = ExponentialMovingAverage(200, MovingAverageType.Simple)
            WeekConsolidator = TradeBarConsolidator(timedelta(days=10))
            self.SubscriptionManager.AddConsolidator(symbol, WeekConsolidator)
            self.RegisterIndicator(symbol, smaConsolidate, WeekConsolidator)
            self.Trend0QQQ = Trend0('Trend0 QQQ', period=10, exponent=1.5)
            self.RegisterIndicator(symbol, self.Trend0QQQ, Resolution.Hour)
            
            #symbolvolData = SymbolData(symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, rsi, macd, macdSlow, DCHindicator, RSIConsolidate, smaConsolidate) 
            self.volatilityDataBySymbol[symbol] = symbolvolData(symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, rsi, macd, macdSlow, DCHindicator, RSIConsolidate, smaConsolidate)

        for symbol in self.tickers:
            self.AddEquity(symbol, Resolution.Hour).Symbol
            ema7 = self.EMA(symbol, 7, Resolution.Daily, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            ema50 = self.EMA(symbol, 50, Resolution.Daily, Field.Close)
            sma100 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
            macdSlow = self.MACD(symbol, 26, 48, 12, MovingAverageType.Exponential, Resolution.Daily)
            self.high = self.MAX(symbol, 5, Resolution.Daily, Field.High)
            self.midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High)
            self.buylow = self.MIN(symbol, 4, Resolution.Daily, Field.Low)
            self.low = self.MIN(symbol, 5, Resolution.Daily, Field.Low)
            self.stoplow = self.MIN(symbol, 20, Resolution.Daily, Field.Low)
            DCHindicator = self.DCH(symbol, 20, 20)
            self.Trend0Tickers = Trend0('Trend0 Single Equity', period=10, exponent=1.5)

            RSIConsolidate = self.RSI(symbol, 14, MovingAverageType.Wilders)
            dayConsolidator = TradeBarConsolidator(timedelta(days=5))
            self.SubscriptionManager.AddConsolidator(symbol, dayConsolidator)
            self.RegisterIndicator(symbol, RSIConsolidate, dayConsolidator)
            
            smaConsolidate = ExponentialMovingAverage(200, MovingAverageType.Simple)
            WeekConsolidator = TradeBarConsolidator(timedelta(days=10))
            self.SubscriptionManager.AddConsolidator(symbol, WeekConsolidator)
            self.RegisterIndicator(symbol, smaConsolidate, WeekConsolidator)
            
            symbolData = SymbolData(symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, rsi, macd, macdSlow, DCHindicator, RSIConsolidate, smaConsolidate) 
            self.symbolDataBySymbol[symbol] = symbolData
        #Schedules:            
        #self.Schedule.On(self.DateRules.WeekStart(self.MKT), self.TimeRules.AfterMarketOpen(self.MKT, 31), 
        #    self.Rebalance)   

        # Before the open


        self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", -5), Action(self.beforeTheOpen))
        self.Schedule.On(self.DateRules.MonthStart(self.canary[0]),self.TimeRules.AfterMarketOpen(self.canary[0],30),self.rebal)
        self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 60), lambda: stageIndicator(self))
        #self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 60), lambda: stageTradeManager(self))  
        self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 60), lambda: stageIndicatorBear(self))
        #self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 60), lambda: stageBearTradeManager(self))  
        self.Schedule.On(self.DateRules.WeekStart("SPY"), self.TimeRules.AfterMarketOpen("SPY", 30),  lambda: Rebalance(self))
        self.Schedule.On(self.DateRules.WeekStart("SPY"), self.TimeRules.AfterMarketOpen("SPY", 25),  lambda: BullBearCalc(self))
        #self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday, DayOfWeek.Wednesday, DayOfWeek.Friday), self.TimeRules.AfterMarketOpen("SPY", 60), lambda: MarketDirectionSMA200(self))
        self.Schedule.On(self.DateRules.WeekEnd("SPY"), self.TimeRules.At(23, 59),  lambda: WeekEnd(self))


        #self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 30), lambda: buySectorTrendSignal(self))           
        #self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 40), lambda: sellSignals(self))
        #self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 30), lambda: sellReversalSignals(self))

        #ML
        self.Schedule.On(self.DateRules.WeekStart("SPY"), self.TimeRules.BeforeMarketClose('SPY', 10), self.create_model)
        #self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen('SPY', minutes=1), Action(self.trade))       
             
                 
        #self.Schedule.On(self.DateRules.EveryDay("SPY"),
        #         self.TimeRules.Every(timedelta(hours=7.5)),
        #         self.exitTrade)
                 
#        self.Schedule.On(self.DateRules.EveryDay("SPY"),
#                 self.TimeRules.Every(timedelta(hours=1)),
#                 self.buySignals)
        
#        self.Schedule.On(self.DateRules.EveryDay("SPY"),
#                 self.TimeRules.Every(timedelta(hours=1)),
#                 self.sellSignals)


        #self.AddRiskManagement(TrailingStopRiskManagementModel(0.04))
        self.SetWarmUp(timedelta(days=200))
        

    def Coarse(self, coarse):
        if self.Time.month == self.lastMonth:
            return Universe.Unchanged
        self.lastMonth = self.Time.month
        
        allCoarse = [x for x in coarse if x.HasFundamentalData and x.Price > 1 and x.Volume > 1]
        finalCoarse = sorted(allCoarse, key = lambda x: x.DollarVolume, reverse = True)
        
        return [x.Symbol for x in finalCoarse][:self.numberOfSymbolsCoarse]
        return self.tickers
    
    def Fine(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)[:self.exposureToSector]:
                filteredSymbols.append(x.Symbol)
        
        
    
        return filteredSymbols[:5]
        self.tickers = filteredSymbols + self.manually_selected
        self.Log("tickers: {0}".format(self.tickers))
    
   

    def beforeTheOpen(self):
        return

    def rebal(self):
        self.Trade = True
    
    def OnData(self, data):
            if self.Trade:
                # Get price data and trading weights
                h = self.History(self.eqs,self.hprd,Resolution.Daily)['close'].unstack(level=0)
                wts = self.trade_wts(h)

                # trade
                port_tgt = [PortfolioTarget(x,y) for x,y in zip(wts.index,wts.values/2)]
                self.SetHoldings(port_tgt)
            
                self.Trade = False
            
    def create_model(self):
        
        for symbol in self.tickers: 

            recent_prices = self.History([symbol], self.history_range)['close'].values
            price_changes = np.diff(recent_prices).tolist()
        
            for i in range(self.history_range-self.lookback-1):
                self.X.append(price_changes[i:i+self.lookback]) 
                self.y.append(price_changes[i+self.lookback])
            
            self.model.fit(self.X, self.y)
    
    def trade_wts(self,hist):
        # initialize wts Series
        wts = pd.Series(0,index=hist.columns)
        # end of month values
        h_eom = (hist.loc[hist.groupby(hist.index.to_period('M')).apply(lambda x: x.index.max())]
                .iloc[:-1,:])

        # =====================================
        # check if canary universe is triggered
        # =====================================
        # build dataframe of momentum values
        mom = h_eom.iloc[-1,:].div(h_eom.iloc[[-p-1 for p in self.prds],:],axis=0)-1
        mom = mom.loc[:,self.canary].T
        # Determine number of canary securities with negative weighted momentum
        n_canary = np.sum(np.sum(mom.values*self.prdwts,axis=1)<0)
        # % equity offensive 
        pct_in = 1-min(1,n_canary/self.B)

        # =====================================
        # get weights for offensive and defensive universes
        # =====================================
        # determine weights of offensive universe
        if pct_in > 0:
            # price / SMA
            mom_in = h_eom.iloc[-1,:].div(h_eom.iloc[[-t for t in range(1,self.LO+1)]].mean(axis=0),axis=0)
            mom_in = mom_in.loc[self.offensive].sort_values(ascending=False)
            # equal weightings to top relative momentum securities
            in_wts = pd.Series(pct_in/self.TO,index=mom_in.index[:self.TO])
            wts = pd.concat([wts,in_wts])
        # determine weights of defensive universe
        if pct_in < 1:
            # price / SMA
            mom_out = h_eom.iloc[-1,:].div(h_eom.iloc[[-t for t in range(1,self.LD+1)]].mean(axis=0),axis=0)
            mom_out = mom_out.loc[self.alldefensive].sort_values(ascending=False)
            # equal weightings to top relative momentum securities
            out_wts = pd.Series((1-pct_in)/self.TD,index=mom_out.index[:self.TD])
            wts = pd.concat([wts,out_wts])     
        
        wts = wts.groupby(wts.index).sum()

        return wts

    
    #def OnEndOfAlgorithm(self):
    #    self.portfolio_holdings()
    #    self.write_stage_log()


    def tradeStart(self):
        self.trade = True

    def tradeEnd(self):
        self.trade = False       
    
    

    def portfolio_holdings(self): 
        self.Log("-- Portfolio --")
        for kvp in self.Portfolio:
            if kvp.Value.Invested:
                symbol = kvp.Key  #full security key
                holding = kvp.Value
                ticker = holding.Symbol.Value 
                quantity = holding.Quantity
                avgprice = holding.AveragePrice
                cost = quantity * avgprice
                price =self.Portfolio[symbol].Price
                unrealized_profit = self.Portfolio[symbol].UnrealizedProfit
                net = (unrealized_profit / cost) * 100
                s1 = '{:3.2f}'.format(avgprice) + ',' + '{:3.2f}'.format(price) + ',' + '{:3.2f}'.format(net) + ',' + '{:3.2f}'.format(unrealized_profit)   
                self.Log(ticker + "," + str(quantity) + "," + s1)
        return()
        
    def add_stage_log(self, stage, stage_num):
        d1 = str(self.Time)
        entry_date = d1[0:10]
        for key in self.symbols_dict:
            self.stage_log_df = self.stage_log_df.append({
            'stage_date': entry_date,
            'stage_num': stage_num,
            'stage': stage,
            'stage_days': 0,
            'symbol': self.symbols_dict[key][0],
            'price' : self.Securities[self.symbols_dict[key][0]].Price
            }, ignore_index = True)
       
        self.Log(d1 + "," + stage + "," + str(stage_num) )
        
        
    def write_stage_log(self):
        #Convert each stage_date and stage_num group to a single row
        df_out = self.stage_log_df.set_index(['stage_date','stage_num','stage',self.stage_log_df.groupby(['stage_date','stage_num','stage']).cumcount()+1]).unstack().sort_index(level=1, axis=1)
        df_out.columns = df_out.columns.map('{0[0]}_{0[1]}'.format)
        df_out.reset_index()
        
        #calculate the gain and net change for each symbol in the row
        for x in range(1, (len(self.symbols_dict)+1)):
            gain_col = 'gain_' + str(x)
            price_col = 'price_' + str(x)
            net_col = "net_" + str(x)
            df_out[gain_col] =  (df_out[price_col].shift(-1)- df_out[price_col]) #calculate the gain during the stage
            df_out[net_col]  = (df_out[gain_col] / df_out[price_col]) * 100 #calculate the net change during the stage
        
        df_out.fillna(0,inplace=True)
        """
        #self.stage_log_df['start_date'] = pd.to_datetime(self.stage_log_df['entry_date'], format="%Y-%m-%d")
        
        """
        
        #for each row build output log string
        print_header = True
        for index, row in df_out.iterrows():
            s1 = str(index[0])  + "," + str(index[1]) + "," + str(index[2]) + ","
            x1 = str(index[0])  + "," + str(index[1]) + "," + str(index[2]) + ","

            for x in range(1, (len(self.symbols_dict)+1)):
                symbol_col = 'symbol_' + str(x)
                gain_col = 'gain_' + str(x)
                price_col = 'price_' + str(x)
                net_col = "net_" + str(x)
                s2 = symbol_col + "," + price_col + "," + gain_col + "," + net_col + ","
                s1 = s1 + s2

                symbol_val = row[symbol_col]
                gain_val = '{:3.2f}'.format(row[gain_col])
                price_val = '{:3.2f}'.format(row[price_col])
                net_val = '{:3.2f}'.format(row[net_col])
                x2 = symbol_val + "," + price_val + "," + gain_val + "," + net_val + ","
                x1 = x1 + x2

            if print_header :
                self.Log (s1)
                print_header = False
            self.Log (x1)
    
class symbolMarkData:
    def __init__(self, symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, macd, macdSlow, rsi, RSIConsolidate, smaConsolidate):
        self.Symbol = symbol
        self.ema7 = ema7
        self.sma20 = sma20
        self.ema20 = ema20
        self.sma50 = sma50
        self.sma200 = sma200
        self.macd = macd
        self.macdSlow = macdSlow
        self.rsi = rsi
        self.RSIConsolidate = RSIConsolidate
        self.smaConsolidate = smaConsolidate

class symbolMarketData:
    def __init__(self, symbol, sma7, sma20, sma50, sma100, sma200, DCHindicator):
        self.Symbol = symbol
        self.sma7 = sma7
        self.sma20 = sma20
        self.sma50 = sma50
        self.sma100 = sma100
        self.sma200 = sma200
        self.DCHindicator = DCHindicator

class symbolvolData:
    def __init__(self, symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, rsi, macd, macdSlow, DCHindicator, RSIConsolidate, smaConsolidate):
        self.Symbol = symbol
        self.ema7 = ema7
        self.sma20 = sma20
        self.sma50 = sma50
        self.ema50 = ema50
        self.sma100 = sma100
        self.sma200 = sma200
        self.rsi = rsi
        self.macd = macd
        self.macdSlow = macdSlow
        self.DCHindicator = DCHindicator

        self.RSIConsolidate = RSIConsolidate
        self.smaConsolidate = smaConsolidate


class SymbolData:
    def __init__(self, symbol, ema7, sma20, ema20, sma50, ema50, sma100, sma200, rsi, macd, macdSlow, DCHindicator, RSIConsolidate, smaConsolidate):
        self.Symbol = symbol
        self.ema7 = ema7
        self.sma20 = sma20
        self.sma50 = sma50
        self.ema50 = ema50
        self.sma100 = sma100
        self.sma200 = sma200
        self.rsi = rsi
        self.macd = macd
        self.macdSlow = macdSlow
        self.DCHindicator = DCHindicator

        self.RSIConsolidate = RSIConsolidate
        self.smaConsolidate = smaConsolidate

class QuandlCustomColumns(PythonQuandl):
    def __init__(self):
        # Define ValueColumnName: cannot be None, Empty or non-existant column name
        self.ValueColumnName = "Value"


class SecurityData:
        def __init__(self, symbol, history):
            self.symbol = symbol
            self.fast = ExponentialMovingAverage(4)
            self.slow = ExponentialMovingAverage(30)
            self.vol = ExponentialMovingAverage(30)
            
            self.isBubble = False
            self.ratio = 0
            
            for bar in history.itertuples():
                self.fast.Update(bar.Index[1], bar.close)
                self.slow.Update(bar.Index[1], bar.close)
                self.vol.Update(bar.Index[1], ((bar.open + bar.close)/2.0) * bar.volume) # approx. dollar volume
        
        def update(self, time, price, volume):
            if self.fast.Update(time, price) and self.slow.Update(time, price) and self.vol.Update(time, volume):
                self.isBubble = (self.fast.Current.Value > (2.0 * self.slow.Current.Value)) and (price > self.slow.Current.Value)
                self.ratio = self.fast.Current.Value/self.slow.Current.Value
#region imports
from AlgorithmImports import *
#endregion
from QuantConnect.Algorithm.Framework.Risk import RiskManagementModel

# bracket risk model class
class BracketRiskModel(RiskManagementModel):
    '''Creates a trailing stop loss for the maximumDrawdownPercent value and a profit taker for the maximumUnrealizedProfitPercent value'''
    def __init__(self, maximumDrawdownPercent = 0.05, maximumUnrealizedProfitPercent = 0.05):
        self.maximumDrawdownPercent = -abs(maximumDrawdownPercent)
        self.trailingHighs = dict()
        self.maximumUnrealizedProfitPercent = abs(maximumUnrealizedProfitPercent)

    def ManageRisk(self, algorithm, targets):
        riskAdjustedTargets = list()
        for kvp in algorithm.Securities:
            symbol = kvp.Key
            security = kvp.Value

            # Remove if not invested
            if not security.Invested:
                self.trailingHighs.pop(symbol, None)
                continue
            pnl = security.Holdings.UnrealizedProfitPercent
            
            if pnl > self.maximumUnrealizedProfitPercent:
                # liquidate
                algorithm.Debug(f"Profit Taken: {security.Symbol}")
                algorithm.Log(f"Profit Taken: {security.Symbol}")
                riskAdjustedTargets.append(PortfolioTarget(security.Symbol, 0))
                return riskAdjustedTargets
                
            # Add newly invested securities
            if symbol not in self.trailingHighs:
                self.trailingHighs[symbol] = security.Holdings.AveragePrice   # Set to average holding cost
                continue

            # 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]
            drawdown = (security.Low / securityHigh) - 1

                
            if drawdown < self.maximumDrawdownPercent:
                # liquidate
                algorithm.Debug(f"Losses Taken: {security.Symbol}")
                algorithm.Log(f"Losses Taken: {security.Symbol}")
                riskAdjustedTargets.append(PortfolioTarget(symbol, 0))
                
        return riskAdjustedTargets
 #region imports
from AlgorithmImports import *
from main import *

def Rebalance(self):
        if self.IsWarmingUp or not self.mom.IsReady or not self.sma.IsReady: return
        initial_asset = self.symbols_dict['QQQ'][0] if self.mom.Current.Value > 0 else self.symbols_dict['TLT'][0]
        
        if self.init:
            self.SetHoldings(initial_asset, .5)
            self.init = False
            
        keihist = self.History([self.kei], 1400)
        #returns the historical data for custom 90 day period.
        #keihist = self.History([self.kei],self.StartDate-timedelta(100),self.StartDate-timedelta(10))
        
        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):
        if (keimom < 0 and kei < keihistmidt and  kei > keihistlowt) and not (self.stage == 5):
            # DECLINE
#            self.Liquidate('MTUM')
#            self.Liquidate('TLT')
#            self.Liquidate('XMMO')
#            self.Liquidate('QQQ')            
            self.stage = 5
            self.SetHoldings(self.symbols_dict['GLD'][0], .2)
            self.add_stage_log("DECLINE", self.stage)
            
        elif (keimom > 0 and kei < keihistlowt) and not (self.stage == 1):
            # RECOVERY
#            self.Liquidate('GLD')
#            self.Liquidate('TLT')
#            self.Liquidate('QQQ')
#            self.Liquidate('XMMO')
            self.stage = 1
            self.SetHoldings(self.symbols_dict['MTUM'][0], .2)
            self.add_stage_log("RECOVERY", self.stage)

        elif (keimom > 0 and kei > keihistlowt and kei < keihistmidt) and not (self.stage == 2):
            # EARLY
#            self.Liquidate('GLD')
#            self.Liquidate('TLT')
#            self.Liquidate('MTUM')
#            self.Liquidate('QQQ')
            self.stage = 2
            self.SetHoldings(self.symbols_dict['XMMO'][0], .2)
            self.add_stage_log("EARLY", self.stage)
        
        elif (keimom > 0 and kei > keihistmidt and kei < keihisthight) and not (self.stage == 3):    
            # REBOUND
#            self.Liquidate('GLD')
#            self.Liquidate('XMMO')
#            self.Liquidate('QQQ')
#            self.Liquidate('TLT')
            self.stage = 3
            self.SetHoldings(self.symbols_dict['MTUM'][0], .2)
            self.add_stage_log("REBOUND", self.stage)
                    
        elif (keimom < 0 and kei < keihisthight and kei > keihistmidt) and not (self.stage == 4):
            # LATE
#            self.Liquidate('GLD')
#            self.Liquidate('XMMO')
#            self.Liquidate('MTUM')
#            self.Liquidate('TLT')
            self.stage = 4
            self.SetHoldings(self.symbols_dict['QQQ'][0], .2)
            self.add_stage_log("LATE", self.stage)
            

        elif (keimom < 0 and kei < 100 and not self.Securities[self.bond].Invested) and not (self.stage == 6):
#            self.Liquidate('GLD')
#            self.Liquidate('XMMO')
#            self.Liquidate('MTUM')
#            self.Liquidate('QQQ')
            self.stage = 6
            self.SetHoldings(self.symbols_dict['TLT'][0], .2)
            self.add_stage_log("BONDS", self.stage)
            
        
        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)
        self.Plot("Stage","recovery = 1 early = 2 rebound = 3 late = 4 decline = 5",self.stage)

def BullBearCalc(self):

    if self.Securities[self.spyg].Invested or self.Securities[self.eem].Invested or self.Securities[self.efa].Invested:
        self.MarketTrend = 1
    
    elif self.Securities[self.bil].Invested or self.Securities[self.dbc].Invested or self.Securities[self.ief].Invested or self.Securities[self.tip].Invested or self.Securities[self.vglt].Invested:
        self.MarketTrend = 0

def stageIndicator(self):
        if self.IsWarmingUp or not self.mom.IsReady or not self.sma.IsReady: 
            return
        if self.stage == 0:
            return
        if self.stage == 1 and self.Securities[self.spyg].Invested or self.Securities[self.eem].Invested or self.Securities[self.efa].Invested:            
            #for symbol in self.RecoveryStocks:
            for symbol, symbolData in self.RecoveryStocksDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value):# and (self.Securities[symbol].Close < symbolData.DCHindicator.LowerBand.Current.Value):
                    self.SetHoldings(symbol, .15, False, "KEI Long Recovery Stage")
                    self.Notify.Web("https://discord.com/api/webhooks/1040435197092569099/86mE02R0GzQrJDuQ9QdsY4CMQInj14H9I_Ncu5q_28Ic5scrdcPaGMOO3A83JobSh-2X", "KEI Long Recovery Stage")    
#            for symbol, symbolvolData in self.volatilityDataBySymbol.items():
#                if not self.Portfolio[symbol].Invested  and (self.Trend0Recovery.Value > 0) and (self.Securities[symbol].Open > symbolvolData.sma50.Current.Value):
#                    self.SetHoldings(symbol, .15, False, "KEI Long Recovery Stage 2")
        if self.stage == 2 and self.Securities[self.spyg].Invested or self.Securities[self.eem].Invested or self.Securities[self.efa].Invested:            
            #for symbol in self.EarlyStocks:
            for symbol, symbolData in self.EarlyStocksDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value):# and (self.Securities[symbol].Close < symbolData.DCHindicator.LowerBand.Current.Value):
                    self.SetHoldings(symbol, .1, False, "KEI Long Early Stage")    
                    self.Notify.Web("https://discord.com/api/webhooks/1040435197092569099/86mE02R0GzQrJDuQ9QdsY4CMQInj14H9I_Ncu5q_28Ic5scrdcPaGMOO3A83JobSh-2X", "KEI Long Early Stage")    
#                for symbol, symbolvolData in self.volatilityDataBySymbol.items():
#                    if not self.Portfolio[symbol].Invested  and (self.Trend0Early.Value > 0) and (self.Securities[symbol].Open > symbolvolData.sma50.Current.Value):
#                        self.SetHoldings(symbol, .1, False, "KEI Long Early Stage 2")
        if self.stage == 3 and self.Securities[self.spyg].Invested or self.Securities[self.eem].Invested or self.Securities[self.efa].Invested:            
            #for symbol in self.ReboundStocks:
            for symbol, symbolData in self.ReboundStocksDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) or (self.Trend0Rebound.Value > 0):# and (self.Securities[symbol].Close < symbolData.DCHindicator.LowerBand.Current.Value):
                    self.SetHoldings(symbol, .15, False, "KEI Long Rebound Stage")
                    self.Notify.Web("https://discord.com/api/webhooks/1040435197092569099/86mE02R0GzQrJDuQ9QdsY4CMQInj14H9I_Ncu5q_28Ic5scrdcPaGMOO3A83JobSh-2X", "KEI Long Rebound Stage")    
#               for symbol, symbolvolData in self.volatilityDataBySymbol.items():
#                    if not self.Portfolio[symbol].Invested  and (self.Trend0Rebound.Value > 0) and (self.Securities[symbol].Open > symbolvolData.sma50.Current.Value):
#                        self.SetHoldings(symbol, .15, False, "KEI Long Rebound Stage 2")

        if self.stage == 4 and self.Securities[self.spyg].Invested or self.Securities[self.eem].Invested or self.Securities[self.efa].Invested:                  
            #for symbol in self.LateStocks:
                for symbol, symbolData in self.LateStocksDataBySymbol.items():
                    if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) or (self.Trend0Late.Value > 0):# and (self.Securities[symbol].Close < symbolData.DCHindicator.LowerBand.Current.Value):
                        self.SetHoldings(symbol, .15, False, "KEI Long Late Stage")
                        self.Notify.Web("https://discord.com/api/webhooks/1040435197092569099/86mE02R0GzQrJDuQ9QdsY4CMQInj14H9I_Ncu5q_28Ic5scrdcPaGMOO3A83JobSh-2X", "KEI Long Late Stage")    
#                   for symbol, symbolvolData in self.volatilityDataBySymbol.items():
#                       if not self.Portfolio[symbol].Invested  and (self.Trend0Late.Value > 0) and (self.Securities[symbol].Open > symbolvolData.sma50.Current.Value):
#                           self.SetHoldings(symbol, .15, False, "KEI Long Late Stage 2")

        if self.stage == 5 and self.Securities[self.spyg].Invested or self.Securities[self.eem].Invested or self.Securities[self.efa].Invested:            
            #for symbol in self.DeclineStocks:
            for symbol, symbolData in self.DeclineStocksDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) or (self.Trend0Decline.Value > 0):# and (self.Securities[symbol].Close < symbolData.DCHindicator.LowerBand.Current.Value):
                    self.SetHoldings(symbol, .25, False, "KEI Long Decline Stage")
                    self.Notify.Web("https://discord.com/api/webhooks/1040435197092569099/86mE02R0GzQrJDuQ9QdsY4CMQInj14H9I_Ncu5q_28Ic5scrdcPaGMOO3A83JobSh-2X", "KEI Long Decline Stage")
#           for symbol, symbolvolData in self.volatilityDataBySymbol.items():
#                if not self.Portfolio[symbol].Invested  and (self.Trend0Decline.Value > 0) and (self.Securities[symbol].Open > symbolvolData.sma50.Current.Value):
#                    self.SetHoldings(symbol, .15, False, "KEI Long Decline Stage 2")

        if self.stage == 6:
            return

def stageIndicatorBear(self):
        if self.IsWarmingUp or not self.mom.IsReady or not self.sma.IsReady: 
            return
        #if self.stage == 1 and self.Securities[self.ief].Invested or self.Securities[self.bil].Invested or self.Securities[self.vglt].Invested or self.Securities[self.lqd].Invested or self.Securities[self.tip].Invested or self.Securities[self.dbc].Invested:            
        #    for symbol, symbolData in self.BearRecoveryStocksDataBySymbol.items():
        #        if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value):# and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
        #            self.SetHoldings(symbol, .15, False, "KEI Bear")
        #if self.stage == 2 and self.Securities[self.ief].Invested or self.Securities[self.bil].Invested or self.Securities[self.vglt].Invested or self.Securities[self.lqd].Invested or self.Securities[self.tip].Invested or self.Securities[self.dbc].Invested:  
        #    for symbol, symbolData in self.BearEarlyStocksDataBySymbol.items():
        #        if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value):# and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
        #            self.SetHoldings(symbol, .1, False, "KEI Bear")
        #if self.stage == 3 and self.Securities[self.ief].Invested or self.Securities[self.bil].Invested or self.Securities[self.vglt].Invested or self.Securities[self.lqd].Invested or self.Securities[self.tip].Invested or self.Securities[self.dbc].Invested: 
        #    for symbol, symbolData in self.BearReboundStocksDataBySymbol.items():
        #        if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value):# and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
        #            self.SetHoldings(symbol, .15, False, "KEI Bear")
        if self.stage == 4 and self.Securities[self.ief].Invested or self.Securities[self.bil].Invested or self.Securities[self.vglt].Invested or self.Securities[self.lqd].Invested or self.Securities[self.tip].Invested or self.Securities[self.dbc].Invested:      
            for symbol, symbolData in self.BearLateStocksDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value):# and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
                    self.SetHoldings(symbol, .2, False, "KEI Bear")
                    self.Notify.Web("https://discord.com/api/webhooks/1040435197092569099/86mE02R0GzQrJDuQ9QdsY4CMQInj14H9I_Ncu5q_28Ic5scrdcPaGMOO3A83JobSh-2X", "KEI Bear Energy Stage")
        #if self.stage == 5 and self.Securities[self.ief].Invested or self.Securities[self.bil].Invested or self.Securities[self.vglt].Invested or self.Securities[self.lqd].Invested or self.Securities[self.tip].Invested or self.Securities[self.dbc].Invested: 
        #    for symbol, symbolData in self.BearDeclineStocksDataBySymbol.items():
        #        if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value):# and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
        #            self.SetHoldings(symbol, .15, False, "KEI Bear")

            
def stageTradeManager(self):
        if self.IsWarmingUp or not self.mom.IsReady or not self.sma.IsReady: 
            return
        if self.stage == 0:
            return
        if self.stage == 1:
            for symbol, symbolData in self.EarlyStocksDataBySymbol.items() and self.ReboundStocksDataBySymbol.items() and self.LateStocksDataBySymbol.items() and self.DeclineStocksDataBySymbol.items():
                if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
                    self.Liquidate('XLE')
                    self.Liquidate('XLF')
                    self.Liquidate('XLI')
                    self.Liquidate('XLU')
                    self.Liquidate('XLK')
                    self.Liquidate('XLV')
                    self.Liquidate('XLP')
        #XLB, XLY
        if self.stage == 2:
            for symbol, symbolData in self.RecoveryStocksDataBySymbol.items() and self.ReboundStocksDataBySymbol.items() and self.LateStocksDataBySymbol.items() and self.DeclineStocksDataBySymbol.items():
                if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
                    self.Liquidate("XLB")
                    self.Liquidate("XLY")
                    self.Liquidate("XLK")
                    self.Liquidate("XLV")
                    self.Liquidate("XLK")
                    self.Liquidate("XLP")
        #XLE, XLF,XLI
        if self.stage == 3:
            for symbol, symbolData in self.EarlyStocksDataBySymbol.items() and self.RecoveryStocksDataBySymbol.items() and self.LateStocksDataBySymbol.items() and self.DeclineStocksDataBySymbol.items():
                if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
                    self.Liquidate("XLB")
                    self.Liquidate("XLY")
                    self.Liquidate("XLE")
                    self.Liquidate("XLF")
                    self.Liquidate("XLI")
                    self.Liquidate("XLV")
                    self.Liquidate("XLP")
        #XLK, XLU
        if self.stage == 4:        
            for symbol, symbolData in self.EarlyStocksDataBySymbol.items() and self.ReboundStocksDataBySymbol.items() and self.RecoveryStocksDataBySymbol.items() and self.DeclineStocksDataBySymbol.items():
                if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
                    self.Liquidate("XLB")
                    self.Liquidate("XLY")
                    self.Liquidate("XLE")
                    self.Liquidate("XLF")
                    self.Liquidate("XLI")
                    self.Liquidate("XLU")
                    self.Liquidate("XLP")
        #XLK, XLV

            #for symbol in self.LateStocks:
            #for symbol, symbolData in self.LateStocksDataBySymbol.items():
            #    if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value):
            #        self.SetHoldings(symbol, .15, False, "Profit Taken KEI Long")
        if self.stage == 5:
            for symbol, symbolData in self.EarlyStocksDataBySymbol.items() and self.ReboundStocksDataBySymbol.items() and self.RecoveryStocksDataBySymbol.items() and self.LateStocksDataBySymbol.items():
                if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
                    self.Liquidate("XLB")
                    self.Liquidate("XLY")
                    self.Liquidate("XLE")
                    self.Liquidate("XLF")
                    self.Liquidate("XLI")
                    self.Liquidate("XLU")
                    self.Liquidate("XLV")
            #XLP
        if self.stage == 6:
            return

def stageBearTradeManager(self):
        if self.IsWarmingUp or not self.mom.IsReady or not self.sma.IsReady: 
            return
        if self.stage == 0:
            return
        if self.stage == 1:
            #for symbol in self.BearRecoveryStocks:
#                for symbol, symbolData in self.BearEarlyStocksDataBySymbol.items() and self.BearReboundStocksDataBySymbol.items() and self.BearLateStocksDataBySymbol.items():
#                    if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
#                        self.Liquidate()
            for symbol, symbolData in self.BearRecoveryStocksDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):# and (self.Securities[symbol].Close < self.low.Current.Value): 
                    self.Liquidate('VCR')


        if self.stage == 2:
            #for symbol in self.BearEarlyStocks:    
#                for symbol, symbolData in self.RecoveryStocksDataBySymbol.items() and self.BearReboundStocksDataBySymbol.items() and self.BearLateStocksDataBySymbol.items():
#                    if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
#                        self.Liquidate()
            for symbol, symbolData in self.BearEarlyStocksDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
                    self.Liquidate('VFH')
        if self.stage == 3:
            #for symbol in self.BearReboundStocks:
#                for symbol, symbolData in self.BearEarlyStocksDataBySymbol.items() and self.RecoveryStocksDataBySymbol.items() and self.BearLateStocksDataBySymbol.items():
#                    if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
#                        self.Liquidate()
            for symbol, symbolData in self.BearReboundStocksDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
                    self.Liquidate('VGT')
                    self.Liquidate('VOX')
                    
        if self.stage == 4:
            #for symbol in self.BearLateStocks:        
#            for symbol, symbolData in self.BearEarlyStocksDataBySymbol.items() and self.BearReboundStocksDataBySymbol.items() and self.RecoveryStocksDataBySymbol.items():
#                if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
#                    self.Liquidate()
            for symbol, symbolData in self.BearLateStocksDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
                    self.Liquidate('VDE')
        if self.stage == 5:
            #for symbol in self.BearDeclineStocks: 
#            for symbol, symbolData in self.BearEarlyStocksDataBySymbol.items() and self.BearReboundStocksDataBySymbol.items() and self.BearRecoveryStocksDataBySymbol.items() and self.BearLateStocksDataBySymbol.items():
#                if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
#                    self.Liquidate()
            for symbol, symbolData in self.BearDeclineStocksDataBySymbol.items():
                if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value):
                    self.Liquidate('VDE')
                    self.Liquidate('VAW')
        if self.stage == 6:
            return

def buyLongTrendSingal(self):              
    if self.trade == False:
        return


    if len(self.y) > self.lookback:
            
        recent_prices = self.History(['SPY'], self.lookback+1)['close'].values
        price_changes = np.diff(recent_prices)
            
        prediction = self.model.predict(price_changes.reshape(1, -1))
            
    for symbol, symbolData in self.symbolDataBySymbol.items():
        if not self.Portfolio[symbol].Invested and (symbolData.sma20.Current.Value > symbolData.sma50.Current.Value) and (symbolData.ema10.Current.Value > symbolData.sma50.Current.Value) and prediction > 0:
            #self.limitPrice = self.Securities[self.symbol].Price * 0.995
            #self.quantity = (self.Portfolio.MarginRemaining * 0.99) / self.limitPrice
            self.SetHoldings(symbol, .1, False, "Buy Trend Signal")

def buySectorTrendSignal(self):              
    if self.trade == False:
        return
        
    for symbol in self.MarketCaps:
        for symbol, symbolData in self.marketDataBySymbol.items():
            if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close < symbolData.sma200.Current.Value) and (self.Securities[symbol].Close < symbolData.DCHindicator.LowerBand.Current.Value): 
                    self.SetHoldings(symbol, .2, False, "Buy Sector Trend Signal")

def shortSectorTrendSignal(self):              
    if self.trade == False:
        return
        
    for symbol in self.MarketCaps:
        for symbol, symbolData in self.marketDataBySymbol.items():
            if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close < symbolData.sma200.Current.Value) and (self.Securities[symbol].Close > symbolData.DCHindicator.UpperBand.Current.Value): 
                    self.SetHoldings(symbol, .2, False, "Buy Sector Trend Signal")

                    
def sellSignals(self):
    if self.trade == False:
        return
    for symbol, symbolData in self.marketDataBySymbol.items():
        if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > self.DCHindicatorShort.UpperBand.Current.Value):
            self.SetHoldings(symbol, -.2, False, "Sell Sector Trend Signal")

def sellReversalSignals(self):
    if self.trade == False:
        return
    for symbol, symbolData in self.marketDataBySymbol.items():
        if self.Portfolio[symbol].Invested and (symbolData.rsi.Current.Value > 70):
            self.SetHoldings(symbol, -.2, False, "Sell Reversal Signal")

                    #("SPXS", .5, False, "TakeProfit")

def shortSignals(self):
    if self.trade == False:
        return

    for symbol, symbolData in self.symbolDataBySymbol.items():
        if not self.Portfolio[symbol].Invested and (symbolData.sma20.Current.Value < symbolData.sma50.Current.Value) and (symbolData.ema10.Current.Value < symbolData.sma50.Current.Value):# and (self.midhigh.Current.Value < self.high.Current.Value):
                self.SetHoldings(symbol, -.1, False, "Short Signal")           

def coverSignals(self):
    if self.trade == False:
        return
    for symbol, symbolData in self.symbolDataBySymbol.items():
        if self.Portfolio[symbol].Invested and (symbolData.RSIConsolidate.Current.Value < 10):
            self.SetHoldings(symbol, .1, False, "Cover Signal")
            #("SPXS", .5, False, "TakeProfit")

def exitTrade(self):
    if  self.trade == False:
        return
    for symbol, symbolData in self.symbolDataBySymbol.items():
        if self.Portfolio[symbol].Invested and (self.Portfolio[symbol].UnrealizedProfit<= -250) or (self.Portfolio[symbol].UnrealizedProfit>= 500):
        # self.Debug("Sell at "+str(self.Securities[symbol].Price))
            self.Liquidate(symbol, "Profit or Loss take")

def exitShort(self):
    if self.trade == False:
        return
    for symbolmark, symbolMarkData in self.marketDataBySymbol.items():
        if self.Portfolio[symbolmark].Invested and (self.Portfolio[symbolmark].UnrealizedProfit<= -100) or (self.Portfolio[symbolmark].UnrealizedProfit>= 200):
            self.Liquidate("SPXS", "Short Market Cover")

# Times
def WeekEnd(self):
        self.state = False

#def MarketDirectionSMA200(self):
#    if self.IsWarmingUp:
#        return
#    for symbol, symbolMarketData in self.marketData.items():
#        if (self.Securities['SPY'].Close > symbolMarketData.sma200.Current.Value):
#            self.MarketDir = 1
#    for symbol, symbolMarketData in self.marketData.items():
#        if (self.Securities['SPY'].Close < symbolMarketData.sma200.Current.Value):
#            self.MarketDir = 0

def SuperTrendCalc(self):
    if self.IsWarmingUp:
        return
        
#If Trend up set.trendstage = 2
#if Trend down set.trendstage = 3
#if Trend down liqudiate
#
from AlgorithmImports import *
from main import *



class Trend0(PythonIndicator):
    def __init__(self, name, period, exponent):
        self.Name = name
        self.period = period
        self.exponent = exponent
        self.Time = datetime.min
        self.Value = 0
        self.prices = np.array([])


    def Update(self, input):
        
        self.prices = np.append(self.prices, input.Close)[-self.period:]
        
        # IsReady?
        if len(self.prices) != self.period:
            self.Value = 0
            return False
        
        self.Value = self.calc_trend()
        return True
    
    def calc_trend(self):
        changes = np.array([])
        for i in range(len(self.prices) - 1):
            _return = (self.prices[i + 1] - self.prices[i]) / self.prices[i]
            changes = np.append(changes, _return)
        return self.power_weighted_moving_average(changes)
    
    def power_weighted_moving_average(self, changes):
        return self.weighted_average(changes, self.exponential_weights(len(changes)))
        
    def exponential_weights(self, length):
        weights = np.array([])
        for i in range(length):
            w = i + 1
            weights = np.append(weights, w**self.exponent)
        return weights
        
    def weighted_average(self, changes, weights):
        products = []
        for i in range(len(changes)):
            products.append(changes[i] * weights[i])
        return sum(products) / sum(weights)