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)