Overall Statistics |
Total Trades 6 Average Win 0% Average Loss -0.34% Compounding Annual Return -71.573% Drawdown 1.000% Expectancy -1 Net Profit -1.028% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 100% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -18.527 Tracking Error 0.087 Treynor Ratio 0 Total Fees $6.00 Estimated Strategy Capacity $15000000.00 |
''' Gap and Go Strategy -calculate best support options and weight for each -make sure supports are different -take profit: -New 1 min candle to make new low -Add a buffer (.03?) -at a certain level -Stop loss -Change from trailing to next support level below -Liquidate after 90 min -Relative vol filter? ''' class MeasuredRedSalmon(QCAlgorithm): success_count = 1 loss_count = 1 success_countt = 1 loss_countt = 1 def Initialize(self): self.SetStartDate(2021, 3, 10) # Set Start Date self.SetEndDate(2021, 3, 12) self.SetCash(100000) # Set Strategy Cash #self.nvx = self.AddEquity("NVAX", Resolution.Minute, Market.USA, True, 1.0, True) self.spy = self.AddEquity("SPY", Resolution.Minute, Market.USA, True, 1.0, True) self.UniverseSettings.Resolution = Resolution.Minute self.UniverseSettings.ExtendedMarketHours = True self.AddUniverse(self.Coarse, self.Fine) self.SetRiskManagement(MaximumDrawdownPercentPerSecurity(0.05)) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 0), self.collectPreMarketData) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 1), self.trackMarket) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 90), self.endMarket) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 100), self.LiquidatePositions) self.isPreMarket = False self.isMarket = False self.lastPrePrice = -1 self.highestPreMarket = 0 self.yesterday = -1 self.isGapped = False self.maxTraded = 5 self.securityWeight = .2 self.lastMonth = -1 self.activeSecurities = {} self.tradedToday = [] self.tradingSecurities = {} self.oneMinuteHigh = {} self.quarterPositions = {} self.oneMinuteLow = {} self.SetWarmUp(timedelta(days = 2)) def endMarket(self): self.isMarket = False self.tradedToday = [] self.tradingSecurities = {} self.oneMinuteHigh def trackMarket(self): sortedByGap = [x for x in self.activeSecurities.keys()] gapPercentBySymbol = {x.Symbol:x.isGapPercent for x in self.activeSecurities.values()} sortedByGap = sorted(sortedByGap, key = lambda x: self.activeSecurities[x].isGapPercent, reverse = True) finalGap = sortedByGap[:self.maxTraded] for symbol in finalGap: self.tradingSecurities[symbol] = self.activeSecurities[symbol] self.oneMinuteHigh[symbol] = self.Securities[symbol].High self.isMarket = True def collectPreMarketData(self): remove = [] for symbol, symbolData in self.activeSecurities.items(): symbolData.Open = self.Securities[symbol].Price historyMinute = self.History(symbol, 180, Resolution.Minute) historyDay = self.History(symbol, 1, Resolution.Daily) try: symbolData.YesterdayClose = float(historyDay["close"]) except: remove.append(symbol) continue preMarketHigh = -1 support1 = 100000 support2 = 100000 support3 = 100000 counter = 0 premarketvol = 0 for tuple in historyMinute.itertuples(): premarketvol = premarketvol + tuple.volume if tuple.close > preMarketHigh: preMarketHigh = tuple.close if tuple.close < support1: support1 = tuple.close if counter >= 100: if tuple.close < support2: support2 = tuple.close if counter >= 150: if tuple.close < support3: support3 = tuple.close counter += 1 if support1 <= support2 and support1 <= support3: lowest_support = support1 if support2 <= support3: mid_support = support2 high_support = support3 else: mid_support = support3 high_support = support2 if support2 < support1 and support2 <= support3: lowest_support = support2 if support1 <= support3: mid_support = support1 high_support = support3 else: mid_support = support3 mid_support = support1 if support3 < support1 and support3 < support2: lowest_support = support3 if support1 <= support2: mid_support = support1 high_support = support3 else: mid_support= support3 high_support = support1 symbolData.support1 = lowest_support symbolData.support2 = mid_support symbolData.support3 = high_support symbolData.firstSupportBroke = False symbolData.secondSupportBroke = False symbolData.thirdSupportBroke = False symbolData.AlreadyBrokeOut = False symbolData.preMarketHigh = preMarketHigh if symbolData.Open >= symbolData.YesterdayClose*1.03: symbolData.isGap = True else: symbolData.isGap = False if premarketvol <= 1000000: remove.append(symbol) symbolData.isGapPercent = (symbolData.Open - symbolData.YesterdayClose) / symbolData.YesterdayClose for symbol in remove: self.activeSecurities.pop(symbol, None) self.Liquidate(symbol) self.RemoveSecurity(symbol) def LiquidatePositions(self): self.Liquidate() def OnData(self, data): if self.isMarket == True: for symbol, symbolData in self.tradingSecurities.items(): if symbolData.isGap == True: if len([x for x in self.Portfolio if x.Value.Invested]) >= self.maxTraded: break if self.Portfolio[symbol].Invested: if symbolData.AlreadyBrokeOut == False and self.Securities[symbol].Price >= symbolData.preMarketHigh: self.SetHoldings([PortfolioTarget(symbol, self.securityWeight)]) self.oneMinuteLow[symbol] = self.Securities[symbol].Low symbolData.AlreadyBrokeOut = True if not self.Portfolio[symbol].Invested and symbol not in self.tradedToday: if self.Securities[symbol].Price <= symbolData.support1: symbolData.firstSupportBroke = True if self.Securities[symbol].Price <= symbolData.preMarketHigh: symbolData.secondSupportBroke = True if symbolData.firstSupportBroke == True and self.Securities[symbol].Price >= symbolData.support1: self.SetHoldings([PortfolioTarget(symbol, self.securityWeight/2)]) self.oneMinuteLow[symbol] = self.Securities[symbol].Low self.tradedToday.append(symbol) self.Log(str(symbol) + "support1 = " + str(symbolData.support1)) self.Log(str(symbol) + "PreMarketHigh = " + str(symbolData.preMarketHigh)) if symbolData.secondSupportBroke == True and self.Securities[symbol].Price >= symbolData.preMarketHigh: self.SetHoldings([PortfolioTarget(symbol, self.securityWeight/2)]) self.tradedToday.append(symbol) self.oneMinuteLow[symbol] = self.Securities[symbol].Low symbolData.AlreadyBrokeOut = True # if symbol in self.quarterPositions: # self.quarterPositions.pop(symbol, None) continue # if symbol not in self.quarterPositions: # self.quarterPositions[symbol] = self.securityWeight/4 # else: # self.quarterPositions[symbol] += self.securityWeight/4 # # if self.quarterPositions[symbol] >=1: # continue self.oneMinuteHigh[symbol] = self.Securities[symbol].High self.manageProfit() self.oneMinuteLow[symbol] = self.Securities[symbol].Low def manageProfit(self): investedSecurities = [x.Key for x in self.Portfolio if x.Value.Invested] for symbol, symbolData in self.activeSecurities.items(): if self.Portfolio[symbol].Invested and (self.Securities[symbol].Price <= symbolData.preMarketHigh) and (self.Securities[symbol].Price <= self.oneMinuteLow[symbol]) and (self.Securities[symbol].Price > symbolData.support1): self.Liquidate(symbol, "PROFIT for Support 1") self.Log("Support success count = " + str(self.success_count)) self.success_count = self.success_count + 1 elif self.Portfolio[symbol].Invested and self.Securities[symbol].Price <= symbolData.support1: self.Liquidate(symbol, "Hit Support 1") self.Log("Support loss count = " + str(self.loss_count)) self.loss_count = self.loss_count + 1 continue if self.Portfolio[symbol].Invested and self.Securities[symbol].Price >= symbolData.preMarketHigh and (self.Securities[symbol].Price <= self.oneMinuteLow[symbol]): self.Liquidate(symbol, "PROFIT High") self.Log("PMH success count = " + str(self.success_countt)) self.success_countt = self.success_countt + 1 elif self.Portfolio[symbol].Invested and self.Securities[symbol].Price >= symbolData.preMarketHigh and (self.Securities[symbol].Price <= self.oneMinuteLow[symbol]): self.Liquidate(symbol, "Hit High Support") self.Log("PMH loss count = " + str(self.loss_countt)) self.loss_countt = self.loss_countt + 1 # if self.Portfolio[symbol].Invested and (self.Securities[symbol].Holdings.UnrealizedProfitPercent > 0.02): # self.Liquidate(symbol, "PROFIT") def OnSecuritiesChanged(self, changes): addedSecurities = [x.Symbol for x in changes.AddedSecurities] removedSecurities = [x.Symbol for x in changes.RemovedSecurities] for symbol in addedSecurities: if symbol == self.spy.Symbol: continue symbolData = SymbolData(symbol) self.activeSecurities[symbol] = symbolData for symbol in removedSecurities: if symbol in self.activeSecurities: self.activeSecurities.pop(symbol, None) if self.Portfolio[symbol].Invested: self.Liquidate(symbol) # self.securityWeight = 1/self.maxTraded def Coarse(self, coarse): if self.lastMonth == self.Time.month: return Universe.Unchanged self.lastMonth = self.Time.month selectedCoarse = [x for x in coarse if x.HasFundamentalData and x.Price > 40 and x.Volume > 1000000] self.dollarVolumeBySymbol = {x.Symbol:x.Volume for x in selectedCoarse} # If no security has met the QC500 criteria, the universe is unchanged. # A new selection will be attempted on the next trading day as self.lastMonth is not updated if len(self.dollarVolumeBySymbol) == 0: return Universe.Unchanged return [x.Symbol for x in selectedCoarse] def Fine(self, fine): sortedByVolume = sorted([x.Symbol for x in fine if x.CompanyReference.CountryId == "USA" and x.CompanyReference.PrimaryExchangeID in ["NYS","NAS"]], key = lambda x: self.dollarVolumeBySymbol[x], reverse=True) count = len(sortedByVolume) if count == 0: return Universe.Unchanged return sortedByVolume[:500] class SymbolData: def __init__(self, symbol): self.Open = -1 self.YesterdayClose = -1 self.preMarketHigh = -1 self.isGap = False self.Symbol = symbol self.isGapPercent = 0.0 self.support1 = 0 self.support2 = 0 self.support3 = 0 self.firstSupportBroke = False self.secondSupportBroke = False self.thirdSupportBroke = False self.AlreadyBrokeOut = False