Overall Statistics
Total Trades
92
Average Win
0.00%
Average Loss
0.00%
Compounding Annual Return
0.003%
Drawdown
0.000%
Expectancy
0.026
Net Profit
0.000%
Sharpe Ratio
-2.727
Probabilistic Sharpe Ratio
31.343%
Loss Rate
40%
Win Rate
60%
Profit-Loss Ratio
0.71
Alpha
-0.001
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
-26.171
Tracking Error
0.095
Treynor Ratio
-0.51
Total Fees
$92.00
class ResistanceTachyonCoreWave(QCAlgorithm):

    def Initialize(self):
        
        # Set the start and end date
        self.SetStartDate(2019, 3, 8)
        self.SetEndDate(2019, 3, 13)
        
        # Set the cash amount
        self.SetCash(100000000)
        
        # Call coarse and fine universe
        self.UniverseSettings.Resolution = Resolution.Minute
        self.AddUniverse(self.CoarseSelectionFunction, self.FineSelectionFunction)
        
        # Initialize symbol data dictionary
        self.symbol_data_by_symbol = {}

        # Initialize 1 minute EMA dictionaries
        self.ema_short_by_symbol = {}
        self.ema_long_by_symbol = {}
        self.ema_longer_by_symbol = {}
        
        # Initialize 5 minute EMA dictionaries
        self.ema_nine_five = {}
        self.ema_eighteen_five = {}
        self.ema_thirtysix_five = {}
        
        # Initialize stop market order dictionaries
        self.highestPrice = {}
        self.stopMarketTicket = {}
        self.stopMarketOrderFillTime = {}
        
        # Checks if the data has passed through an adequate number of times
        self.passed_once = {}
        
        self.minutes_stayed_in = {}
        
        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(15, 55), self.BeforeMarketClose)
        
        self.breakout_in_last_mins = {}
        
        self.daily_open = {}
        
        self.done_open = {}
        
        self.ema_short_by_symbol = {}
        
        self.low_less_than = {}

    
    
    def OnSecuritiesChanged(self, changes):
    
        
        self.passed_once = {}

        for symbol in changes.RemovedSecurities:
            data = self.symbol_data_by_symbol.pop(symbol.Symbol, None)

            if data:
                data.dispose()
        
        # For each symbol in the added securites for the day
        for added in changes.AddedSecurities:
            # Set each symbol equal to a variable
            symbol = added.Symbol
            
            # Call the SymbolData function and add it to the dictionary for each symbol
            self.symbol_data_by_symbol[symbol] = SymbolData(symbol, self)
            
            self.ema_short_by_symbol[symbol] = RollingWindow[float](2)
            
            # Put in filler values for the stop market dictionaries
            self.highestPrice[symbol] = 0
            self.stopMarketTicket[symbol] = None
            
            # Create EMAs for each of the five minute dictionaries
            self.ema_nine_five[symbol] = ExponentialMovingAverage(9)
            self.ema_eighteen_five[symbol] = ExponentialMovingAverage(18)
            self.ema_thirtysix_five[symbol] = ExponentialMovingAverage(36)
            
            # Register each of these to a five minute auto update consolidator
            self.RegisterIndicator(symbol, self.ema_nine_five[symbol], timedelta(minutes=5))
            self.RegisterIndicator(symbol, self.ema_eighteen_five[symbol], timedelta(minutes=5))
            self.RegisterIndicator(symbol, self.ema_eighteen_five[symbol], timedelta(minutes=5))
            
            self.breakout_happened_in_last_mins = {}
            
            self.breakout_in_last_mins[symbol] = []
            
            self.low_less_than[symbol] = []
            
            
        
        
    # When data is received  
    def OnData(self, data):
        
        # For each symbol that we have in our algorithm
        for symbol, symbol_data in self.symbol_data_by_symbol.items():
            
            # Check if the data just pumped in contains the current symbol
            if data.ContainsKey(symbol) and data[symbol] is not None:
                    
                # Set the current EMAs to a variable  
                ema_short = symbol_data.ema_short.Current.Value
                ema_long = symbol_data.ema_long.Current.Value
                ema_longer = symbol_data.ema_longer.Current.Value
                
                self.ema_short_by_symbol[symbol].Add(float(ema_short))
                
                # Get the current value for the Low and Close 
                low_ = data[symbol].Low
                    
                # If EMA9 > EMA18 > EMA36
                ema_greater = ema_short > ema_long and ema_long > ema_longer   
                
                # If, on the 5 minute bar, EMA9 > EMA18 > EMA36
                ema_fives = self.ema_nine_five[symbol].Current.Value > self.ema_eighteen_five[symbol].Current.Value and self.ema_eighteen_five[symbol].Current.Value > self.ema_thirtysix_five[symbol].Current.Value
                
                low_below_fives = low_ < self.ema_nine_five[symbol].Current.Value

                # If ALL of these previous conditions are true
                if ema_fives:
                    self.breakout_in_last_mins[symbol].append("Y")
                    
                else:
                    self.breakout_in_last_mins[symbol].append("N")
                    
                if low_below_fives:
                    self.low_less_than[symbol].append("Y")
                    
                else:
                    self.low_less_than[symbol].append("N")
                    
                
                if len(self.breakout_in_last_mins[symbol]) > 10:
                    self.breakout_in_last_mins[symbol].pop(0)
                    
                if len(self.low_less_than[symbol]) > 5:
                    self.low_less_than[symbol].pop(0)
                
                    
                if len(self.breakout_in_last_mins[symbol]) > 9:
                    
                     # If the slopes of the EMAs are increasing in the last 1 bar
                    ema_slope_inc = ema_short > self.ema_short_by_symbol[symbol][1]
   
                    if ema_slope_inc and ema_slope_inc and "Y" in self.breakout_in_last_mins[symbol] and "Y" in self.low_less_than[symbol]:

                        # If the symbol is not invested currently
                        if not self.Portfolio[symbol].Invested:
                            
                            # Order 50 shares, and place a stop market for the same amount
                            self.MarketOrder(symbol, 20)
                            self.stopMarketTicket[symbol] = self.StopMarketOrder(symbol, -20, data[symbol].Close * .98)
                            self.minutes_stayed_in[symbol] = 0
                    
                        # If the symbol is already invested
                        else:
                            
                            # Check if the current price is greater than the last high
                            if data[symbol].Close > self.highestPrice[symbol]:
                                
                                # Save the new high, then update the stop price
                                self.highestPrice[symbol] = data[symbol].Close
                                updateFields = UpdateOrderFields()
                                #updateFields.StopPrice = data[symbol].Close * .95
                                updateFields.StopPrice = data[symbol].Close * .98
                                #updateFields.StopPrice = ema_short
                                self.stopMarketTicket[symbol].Update(updateFields)

            if self.Portfolio[symbol].Invested:
                self.minutes_stayed_in[symbol] += 1
            '''
            if self.minutes_stayed_in[symbol] == 5 and self.Portfolio[symbol].Invested:
                self.MarketOrder(symbol, 200)
                self.stopMarketTicket[symbol] = self.StopMarketOrder(symbol, -220, ema_short)
                self.minutes_stayed_in[symbol] = -100000
            '''

        
        # On each order event
        def OnOrderEvent(self, orderEvent):
            
            # If the order has been filled
            if orderEvent.Status != OrderStatus.Filled:
                return
            
            # If the price is below the trailing stop, sell the stock
            if self.stopMarketTicket[orderEvent.Symbol] is not None and self.stopMarketTicket[orderEvent.Symbol].OrderId == orderEvent.OrderId: 
                self.stopMarketOrderFillTime[orderEvent.Symbol] = self.Time
    
    # Coarse Universe Selection
    def CoarseSelectionFunction(self, coarse):
        
        # Sort descending by daily dollar volume
        sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
        
        # Filter for stocks in our price range
        pricefilter = [x for x in sortedByDollarVolume if x.Price > 1 and x.Price < 700]
        
        # Return the symbol objects of the top entries from our sorted collection
        return [ x.Symbol for x in pricefilter[:20] ]
        
    
    # Fine Universe Selection
    def FineSelectionFunction(self, fine):
        
        # Retrieve 10 days of historical data for each symbol
        selectedSymbols = []
        symbols = [x.Symbol for x in fine]
        history = self.History(symbols, 10, Resolution.Daily)
            
        # Iterate through symbols
        for symbol in symbols:
            
            if str(symbol) in history.index:
                
                # Find hsitory for specific symbol
                symbolhistory = history.loc[str(symbol)]
    
                # Create SMA and EMA for symbol and register it with algorithm
                symbolSMA = SimpleMovingAverage(10)
                #symbolEMA = ExponentialMovingAverage(9)
    
                # Iterate through historical data
                for tuple in symbolhistory.itertuples():
                    
                    # Update SMA and EMA with data time and volume
                    symbolSMA.Update(tuple.Index, tuple.volume)
                    #symbolEMA.Update(tuple.Index, tuple.close)
                
                # If the SMA and EMA pass a certain threshold, add to our selected symbols
                if float(str(symbolSMA)) > float(3500000):
                    selectedSymbols.append(symbol)
        
        # Return selected symbols
        self.Debug(self.Time)
        return selectedSymbols
        
    
    def BeforeMarketClose(self):
        self.Liquidate()
        
# Class to create data for our symbols        
class SymbolData:
    
    # Initialize
    def __init__(self, symbol, algorithm):
        
        # Define variables
        self.symbol = symbol
        self.algorithm = algorithm
        
        # Initialze our EMAs and SMAs
        self.ema_short = ExponentialMovingAverage(9)
        self.ema_long = ExponentialMovingAverage(18)
        self.ema_longer = ExponentialMovingAverage(36)
        self.sma_volume = SimpleMovingAverage(3)
        
        # Setup consolidator
        self.consolidator = TradeBarConsolidator(1)
        self.consolidator.DataConsolidated += self.consolidation_handler
        algorithm.SubscriptionManager.AddConsolidator(symbol, self.consolidator)
     
    # Dispose if removed   
    def dispose(self):
        self.algorithm.SubscriptionManager.RemoveConsolidator(self.symbol, self.consolidator)
     
    # On data consolidated   
    def consolidation_handler(self, sender, consolidated):
        
        # Set variables for time, close, and volume
        time = consolidated.EndTime
        close = consolidated.Close
        volume = consolidated.Volume
        
        # Update our EMAs and SMAs
        self.ema_short.Update(time, close)
        self.ema_long.Update(time, close)
        self.ema_longer.Update(time, close)
        self.sma_volume.Update(time, volume)